From fba8bbd369f36f3dba348201dd608e162f4a2286 Mon Sep 17 00:00:00 2001 From: Hanz Po Date: Tue, 21 Apr 2026 13:15:28 -0400 Subject: [PATCH] feat(config): add configurable input_prompt setting Add an optional `input_prompt` string under [settings] that overrides the default lock/unlock emoji prompt in the input area. When unset, preserve existing behaviour (U+1F512 green for encrypted, U+1F513 red for unencrypted, `> ` red for unknown). When set, use the provided string for all three states. The default emoji prompt can produce stray characters in the input line when iamb runs inside tmux, because ratatui's unicode-width, tmux's internal width tables, and the outer terminal's emoji rendering do not always agree on the width of the lock glyph plus variation selector. An ASCII override avoids the width mismatch without changing defaults. --- config.example.toml | 1 + src/config.rs | 4 ++++ src/windows/room/chat.rs | 32 ++++++++++++++++++++++---------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/config.example.toml b/config.example.toml index c4ebd653..4937a33d 100644 --- a/config.example.toml +++ b/config.example.toml @@ -7,6 +7,7 @@ url = "https://matrix.org" [settings] default_room = "#iamb-users:0x.badd.cafe" external_edit_file_suffix = ".md" +# input_prompt = "❯ " # Overrides the input-area prompt. Unset = default 🔒/🔓/> based on encryption state. log_level = "warn" message_shortcode_display = false open_command = ["my-open", "--file"] diff --git a/src/config.rs b/src/config.rs index 39853ecb..1c27d615 100644 --- a/src/config.rs +++ b/src/config.rs @@ -540,6 +540,7 @@ pub struct TunableValues { pub user_gutter_width: usize, pub external_edit_file_suffix: String, pub tabstop: usize, + pub input_prompt: Option, } #[derive(Clone, Default, Deserialize)] @@ -569,6 +570,7 @@ pub struct Tunables { pub user_gutter_width: Option, pub external_edit_file_suffix: Option, pub tabstop: Option, + pub input_prompt: Option, } impl Tunables { @@ -604,6 +606,7 @@ impl Tunables { .external_edit_file_suffix .or(other.external_edit_file_suffix), tabstop: self.tabstop.or(other.tabstop), + input_prompt: self.input_prompt.or(other.input_prompt), } } @@ -635,6 +638,7 @@ impl Tunables { .external_edit_file_suffix .unwrap_or_else(|| ".md".to_string()), tabstop: self.tabstop.unwrap_or(4), + input_prompt: self.input_prompt, } } } diff --git a/src/windows/room/chat.rs b/src/windows/room/chat.rs index 7d26a1fe..b2e0909d 100644 --- a/src/windows/room/chat.rs +++ b/src/windows/room/chat.rs @@ -9,7 +9,6 @@ use edit::edit_with_builder as external_edit; use edit::Builder; use matrix_sdk::EncryptionState; use modalkit::editing::store::RegisterError; -use ratatui::style::{Color, Style}; use std::process::Command; use tokio; use url::Url; @@ -41,6 +40,7 @@ use matrix_sdk::{ use ratatui::{ buffer::Buffer, layout::Rect, + style::{Color, Style}, text::{Line, Span}, widgets::{Paragraph, StatefulWidget, Widget}, }; @@ -992,15 +992,27 @@ impl StatefulWidget for Chat<'_> { Paragraph::new(desc_spans).render(descarea, buf); } - let prompt = match (self.focused, state.room().encryption_state()) { - (false, _) => Span::raw(" "), - (_, EncryptionState::Encrypted) => { - Span::styled("\u{1F512}\u{FE0E} ", Style::new().fg(Color::LightGreen)) - }, - (_, EncryptionState::NotEncrypted) => { - Span::styled("\u{1F513}\u{FE0E} ", Style::new().fg(Color::Red)) - }, - (_, EncryptionState::Unknown) => Span::styled("> ", Style::new().fg(Color::Red)), + let prompt = if !self.focused { + Span::raw(" ") + } else if let Some(custom) = self + .store + .application + .settings + .tunables + .input_prompt + .as_deref() + { + Span::raw(custom) + } else { + match state.room().encryption_state() { + EncryptionState::Encrypted => { + Span::styled("\u{1F512}\u{FE0E} ", Style::new().fg(Color::LightGreen)) + }, + EncryptionState::NotEncrypted => { + Span::styled("\u{1F513}\u{FE0E} ", Style::new().fg(Color::Red)) + }, + EncryptionState::Unknown => Span::styled("> ", Style::new().fg(Color::Red)), + } }; let tbox = TextBox::new().prompt(prompt);