Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ user_id = "@user:matrix.org"
url = "https://matrix.org"

[settings]
cursor_shape = "default"
default_room = "#iamb-users:0x.badd.cafe"
external_edit_file_suffix = ".md"
log_level = "warn"
Expand Down
10 changes: 10 additions & 0 deletions docs/iamb.5
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ key and can be overridden as described in
.It Sy external_edit_file_suffix
Suffix to append to temporary file names when using the :editor command. Defaults to .md.

.It Sy cursor_shape
Control the terminal cursor shape used by iamb.
Possible values are:
.Dq Sy default ,
.Dq Sy block ,
.Dq Sy line , and
.Dq Sy underline .
Defaults to
.Dq Sy default .

.It Sy default_room
The room to show by default instead of the
.Sy :welcome
Expand Down
24 changes: 24 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ impl SortOverrides {

#[derive(Clone)]
pub struct TunableValues {
pub cursor_shape: CursorShape,
pub log_level: Level,
pub message_shortcode_display: bool,
pub normal_after_send: bool,
Expand Down Expand Up @@ -585,6 +586,7 @@ pub struct TunableValues {

#[derive(Clone, Default, Deserialize)]
pub struct Tunables {
pub cursor_shape: Option<CursorShape>,
pub log_level: Option<LogLevel>,
pub message_shortcode_display: Option<bool>,
pub normal_after_send: Option<bool>,
Expand Down Expand Up @@ -614,6 +616,7 @@ pub struct Tunables {
impl Tunables {
fn merge(self, other: Self) -> Self {
Tunables {
cursor_shape: self.cursor_shape.or(other.cursor_shape),
log_level: self.log_level.or(other.log_level),
message_shortcode_display: self
.message_shortcode_display
Expand Down Expand Up @@ -648,6 +651,7 @@ impl Tunables {

fn values(self) -> TunableValues {
TunableValues {
cursor_shape: self.cursor_shape.unwrap_or_default(),
log_level: self.log_level.map(Level::from).unwrap_or(Level::INFO),
message_shortcode_display: self.message_shortcode_display.unwrap_or(false),
normal_after_send: self.normal_after_send.unwrap_or(false),
Expand Down Expand Up @@ -677,6 +681,16 @@ impl Tunables {
}
}

#[derive(Copy, Clone, Debug, Default, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum CursorShape {
#[default]
Default,
Block,
Line,
Underline,
}

#[derive(Clone)]
pub struct DirectoryValues {
pub cache: PathBuf,
Expand Down Expand Up @@ -1345,6 +1359,16 @@ mod tests {
assert!(serde_json::from_str::<NotifyVia>(r#""""#).is_err());
}

#[test]
fn test_parse_cursor_shape() {
assert_eq!(CursorShape::Default, CursorShape::default());
assert_eq!(CursorShape::Default, serde_json::from_str(r#""default""#).unwrap());
assert_eq!(CursorShape::Block, serde_json::from_str(r#""block""#).unwrap());
assert_eq!(CursorShape::Line, serde_json::from_str(r#""line""#).unwrap());
assert_eq!(CursorShape::Underline, serde_json::from_str(r#""underline""#).unwrap());
assert!(serde_json::from_str::<CursorShape>(r#""beam""#).is_err());
}

#[test]
fn test_load_example_config_toml() {
let path = PathBuf::from("config.example.toml");
Expand Down
19 changes: 16 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use tracing_subscriber::FmtSubscriber;

use modalkit::crossterm::{
self,
cursor::Show as CursorShow,
cursor::{SetCursorStyle, Show as CursorShow},
event::{
poll,
read,
Expand Down Expand Up @@ -99,7 +99,7 @@ use crate::{
ProgramContext,
ProgramStore,
},
config::{ApplicationSettings, Iamb},
config::{ApplicationSettings, CursorShape, Iamb},
windows::IambWindow,
worker::{create_room, ClientWorker, LoginStyle, Requester},
};
Expand Down Expand Up @@ -976,6 +976,12 @@ async fn login_normal(
/// Set up the terminal for drawing the TUI, and getting additional info.
fn setup_tty(settings: &ApplicationSettings, enable_enhanced_keys: bool) -> std::io::Result<()> {
let title = format!("iamb ({})", settings.profile.user_id.as_str());
let cursor_style = match settings.tunables.cursor_shape {
CursorShape::Default => SetCursorStyle::DefaultUserShape,
CursorShape::Block => SetCursorStyle::SteadyBlock,
CursorShape::Line => SetCursorStyle::SteadyBar,
CursorShape::Underline => SetCursorStyle::SteadyUnderScore,
};

// Enable raw mode and enter the alternate screen.
crossterm::terminal::enable_raw_mode()?;
Expand All @@ -993,7 +999,13 @@ fn setup_tty(settings: &ApplicationSettings, enable_enhanced_keys: bool) -> std:
crossterm::execute!(stdout(), EnableMouseCapture)?;
}

crossterm::execute!(stdout(), EnableBracketedPaste, EnableFocusChange, SetTitle(title))
crossterm::execute!(
stdout(),
EnableBracketedPaste,
EnableFocusChange,
SetTitle(title),
cursor_style
)
}

// Do our best to reverse what we did in setup_tty() when we exit or crash.
Expand All @@ -1010,6 +1022,7 @@ fn restore_tty(enable_enhanced_keys: bool, enable_mouse: bool) {
stdout(),
DisableBracketedPaste,
DisableFocusChange,
SetCursorStyle::DefaultUserShape,
LeaveAlternateScreen,
CursorShow,
);
Expand Down