aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorsf-jin-ku <jin.ku@sendbird.com>2026-06-03 09:13:01 -0700
committerGitHub <noreply@github.com>2026-06-03 19:13:01 +0300
commitf5e66b251fa8ec24989bf25861bcf4e38a561470 (patch)
tree3244ffd1af0054334f8fe65ddbb0ff6f5a809cd3 /src/ui
parent03f68b7275f07c98769bf699d2aa14805b921f8d (diff)
feat: switch input source during prefix mode (#434)
On macOS, opt-in under [experimental], temporarily switch the host input source to the current ASCII-capable layout while prefix mode is active so prefix commands register even when a CJK IME is composing, then restore the previous input source when prefix mode exits or is cancelled. No-op when the current source is already ASCII-capable, on non-macOS platforms, or when any input source call fails. Pane text input is unaffected. Also pin next_resize_poll in next_loop_deadline_includes_selection_autoscroll_deadline so the selection autoscroll deadline stays the earliest; the default resize poll could otherwise beat it and flake the assertion. refs #400 Co-authored-by: Can Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/settings.rs64
1 files changed, 45 insertions, 19 deletions
diff --git a/src/ui/settings.rs b/src/ui/settings.rs
index 2e5ae806..b7104ea6 100644
--- a/src/ui/settings.rs
+++ b/src/ui/settings.rs
@@ -11,7 +11,10 @@ use super::widgets::{
render_action_button, render_modal_choice_list, render_panel_shell, ActionButtonSpec,
};
use crate::{
- app::{state::Palette, AppState},
+ app::{
+ state::{ExperimentSetting, Palette},
+ AppState,
+ },
config::ToastDelivery,
};
@@ -395,24 +398,22 @@ fn render_settings_experiments(app: &AppState, frame: &mut Frame, area: Rect) {
Style::default().fg(p.overlay1),
);
- let marker = if app.pane_history_persistence_enabled() {
- "[✓]"
- } else {
- "[ ]"
- };
- let style = if app.settings.list.selected == 0 {
- Style::default()
- .bg(p.surface0)
- .fg(p.text)
- .add_modifier(Modifier::BOLD)
- } else {
- Style::default().fg(p.subtext0)
- };
- let row = Rect::new(list_area.x, list_area.y, list_area.width, 1);
- frame.render_widget(
- Paragraph::new(format!(" pane screen history {marker}")).style(style),
- row,
- );
+ for (idx, setting) in ExperimentSetting::ALL.iter().copied().enumerate() {
+ let marker = if setting.enabled(app) { "[✓]" } else { "[ ]" };
+ let style = if app.settings.list.selected == idx {
+ Style::default()
+ .bg(p.surface0)
+ .fg(p.text)
+ .add_modifier(Modifier::BOLD)
+ } else {
+ Style::default().fg(p.subtext0)
+ };
+ let row = Rect::new(list_area.x, list_area.y + idx as u16, list_area.width, 1);
+ frame.render_widget(
+ Paragraph::new(format!(" {} {marker}", setting.label())).style(style),
+ row,
+ );
+ }
}
#[cfg(test)]
@@ -471,4 +472,29 @@ mod tests {
assert!(rendered.contains("pane screen history [ ]"));
}
+
+ #[test]
+ fn experiments_renders_switch_ascii_input_source_row() {
+ let mut app = AppState::test_new();
+ app.switch_ascii_input_source_in_prefix = true;
+ app.settings.section = SettingsSection::Experiments;
+ app.settings.list.selected = 1;
+ app.mode = Mode::Settings;
+
+ let mut terminal =
+ Terminal::new(TestBackend::new(80, 24)).expect("test terminal should initialize");
+ terminal
+ .draw(|frame| render_settings_overlay(&app, frame, Rect::new(0, 0, 80, 24)))
+ .expect("settings overlay should render");
+
+ let rendered = terminal
+ .backend()
+ .buffer()
+ .content()
+ .iter()
+ .map(|cell| cell.symbol())
+ .collect::<String>();
+
+ assert!(rendered.contains("switch to ascii input source in prefix (macOS) [✓]"));
+ }
}