fix(tui): handle macOS option-v details shortcut
## Summary - treat the macOS Option+V legacy glyph as the tool-details shortcut instead of inserting text - show the platform-appropriate details shortcut label in active tool status/footer copy - add regression coverage for macOS glyph handling and existing tool-details target behavior ## Test plan - cargo test -p deepseek-tui macos_option_v_glyph_is_treated_as_details_shortcut_only_on_macos --locked - cargo test -p deepseek-tui detail_target_prefers_visible_tool_card --locked - cargo test -p deepseek-tui active_tool_status_label_summarizes_live_tool_group --locked - cargo fmt --all -- --check - git diff --check - GitHub CI: Version drift, Lint, Test (ubuntu-latest), Test (macos-latest), Test (windows-latest), npm wrapper smoke, GitGuardian
This commit is contained in:
@@ -2087,6 +2087,11 @@ async fn run_event_loop(
|
||||
let is_plain_char = matches!(key.code, KeyCode::Char(_)) && !has_ctrl_alt_or_super;
|
||||
let is_enter = matches!(key.code, KeyCode::Enter);
|
||||
|
||||
if is_macos_option_v_legacy_key(&key) {
|
||||
open_tool_details_pager(app);
|
||||
continue;
|
||||
}
|
||||
|
||||
if !is_plain_char
|
||||
&& !is_enter
|
||||
&& let Some(pending) = app.flush_paste_burst_before_modified_input_if_enabled()
|
||||
@@ -6661,7 +6666,7 @@ fn active_tool_status_label(app: &App) -> Option<String> {
|
||||
if active_foreground_shell_running(app) {
|
||||
parts.push("Ctrl+B shell".to_string());
|
||||
}
|
||||
parts.push("Alt+V".to_string());
|
||||
parts.push(tool_details_shortcut_label().to_string());
|
||||
Some(parts.join(" \u{00B7} "))
|
||||
}
|
||||
|
||||
@@ -8155,7 +8160,8 @@ fn selected_detail_footer_label(app: &App) -> Option<String> {
|
||||
)?;
|
||||
let label = detail_target_label(app, cell_index)?;
|
||||
Some(format!(
|
||||
"Alt+V details: {}",
|
||||
"{} details: {}",
|
||||
tool_details_shortcut_label(),
|
||||
truncate_line_to_width(&label, 34)
|
||||
))
|
||||
}
|
||||
@@ -8228,6 +8234,14 @@ fn is_file_tree_toggle_shortcut(key: &KeyEvent) -> bool {
|
||||
ctrl_shift_e || cmd_shift_e
|
||||
}
|
||||
|
||||
fn tool_details_shortcut_label() -> &'static str {
|
||||
if cfg!(target_os = "macos") {
|
||||
"\u{2325}+V"
|
||||
} else {
|
||||
"Alt+V"
|
||||
}
|
||||
}
|
||||
|
||||
fn details_shortcut_modifiers(modifiers: KeyModifiers) -> bool {
|
||||
modifiers.is_empty()
|
||||
|| modifiers == KeyModifiers::SHIFT
|
||||
@@ -8236,6 +8250,14 @@ fn details_shortcut_modifiers(modifiers: KeyModifiers) -> bool {
|
||||
&& !modifiers.contains(KeyModifiers::SUPER))
|
||||
}
|
||||
|
||||
fn is_macos_option_v_legacy_key(key: &KeyEvent) -> bool {
|
||||
is_macos_option_v_legacy_key_for_platform(key, cfg!(target_os = "macos"))
|
||||
}
|
||||
|
||||
fn is_macos_option_v_legacy_key_for_platform(key: &KeyEvent, is_macos: bool) -> bool {
|
||||
is_macos && key.modifiers.is_empty() && matches!(key.code, KeyCode::Char('\u{221A}'))
|
||||
}
|
||||
|
||||
fn is_paste_shortcut(key: &KeyEvent) -> bool {
|
||||
let is_v = matches!(key.code, KeyCode::Char('v') | KeyCode::Char('V'));
|
||||
let is_legacy_ctrl_v = matches!(key.code, KeyCode::Char('\u{16}'));
|
||||
|
||||
@@ -881,7 +881,7 @@ fn active_tool_status_label_summarizes_live_tool_group() {
|
||||
assert!(label.contains("run cargo test"));
|
||||
assert!(label.contains("1 active"));
|
||||
assert!(label.contains("1 done"));
|
||||
assert!(label.contains("Alt+V"));
|
||||
assert!(label.contains(tool_details_shortcut_label()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2261,12 +2261,26 @@ fn detail_target_prefers_visible_tool_card() {
|
||||
app.viewport.last_transcript_visible = 6;
|
||||
|
||||
assert_eq!(detail_target_cell_index(&app), Some(1));
|
||||
let expected = format!("{} details: file_search", tool_details_shortcut_label());
|
||||
assert_eq!(
|
||||
selected_detail_footer_label(&app).as_deref(),
|
||||
Some("Alt+V details: file_search")
|
||||
Some(expected.as_str())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macos_option_v_glyph_is_treated_as_details_shortcut_only_on_macos() {
|
||||
let option_v = KeyEvent::new(KeyCode::Char('\u{221A}'), KeyModifiers::NONE);
|
||||
assert!(is_macos_option_v_legacy_key_for_platform(&option_v, true));
|
||||
assert!(!is_macos_option_v_legacy_key_for_platform(&option_v, false));
|
||||
|
||||
let modified = KeyEvent::new(KeyCode::Char('\u{221A}'), KeyModifiers::SHIFT);
|
||||
assert!(!is_macos_option_v_legacy_key_for_platform(&modified, true));
|
||||
|
||||
let plain_v = KeyEvent::new(KeyCode::Char('v'), KeyModifiers::NONE);
|
||||
assert!(!is_macos_option_v_legacy_key_for_platform(&plain_v, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_tool_details_pager_supports_active_virtual_tool_cell() {
|
||||
let mut app = create_test_app();
|
||||
|
||||
Reference in New Issue
Block a user