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:
Hunter Bown
2026-05-08 09:54:05 -05:00
committed by GitHub
parent a332077410
commit c0fe2e3360
2 changed files with 40 additions and 4 deletions
+24 -2
View File
@@ -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}'));
+16 -2
View File
@@ -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();