diff --git a/src/ui/i18n/en.rs b/src/ui/i18n/en.rs index 6cf0ae03..f883464d 100644 --- a/src/ui/i18n/en.rs +++ b/src/ui/i18n/en.rs @@ -33,7 +33,7 @@ pub fn translate_en(key: L10nKey) -> &'static str { L10nKey::Delete => "Delete", L10nKey::NoMatchingCommands => "No matching commands", L10nKey::ConnectSshHint => "Type user@host to connect over SSH instead.", - L10nKey::EditHint => "→ edit", + L10nKey::EditHint => "edit", L10nKey::OpenFileFromTree => "Open a file from the file tree", L10nKey::TreeDirLoading => "Reading…", L10nKey::TreeDirEmpty => "Empty", diff --git a/src/ui/i18n/ja.rs b/src/ui/i18n/ja.rs index 0a1a7a5a..7fbe1803 100644 --- a/src/ui/i18n/ja.rs +++ b/src/ui/i18n/ja.rs @@ -33,7 +33,7 @@ pub fn translate_ja(key: L10nKey) -> Option<&'static str> { L10nKey::Delete => "削除", L10nKey::NoMatchingCommands => "一致するコマンドがありません", L10nKey::ConnectSshHint => "SSH で接続するには user@host を入力してください", - L10nKey::EditHint => "→ 編集", + L10nKey::EditHint => "編集", L10nKey::OpenFileFromTree => "ファイルツリーからファイルを開く", L10nKey::TreeDirLoading => "読み込み中…", L10nKey::TreeDirEmpty => "空", diff --git a/src/ui/i18n/zh.rs b/src/ui/i18n/zh.rs index e7129ead..70a82fb7 100644 --- a/src/ui/i18n/zh.rs +++ b/src/ui/i18n/zh.rs @@ -33,7 +33,7 @@ pub fn translate_zh(key: L10nKey) -> Option<&'static str> { L10nKey::Delete => "删除", L10nKey::NoMatchingCommands => "没有匹配的命令", L10nKey::ConnectSshHint => "输入 user@host 改为通过 SSH 连接。", - L10nKey::EditHint => "→ 编辑", + L10nKey::EditHint => "编辑", L10nKey::OpenFileFromTree => "从文件树打开文件", L10nKey::TreeDirLoading => "读取中…", L10nKey::TreeDirEmpty => "空", diff --git a/src/ui/palette.rs b/src/ui/palette.rs index 5e59fae7..a24f02fe 100644 --- a/src/ui/palette.rs +++ b/src/ui/palette.rs @@ -878,10 +878,13 @@ impl ListDelegate for PaletteDelegate { .child(left); if cmd.kind.edit_variant().is_some() { row = row.child( - div() + h_flex() + .items_center() + .gap_1() .text_xs() .text_color(muted) - .child(crate::ui::i18n::t(crate::ui::i18n::L10nKey::EditHint)), + .child(crate::ui::i18n::t(crate::ui::i18n::L10nKey::EditHint)) + .child(crate::ui::keymap::key_tokens(EDIT_GESTURE).join("")), ); } if let Some(tokens) = keys { @@ -1070,6 +1073,29 @@ impl PaletteView { impl EventEmitter for PaletteView {} const PALETTE_ROW_H: f32 = 30.; + +/// The chord that opens the selected row for editing instead of running it. +/// +/// It cannot be `→`: gpui-component's `Input` binds bare `right` to MoveRight +/// in its own key context, so with the query field focused the palette never +/// sees the key — the old `→ edit` badge was advertising a gesture that could +/// not fire. `⌘↵` is no better; the app binds it to ToggleFullscreen, which +/// wins for the same reason. `secondary-e` is claimed by neither. +const EDIT_GESTURE: &str = "secondary-e"; + +/// Matches `EDIT_GESTURE` against a live keystroke. Keep the two in step. +fn is_edit_gesture(ks: &gpui::Keystroke) -> bool { + if ks.key != "e" { + return false; + } + let m = &ks.modifiers; + let secondary = if cfg!(target_os = "macos") { + m.platform + } else { + m.control + }; + secondary && !m.shift && !m.alt +} const PALETTE_VISIBLE_ROWS: f32 = 12.; const RECENT_ROWS: usize = 5; @@ -1106,9 +1132,7 @@ impl Render for PaletteView { .bg(scrim) .on_key_down(cx.listener(|this, ev: &gpui::KeyDownEvent, _window, cx| { let ks = &ev.keystroke; - let is_edit_gesture = (ks.key == "enter" && ks.modifiers.platform) - || (ks.key == "right" && !ks.modifiers.platform); - if is_edit_gesture { + if is_edit_gesture(ks) { if let Some(edit) = this.selected_edit_command(cx) { cx.stop_propagation(); cx.emit(PaletteEvent::Confirm(edit));