fix(palette): give the "edit" badge a chord that can actually fire

Every row with an edit variant — quick-connect and every saved SSH profile
— advertised "→ edit", and neither of the two gestures behind it worked:

- `→` never reaches the palette. gpui-component's `Input` binds bare
  `right` to MoveRight inside its own key context, and the query field has
  focus the whole time the palette is open, so the keystroke is consumed
  before the scrim's handler sees it.
- `⌘↵` never reaches it either. The app binds `secondary-enter` to
  ToggleFullscreen, which matches first — pressing it in the palette put
  the window into fullscreen.

So a saved profile could not be opened for editing from the palette at
all, which is the only row-scoped way in; Settings → SSH lists them, but
loses which row you were on.

The chord is now `secondary-e`, claimed by neither the input nor the app.
It lives in one `EDIT_GESTURE` constant next to the matcher that reads it,
and the badge renders through `key_tokens`, so it says ⌘E on macOS and
Ctrl E elsewhere rather than a hardcoded arrow baked into three locale
tables. `EditHint` is now just the word ("edit" / "编辑" / "編集").

Verified on screen: the badge reads "edit ⌘E", and ⌘E on a quick-connect
row opens the SSH profile form with the host, user and port already filled
in from the query.
This commit is contained in:
l0ng-ai
2026-08-08 07:57:37 +08:00
parent 5d1584e4c4
commit 1e7284db2b
4 changed files with 32 additions and 8 deletions
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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 => "",
+1 -1
View File
@@ -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 => "",
+29 -5
View File
@@ -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<PaletteEvent> 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));