diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index bfd2c95449..8993867d6b 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -2,28 +2,28 @@ // Standard Linux bindings { "bindings": { - "shift-tab": "menu::SelectPrev", "home": "menu::SelectFirst", - "pageup": "menu::SelectFirst", "shift-pageup": "menu::SelectFirst", - "ctrl-p": "menu::SelectPrev", - "tab": "menu::SelectNext", + "pageup": "menu::SelectFirst", "end": "menu::SelectLast", + "shift-pagedown": "menu::SelectLast", "pagedown": "menu::SelectLast", - "shift-pagedown": "menu::SelectFirst", "ctrl-n": "menu::SelectNext", + "tab": "menu::SelectNext", + "ctrl-p": "menu::SelectPrev", + "shift-tab": "menu::SelectPrev", "enter": "menu::Confirm", "ctrl-enter": "menu::SecondaryConfirm", - "escape": "menu::Cancel", "ctrl-escape": "menu::Cancel", "ctrl-c": "menu::Cancel", + "escape": "menu::Cancel", "alt-shift-enter": "menu::Restart", "alt-enter": ["picker::ConfirmInput", { "secondary": false }], "ctrl-alt-enter": ["picker::ConfirmInput", { "secondary": true }], "ctrl-shift-w": "workspace::CloseWindow", "shift-escape": "workspace::ToggleZoom", - "ctrl-o": "workspace::Open", "open": "workspace::Open", + "ctrl-o": "workspace::Open", "ctrl-=": "zed::IncreaseBufferFontSize", "ctrl-+": "zed::IncreaseBufferFontSize", "ctrl--": "zed::DecreaseBufferFontSize", @@ -53,8 +53,8 @@ "context": "Editor", "bindings": { "escape": "editor::Cancel", - "backspace": "editor::Backspace", "shift-backspace": "editor::Backspace", + "backspace": "editor::Backspace", "delete": "editor::Delete", "tab": "editor::Tab", "shift-tab": "editor::TabPrev", @@ -64,17 +64,20 @@ "ctrl-k q": "editor::Rewrap", "ctrl-backspace": "editor::DeleteToPreviousWordStart", "ctrl-delete": "editor::DeleteToNextWordEnd", - "shift-delete": "editor::Cut", "cut": "editor::Cut", - "ctrl-insert": "editor::Copy", + "shift-delete": "editor::Cut", + "ctrl-x": "editor::Cut", "copy": "editor::Copy", - "shift-insert": "editor::Paste", + "ctrl-insert": "editor::Copy", + "ctrl-c": "editor::Copy", "paste": "editor::Paste", - "ctrl-z": "editor::Undo", + "shift-insert": "editor::Paste", + "ctrl-v": "editor::Paste", "undo": "editor::Undo", + "ctrl-z": "editor::Undo", + "redo": "editor::Redo", "ctrl-y": "editor::Redo", "ctrl-shift-z": "editor::Redo", - "redo": "editor::Redo", "up": "editor::MoveUp", "ctrl-up": "editor::LineUp", "ctrl-down": "editor::LineDown", @@ -105,11 +108,11 @@ "ctrl-l": "editor::SelectLine", "ctrl-shift-i": "editor::Format", // "cmd-shift-left": ["editor::SelectToBeginningOfLine", {"stop_at_soft_wraps": true }], - "shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }], // "ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }], + "shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }], // "cmd-shift-right": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }], - "shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }], // "ctrl-shift-e": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }], + "shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }], // "alt-v": ["editor::MovePageUp", { "center_cursor": true }], "ctrl-alt-space": "editor::ShowCharacterPalette", "ctrl-;": "editor::ToggleLineNumbers", @@ -122,26 +125,17 @@ "shift-f10": "editor::OpenContextMenu" } }, - { - // Separate block with same context so these display in context menus - "context": "Editor", - "bindings": { - "ctrl-x": "editor::Cut", - "ctrl-c": "editor::Copy", - "ctrl-v": "editor::Paste" - } - }, { "context": "Editor && mode == full", "bindings": { - "enter": "editor::Newline", "shift-enter": "editor::Newline", + "enter": "editor::Newline", "ctrl-enter": "editor::NewlineAbove", "ctrl-shift-enter": "editor::NewlineBelow", "ctrl-k ctrl-z": "editor::ToggleSoftWrap", "ctrl-k z": "editor::ToggleSoftWrap", - "ctrl-f": "buffer_search::Deploy", "find": "buffer_search::Deploy", + "ctrl-f": "buffer_search::Deploy", "ctrl-h": ["buffer_search::Deploy", { "replace_enabled": true }], // "cmd-e": ["buffer_search::Deploy", { "focus": false }], "ctrl->": "assistant::QuoteSelection", @@ -174,8 +168,8 @@ { "context": "Markdown", "bindings": { - "ctrl-c": "markdown::Copy", - "copy": "markdown::Copy" + "copy": "markdown::Copy", + "ctrl-c": "markdown::Copy" } }, { @@ -188,15 +182,15 @@ "ctrl-alt-/": "assistant::ToggleModelSelector", "ctrl-k h": "assistant::DeployHistory", "ctrl-k l": "assistant::DeployPromptLibrary", - "ctrl-n": "assistant::NewContext", - "new": "assistant::NewContext" + "new": "assistant::NewContext", + "ctrl-n": "assistant::NewContext" } }, { "context": "PromptLibrary", "bindings": { - "ctrl-n": "prompt_library::NewPrompt", "new": "prompt_library::NewPrompt", + "ctrl-n": "prompt_library::NewPrompt", "ctrl-shift-s": "prompt_library::ToggleDefaultPrompt" } }, @@ -232,8 +226,8 @@ "context": "ProjectSearchBar", "bindings": { "escape": "project_search::ToggleFocus", - "ctrl-shift-f": "search::FocusSearch", "shift-find": "search::FocusSearch", + "ctrl-shift-f": "search::FocusSearch", "ctrl-shift-h": "search::ToggleReplace", "alt-ctrl-g": "search::ToggleRegex", "alt-ctrl-x": "search::ToggleRegex" @@ -265,34 +259,48 @@ { "context": "Pane", "bindings": { + "alt-1": ["pane::ActivateItem", 0], + "alt-2": ["pane::ActivateItem", 1], + "alt-3": ["pane::ActivateItem", 2], + "alt-4": ["pane::ActivateItem", 3], + "alt-5": ["pane::ActivateItem", 4], + "alt-6": ["pane::ActivateItem", 5], + "alt-7": ["pane::ActivateItem", 6], + "alt-8": ["pane::ActivateItem", 7], + "alt-9": ["pane::ActivateItem", 8], + "alt-0": "pane::ActivateLastItem", "ctrl-pageup": "pane::ActivatePrevItem", "ctrl-pagedown": "pane::ActivateNextItem", "ctrl-shift-pageup": "pane::SwapItemLeft", "ctrl-shift-pagedown": "pane::SwapItemRight", - "back": "pane::GoBack", - "forward": "pane::GoForward", - "ctrl-w": "pane::CloseActiveItem", "ctrl-f4": "pane::CloseActiveItem", + "ctrl-w": "pane::CloseActiveItem", "alt-ctrl-t": ["pane::CloseInactiveItems", { "close_pinned": false }], "alt-ctrl-shift-w": "workspace::CloseInactiveTabsAndPanes", "ctrl-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }], "ctrl-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }], "ctrl-k u": ["pane::CloseCleanItems", { "close_pinned": false }], "ctrl-k w": ["pane::CloseAllItems", { "close_pinned": false }], - "ctrl-shift-f": "pane::DeploySearch", - "shift-find": "pane::DeploySearch", + "back": "pane::GoBack", + "ctrl-alt--": "pane::GoBack", + "ctrl-alt-_": "pane::GoForward", + "forward": "pane::GoForward", "ctrl-alt-g": "search::SelectNextMatch", + "f3": "search::SelectNextMatch", "ctrl-alt-shift-g": "search::SelectPrevMatch", + "shift-f3": "search::SelectPrevMatch", + "ctrl-shift-f": "project_search::ToggleFocus", + "shift-find": "project_search::ToggleFocus", "ctrl-alt-shift-h": "search::ToggleReplace", "ctrl-alt-shift-l": "search::ToggleSelection", "alt-enter": "search::SelectAllMatches", "alt-c": "search::ToggleCaseSensitive", "alt-w": "search::ToggleWholeWord", - "alt-r": "search::ToggleRegex", "alt-ctrl-f": "project_search::ToggleFilters", "alt-find": "project_search::ToggleFilters", "ctrl-alt-shift-r": "search::ToggleRegex", "ctrl-alt-shift-x": "search::ToggleRegex", + "alt-r": "search::ToggleRegex", "ctrl-k shift-enter": "pane::TogglePinTab" } }, @@ -367,47 +375,26 @@ "ctrl-g": "go_to_line::Toggle" } }, - { - "context": "Pane", - "bindings": { - "alt-1": ["pane::ActivateItem", 0], - "alt-2": ["pane::ActivateItem", 1], - "alt-3": ["pane::ActivateItem", 2], - "alt-4": ["pane::ActivateItem", 3], - "alt-5": ["pane::ActivateItem", 4], - "alt-6": ["pane::ActivateItem", 5], - "alt-7": ["pane::ActivateItem", 6], - "alt-8": ["pane::ActivateItem", 7], - "alt-9": ["pane::ActivateItem", 8], - "alt-0": "pane::ActivateLastItem", - "ctrl-alt--": "pane::GoBack", - "ctrl-alt-_": "pane::GoForward", - "f3": "search::SelectNextMatch", - "shift-f3": "search::SelectPrevMatch", - "ctrl-shift-f": "project_search::ToggleFocus", - "shift-find": "project_search::ToggleFocus" - } - }, { "context": "Workspace", "bindings": { // Change the default action on `menu::Confirm` by setting the parameter // "alt-ctrl-o": ["projects::OpenRecent", { "create_new_window": true }], - "alt-ctrl-o": "projects::OpenRecent", "alt-open": "projects::OpenRecent", - "alt-ctrl-shift-o": "projects::OpenRemote", + "alt-ctrl-o": "projects::OpenRecent", "alt-shift-open": "projects::OpenRemote", + "alt-ctrl-shift-o": "projects::OpenRemote", "alt-ctrl-shift-b": "branches::OpenRecent", "ctrl-~": "workspace::NewTerminal", - "ctrl-s": "workspace::Save", "save": "workspace::Save", + "ctrl-s": "workspace::Save", "ctrl-k s": "workspace::SaveWithoutFormat", - "ctrl-shift-s": "workspace::SaveAs", "shift-save": "workspace::SaveAs", - "ctrl-n": "workspace::NewFile", + "ctrl-shift-s": "workspace::SaveAs", "new": "workspace::NewFile", - "ctrl-shift-n": "workspace::NewWindow", + "ctrl-n": "workspace::NewFile", "shift-new": "workspace::NewWindow", + "ctrl-shift-n": "workspace::NewWindow", "ctrl-`": "terminal_panel::ToggleFocus", "alt-1": ["workspace::ActivatePane", 0], "alt-2": ["workspace::ActivatePane", 1], @@ -422,8 +409,8 @@ "ctrl-b": "workspace::ToggleLeftDock", "ctrl-j": "workspace::ToggleBottomDock", "ctrl-alt-y": "workspace::CloseAllDocks", - "ctrl-shift-f": "pane::DeploySearch", "shift-find": "pane::DeploySearch", + "ctrl-shift-f": "pane::DeploySearch", "ctrl-shift-h": ["pane::DeploySearch", { "replace_enabled": true }], "ctrl-shift-t": "pane::ReopenClosedItem", "ctrl-k ctrl-s": "zed::OpenKeymap", @@ -433,14 +420,14 @@ "ctrl-tab": "tab_switcher::Toggle", "ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }], "ctrl-e": "file_finder::Toggle", - "ctrl-shift-p": "command_palette::Toggle", "f1": "command_palette::Toggle", + "ctrl-shift-p": "command_palette::Toggle", "ctrl-shift-m": "diagnostics::Deploy", "ctrl-shift-e": "project_panel::ToggleFocus", "ctrl-shift-b": "outline_panel::ToggleFocus", "ctrl-?": "assistant::ToggleFocus", - "ctrl-alt-s": "workspace::SaveAll", "alt-save": "workspace::SaveAll", + "ctrl-alt-s": "workspace::SaveAll", "ctrl-k m": "language_selector::Toggle", "escape": "workspace::Unfollow", "ctrl-k ctrl-left": ["workspace::ActivatePaneInDirection", "Left"], @@ -472,7 +459,6 @@ { "context": "Editor", "bindings": { - "ctrl-shift-k": "editor::DeleteLine", "ctrl-shift-d": "editor::DuplicateLineDown", "ctrl-shift-j": "editor::JoinLines", "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart", @@ -530,10 +516,10 @@ { "context": "Editor && (showing_code_actions || showing_completions)", "bindings": { - "up": "editor::ContextMenuPrev", "ctrl-p": "editor::ContextMenuPrev", - "down": "editor::ContextMenuNext", + "up": "editor::ContextMenuPrev", "ctrl-n": "editor::ContextMenuNext", + "down": "editor::ContextMenuNext", "pageup": "editor::ContextMenuFirst", "pagedown": "editor::ContextMenuLast" } @@ -650,10 +636,10 @@ "escape": "menu::Cancel", "left": "outline_panel::CollapseSelectedEntry", "right": "outline_panel::ExpandSelectedEntry", - "ctrl-alt-c": "outline_panel::CopyPath", "alt-copy": "outline_panel::CopyPath", - "alt-ctrl-shift-c": "outline_panel::CopyRelativePath", + "ctrl-alt-c": "outline_panel::CopyPath", "alt-shift-copy": "outline_panel::CopyRelativePath", + "alt-ctrl-shift-c": "outline_panel::CopyRelativePath", "alt-ctrl-r": "outline_panel::RevealInFileManager", "space": "outline_panel::Open", "shift-down": "menu::SelectNext", @@ -667,21 +653,26 @@ "bindings": { "left": "project_panel::CollapseSelectedEntry", "right": "project_panel::ExpandSelectedEntry", - "ctrl-n": "project_panel::NewFile", "new": "project_panel::NewFile", - "alt-ctrl-n": "project_panel::NewDirectory", + "ctrl-n": "project_panel::NewFile", "alt-new": "project_panel::NewDirectory", + "alt-ctrl-n": "project_panel::NewDirectory", "cut": "project_panel::Cut", - "ctrl-insert": "project_panel::Copy", + "ctrl-x": "project_panel::Cut", "copy": "project_panel::Copy", - "shift-insert": "project_panel::Paste", + "ctrl-insert": "project_panel::Copy", + "ctrl-c": "project_panel::Copy", "paste": "project_panel::Paste", - "ctrl-alt-c": "project_panel::CopyPath", + "shift-insert": "project_panel::Paste", + "ctrl-v": "project_panel::Paste", "alt-copy": "project_panel::CopyPath", - "alt-ctrl-shift-c": "project_panel::CopyRelativePath", + "ctrl-alt-c": "project_panel::CopyPath", "alt-shift-copy": "project_panel::CopyRelativePath", + "alt-ctrl-shift-c": "project_panel::CopyRelativePath", "enter": "project_panel::Rename", + "f2": "project_panel::Rename", "backspace": ["project_panel::Trash", { "skip_prompt": false }], + "delete": ["project_panel::Trash", { "skip_prompt": false }], "shift-delete": ["project_panel::Delete", { "skip_prompt": false }], "ctrl-backspace": ["project_panel::Delete", { "skip_prompt": false }], "ctrl-delete": ["project_panel::Delete", { "skip_prompt": false }], @@ -694,17 +685,6 @@ "escape": "menu::Cancel" } }, - { - // Separate block with same context so these display in context menus - "context": "ProjectPanel", - "bindings": { - "f2": "project_panel::Rename", - "ctrl-c": "project_panel::Copy", - "ctrl-x": "project_panel::Cut", - "ctrl-v": "project_panel::Paste", - "delete": ["project_panel::Trash", { "skip_prompt": false }] - } - }, { "context": "ProjectPanel && not_editing", "bindings": { @@ -771,9 +751,9 @@ { "context": "TabSwitcher", "bindings": { + "ctrl-shift-tab": "menu::SelectPrev", "ctrl-up": "menu::SelectPrev", "ctrl-down": "menu::SelectNext", - "ctrl-shift-tab": "menu::SelectPrev", "ctrl-backspace": "tab_switcher::CloseSelectedItem" } }, @@ -781,16 +761,18 @@ "context": "Terminal", "bindings": { "ctrl-alt-space": "terminal::ShowCharacterPalette", - "ctrl-insert": "terminal::Copy", "copy": "terminal::Copy", - "shift-insert": "terminal::Paste", + "ctrl-insert": "terminal::Copy", + "ctrl-shift-c": "terminal::Copy", "paste": "terminal::Paste", + "shift-insert": "terminal::Paste", + "ctrl-shift-v": "terminal::Paste", "ctrl-enter": "assistant::InlineAssist", // Overrides for conflicting keybindings "ctrl-w": ["terminal::SendKeystroke", "ctrl-w"], "ctrl-shift-a": "editor::SelectAll", - "ctrl-shift-f": "buffer_search::Deploy", "find": "buffer_search::Deploy", + "ctrl-shift-f": "buffer_search::Deploy", "ctrl-shift-l": "terminal::Clear", "ctrl-shift-w": "pane::CloseActiveItem", "ctrl-e": ["terminal::SendKeystroke", "ctrl-e"], @@ -809,13 +791,5 @@ "shift-end": "terminal::ScrollToBottom", "ctrl-shift-space": "terminal::ToggleViMode" } - }, - { - // Separate block with same context so these display in context menus - "context": "Terminal", - "bindings": { - "ctrl-shift-c": "terminal::Copy", - "ctrl-shift-v": "terminal::Paste" - } } ] diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 843b94fe78..ec792c2856 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -3,27 +3,27 @@ { "use_key_equivalents": true, "bindings": { - "up": "menu::SelectPrev", - "shift-tab": "menu::SelectPrev", "home": "menu::SelectFirst", - "pageup": "menu::SelectFirst", "shift-pageup": "menu::SelectFirst", - "ctrl-p": "menu::SelectPrev", - "down": "menu::SelectNext", - "tab": "menu::SelectNext", - "end": "menu::SelectLast", - "pagedown": "menu::SelectLast", - "shift-pagedown": "menu::SelectFirst", - "ctrl-n": "menu::SelectNext", + "pageup": "menu::SelectFirst", "cmd-up": "menu::SelectFirst", + "end": "menu::SelectLast", + "shift-pagedown": "menu::SelectLast", + "pagedown": "menu::SelectLast", "cmd-down": "menu::SelectLast", + "tab": "menu::SelectNext", + "ctrl-n": "menu::SelectNext", + "down": "menu::SelectNext", + "shift-tab": "menu::SelectPrev", + "ctrl-p": "menu::SelectPrev", + "up": "menu::SelectPrev", "enter": "menu::Confirm", "ctrl-enter": "menu::SecondaryConfirm", "cmd-enter": "menu::SecondaryConfirm", - "escape": "menu::Cancel", - "cmd-escape": "menu::Cancel", "ctrl-escape": "menu::Cancel", + "cmd-escape": "menu::Cancel", "ctrl-c": "menu::Cancel", + "escape": "menu::Cancel", "alt-shift-enter": "menu::Restart", "cmd-shift-w": "workspace::CloseWindow", "shift-escape": "workspace::ToggleZoom", @@ -48,18 +48,18 @@ "use_key_equivalents": true, "bindings": { "escape": "editor::Cancel", - "backspace": "editor::Backspace", "shift-backspace": "editor::Backspace", "ctrl-h": "editor::Backspace", - "delete": "editor::Delete", + "backspace": "editor::Backspace", "ctrl-d": "editor::Delete", + "delete": "editor::Delete", "tab": "editor::Tab", "shift-tab": "editor::TabPrev", "ctrl-t": "editor::Transpose", "ctrl-k": "editor::KillRingCut", "ctrl-y": "editor::KillRingYank", - "cmd-k q": "editor::Rewrap", "cmd-k cmd-q": "editor::Rewrap", + "cmd-k q": "editor::Rewrap", "cmd-backspace": "editor::DeleteToBeginningOfLine", "cmd-delete": "editor::DeleteToEndOfLine", "alt-backspace": "editor::DeleteToPreviousWordStart", @@ -76,27 +76,27 @@ "shift-pageup": "editor::SelectPageUp", "cmd-pageup": "editor::PageUp", "ctrl-pageup": "editor::LineUp", - "home": "editor::MoveToBeginningOfLine", "down": "editor::MoveDown", "ctrl-down": "editor::MoveToEndOfParagraph", "pagedown": "editor::MovePageDown", "shift-pagedown": "editor::SelectPageDown", "cmd-pagedown": "editor::PageDown", "ctrl-pagedown": "editor::LineDown", - "end": "editor::MoveToEndOfLine", - "left": "editor::MoveLeft", - "right": "editor::MoveRight", "ctrl-p": "editor::MoveUp", "ctrl-n": "editor::MoveDown", "ctrl-b": "editor::MoveLeft", + "left": "editor::MoveLeft", "ctrl-f": "editor::MoveRight", + "right": "editor::MoveRight", "ctrl-l": "editor::ScrollCursorCenter", "alt-left": "editor::MoveToPreviousWordStart", "alt-right": "editor::MoveToNextWordEnd", "cmd-left": "editor::MoveToBeginningOfLine", "ctrl-a": "editor::MoveToBeginningOfLine", + "home": "editor::MoveToBeginningOfLine", "cmd-right": "editor::MoveToEndOfLine", "ctrl-e": "editor::MoveToEndOfLine", + "end": "editor::MoveToEndOfLine", "cmd-up": "editor::MoveToBeginning", "cmd-down": "editor::MoveToEnd", "shift-up": "editor::SelectUp", @@ -139,8 +139,8 @@ "context": "Editor && mode == full", "use_key_equivalents": true, "bindings": { - "enter": "editor::Newline", "shift-enter": "editor::Newline", + "enter": "editor::Newline", "cmd-enter": "editor::NewlineBelow", "cmd-shift-enter": "editor::NewlineAbove", "cmd-k z": "editor::ToggleSoftWrap", @@ -341,10 +341,10 @@ "context": "Pane", "use_key_equivalents": true, "bindings": { - "cmd-{": "pane::ActivatePrevItem", - "cmd-}": "pane::ActivateNextItem", "alt-cmd-left": "pane::ActivatePrevItem", + "cmd-{": "pane::ActivatePrevItem", "alt-cmd-right": "pane::ActivateNextItem", + "cmd-}": "pane::ActivateNextItem", "ctrl-shift-pageup": "pane::SwapItemLeft", "ctrl-shift-pagedown": "pane::SwapItemRight", "cmd-w": "pane::CloseActiveItem", @@ -374,10 +374,10 @@ "bindings": { "cmd-[": "editor::Outdent", "cmd-]": "editor::Indent", - "cmd-alt-up": "editor::AddSelectionAbove", // Insert cursor above - "cmd-ctrl-p": "editor::AddSelectionAbove", - "cmd-alt-down": "editor::AddSelectionBelow", // Insert cursor below - "cmd-ctrl-n": "editor::AddSelectionBelow", + "cmd-ctrl-p": "editor::AddSelectionAbove", // Insert cursor above + "cmd-alt-up": "editor::AddSelectionAbove", + "cmd-ctrl-n": "editor::AddSelectionBelow", // Insert cursor below + "cmd-alt-down": "editor::AddSelectionBelow", "cmd-shift-k": "editor::DeleteLine", "alt-up": "editor::MoveLineUp", "alt-down": "editor::MoveLineDown", @@ -404,8 +404,8 @@ "shift-f12": "editor::GoToImplementation", "alt-cmd-f12": "editor::GoToTypeDefinitionSplit", "alt-shift-f12": "editor::FindAllReferences", - "ctrl-m": "editor::MoveToEnclosingBracket", "cmd-|": "editor::MoveToEnclosingBracket", + "ctrl-m": "editor::MoveToEnclosingBracket", "alt-cmd-[": "editor::Fold", "alt-cmd-]": "editor::UnfoldLines", "cmd-k cmd-l": "editor::ToggleFold", @@ -807,9 +807,9 @@ "context": "TabSwitcher", "use_key_equivalents": true, "bindings": { + "ctrl-shift-tab": "menu::SelectPrev", "ctrl-up": "menu::SelectPrev", "ctrl-down": "menu::SelectNext", - "ctrl-shift-tab": "menu::SelectPrev", "ctrl-backspace": "tab_switcher::CloseSelectedItem" } }, @@ -840,16 +840,16 @@ "escape": ["terminal::SendKeystroke", "escape"], "enter": ["terminal::SendKeystroke", "enter"], "ctrl-c": ["terminal::SendKeystroke", "ctrl-c"], - "cmd-up": "terminal::ScrollPageUp", - "cmd-down": "terminal::ScrollPageDown", "shift-pageup": "terminal::ScrollPageUp", + "cmd-up": "terminal::ScrollPageUp", "shift-pagedown": "terminal::ScrollPageDown", + "cmd-down": "terminal::ScrollPageDown", "shift-up": "terminal::ScrollLineUp", "shift-down": "terminal::ScrollLineDown", - "cmd-home": "terminal::ScrollToTop", - "cmd-end": "terminal::ScrollToBottom", "shift-home": "terminal::ScrollToTop", + "cmd-home": "terminal::ScrollToTop", "shift-end": "terminal::ScrollToBottom", + "cmd-end": "terminal::ScrollToBottom", "ctrl-shift-space": "terminal::ToggleViMode", "ctrl-k up": "pane::SplitUp", "ctrl-k down": "pane::SplitDown", diff --git a/assets/keymaps/storybook.json b/assets/keymaps/storybook.json index 5e375821e0..a59e084a88 100644 --- a/assets/keymaps/storybook.json +++ b/assets/keymaps/storybook.json @@ -2,21 +2,27 @@ // Standard macOS bindings { "bindings": { - "up": "menu::SelectPrev", - "pageup": "menu::SelectFirst", + "home": "menu::SelectFirst", "shift-pageup": "menu::SelectFirst", - "ctrl-p": "menu::SelectPrev", - "down": "menu::SelectNext", - "pagedown": "menu::SelectLast", - "shift-pagedown": "menu::SelectFirst", - "ctrl-n": "menu::SelectNext", + "pageup": "menu::SelectFirst", "cmd-up": "menu::SelectFirst", + "end": "menu::SelectLast", + "shift-pagedown": "menu::SelectLast", + "pagedown": "menu::SelectLast", "cmd-down": "menu::SelectLast", + "tab": "menu::SelectNext", + "ctrl-n": "menu::SelectNext", + "down": "menu::SelectNext", + "shift-tab": "menu::SelectPrev", + "ctrl-p": "menu::SelectPrev", + "up": "menu::SelectPrev", "enter": "menu::Confirm", "ctrl-enter": "menu::SecondaryConfirm", "cmd-enter": "menu::SecondaryConfirm", - "escape": "menu::Cancel", + "ctrl-escape": "menu::Cancel", + "cmd-escape": "menu::Cancel", "ctrl-c": "menu::Cancel", + "escape": "menu::Cancel", "cmd-q": "storybook::Quit", "backspace": "editor::Backspace", "delete": "editor::Delete", diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 1d4cd7f0c0..88ad4f6557 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -4,25 +4,25 @@ "bindings": { "i": ["vim::PushOperator", { "Object": { "around": false } }], "a": ["vim::PushOperator", { "Object": { "around": true } }], - "h": "vim::Left", "left": "vim::Left", + "h": "vim::Left", "backspace": "vim::Backspace", - "j": "vim::Down", "down": "vim::Down", "ctrl-j": "vim::Down", - "enter": "vim::NextLineStart", + "j": "vim::Down", "ctrl-m": "vim::NextLineStart", "+": "vim::NextLineStart", + "enter": "vim::NextLineStart", "-": "vim::PreviousLineStart", - "tab": "vim::Tab", "shift-tab": "vim::Tab", - "k": "vim::Up", + "tab": "vim::Tab", "up": "vim::Up", - "l": "vim::Right", + "k": "vim::Up", "right": "vim::Right", + "l": "vim::Right", "space": "vim::Space", - "$": "vim::EndOfLine", "end": "vim::EndOfLine", + "$": "vim::EndOfLine", "^": "vim::FirstNonWhitespace", "_": "vim::StartOfLineDownward", "g _": "vim::EndOfLineDownward", @@ -188,8 +188,8 @@ { "context": "vim_mode == normal", "bindings": { - "escape": "editor::Cancel", "ctrl-[": "editor::Cancel", + "escape": "editor::Cancel", ":": "command_palette::Toggle", ".": "vim::Repeat", "c": ["vim::PushOperator", "Change"], @@ -226,8 +226,8 @@ "g shift-u": ["vim::PushOperator", "Uppercase"], "g ~": ["vim::PushOperator", "OppositeCase"], "\"": ["vim::PushOperator", "Register"], - "g q": ["vim::PushOperator", "Rewrap"], "g w": ["vim::PushOperator", "Rewrap"], + "g q": ["vim::PushOperator", "Rewrap"], "ctrl-pagedown": "pane::ActivateNextItem", "ctrl-pageup": "pane::ActivatePrevItem", "insert": "vim::InsertBefore", @@ -254,8 +254,8 @@ ":": "vim::VisualCommand", "u": "vim::ConvertToLowerCase", "shift-u": "vim::ConvertToUpperCase", - "o": "vim::OtherEnd", "shift-o": "vim::OtherEnd", + "o": "vim::OtherEnd", "d": "vim::VisualDelete", "x": "vim::VisualDelete", "shift-d": "vim::VisualDeleteLine", @@ -264,10 +264,10 @@ "shift-y": "vim::VisualYankLine", "p": "vim::Paste", "shift-p": ["vim::Paste", { "preserveClipboard": true }], - "s": "vim::Substitute", - "shift-s": "vim::SubstituteLine", - "shift-r": "vim::SubstituteLine", "c": "vim::Substitute", + "s": "vim::Substitute", + "shift-r": "vim::SubstituteLine", + "shift-s": "vim::SubstituteLine", "~": "vim::ChangeCase", "*": ["vim::MoveToNext", { "partialWord": true }], "#": ["vim::MoveToPrev", { "partialWord": true }], @@ -283,8 +283,8 @@ "g shift-j": "vim::JoinLinesNoWhitespace", "r": ["vim::PushOperator", "Replace"], "ctrl-c": ["vim::SwitchMode", "Normal"], - "escape": ["vim::SwitchMode", "Normal"], "ctrl-[": ["vim::SwitchMode", "Normal"], + "escape": ["vim::SwitchMode", "Normal"], ">": "vim::Indent", "<": "vim::Outdent", "=": "vim::AutoIndent", @@ -302,9 +302,9 @@ { "context": "vim_mode == insert", "bindings": { - "escape": "vim::NormalBefore", "ctrl-c": "vim::NormalBefore", "ctrl-[": "vim::NormalBefore", + "escape": "vim::NormalBefore", "ctrl-x": null, "ctrl-x ctrl-o": "editor::ShowCompletions", "ctrl-x ctrl-a": "assistant::InlineAssist", // zed specific @@ -352,9 +352,9 @@ { "context": "vim_mode == replace", "bindings": { - "escape": "vim::NormalBefore", "ctrl-c": "vim::NormalBefore", "ctrl-[": "vim::NormalBefore", + "escape": "vim::NormalBefore", "ctrl-k": ["vim::PushOperator", { "Digraph": {} }], "ctrl-v": ["vim::PushOperator", { "Literal": {} }], "ctrl-shift-v": "editor::Paste", // note: this is *very* similar to ctrl-v in vim, but ctrl-shift-v on linux is the typical shortcut for paste when ctrl-v is already in use. @@ -371,9 +371,9 @@ "bindings": { "tab": "vim::Tab", "enter": "vim::Enter", - "escape": "vim::ClearOperators", "ctrl-c": "vim::ClearOperators", "ctrl-[": "vim::ClearOperators", + "escape": "vim::ClearOperators", "ctrl-k": ["vim::PushOperator", { "Digraph": {} }], "ctrl-v": ["vim::PushOperator", { "Literal": {} }], "ctrl-q": ["vim::PushOperator", { "Literal": {} }] @@ -382,9 +382,9 @@ { "context": "vim_mode == operator", "bindings": { - "escape": "vim::ClearOperators", "ctrl-c": "vim::ClearOperators", "ctrl-[": "vim::ClearOperators", + "escape": "vim::ClearOperators", "g c": "vim::Comment" } }, @@ -571,14 +571,14 @@ "ctrl-w right": ["workspace::ActivatePaneInDirection", "Right"], "ctrl-w up": ["workspace::ActivatePaneInDirection", "Up"], "ctrl-w down": ["workspace::ActivatePaneInDirection", "Down"], - "ctrl-w h": ["workspace::ActivatePaneInDirection", "Left"], - "ctrl-w l": ["workspace::ActivatePaneInDirection", "Right"], - "ctrl-w k": ["workspace::ActivatePaneInDirection", "Up"], - "ctrl-w j": ["workspace::ActivatePaneInDirection", "Down"], "ctrl-w ctrl-h": ["workspace::ActivatePaneInDirection", "Left"], "ctrl-w ctrl-l": ["workspace::ActivatePaneInDirection", "Right"], "ctrl-w ctrl-k": ["workspace::ActivatePaneInDirection", "Up"], "ctrl-w ctrl-j": ["workspace::ActivatePaneInDirection", "Down"], + "ctrl-w h": ["workspace::ActivatePaneInDirection", "Left"], + "ctrl-w l": ["workspace::ActivatePaneInDirection", "Right"], + "ctrl-w k": ["workspace::ActivatePaneInDirection", "Up"], + "ctrl-w j": ["workspace::ActivatePaneInDirection", "Down"], "ctrl-w shift-left": ["workspace::SwapPaneInDirection", "Left"], "ctrl-w shift-right": ["workspace::SwapPaneInDirection", "Right"], "ctrl-w shift-up": ["workspace::SwapPaneInDirection", "Up"], @@ -603,19 +603,19 @@ "ctrl-w ctrl-p": "workspace::ActivatePreviousPane", "ctrl-w shift-w": "workspace::ActivatePreviousPane", "ctrl-w ctrl-shift-w": "workspace::ActivatePreviousPane", - "ctrl-w v": "pane::SplitVertical", "ctrl-w ctrl-v": "pane::SplitVertical", - "ctrl-w s": "pane::SplitHorizontal", + "ctrl-w v": "pane::SplitVertical", "ctrl-w shift-s": "pane::SplitHorizontal", "ctrl-w ctrl-s": "pane::SplitHorizontal", - "ctrl-w c": "pane::CloseAllItems", + "ctrl-w s": "pane::SplitHorizontal", "ctrl-w ctrl-c": "pane::CloseAllItems", - "ctrl-w q": "pane::CloseAllItems", + "ctrl-w c": "pane::CloseAllItems", "ctrl-w ctrl-q": "pane::CloseAllItems", - "ctrl-w o": "workspace::CloseInactiveTabsAndPanes", + "ctrl-w q": "pane::CloseAllItems", "ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes", - "ctrl-w n": "workspace::NewFileSplitHorizontal", - "ctrl-w ctrl-n": "workspace::NewFileSplitHorizontal" + "ctrl-w o": "workspace::CloseInactiveTabsAndPanes", + "ctrl-w ctrl-n": "workspace::NewFileSplitHorizontal", + "ctrl-w n": "workspace::NewFileSplitHorizontal" } }, { diff --git a/crates/docs_preprocessor/src/docs_preprocessor.rs b/crates/docs_preprocessor/src/docs_preprocessor.rs index cd019c2c97..0511aedb43 100644 --- a/crates/docs_preprocessor/src/docs_preprocessor.rs +++ b/crates/docs_preprocessor/src/docs_preprocessor.rs @@ -32,8 +32,9 @@ impl PreprocessorContext { _ => return None, }; - keymap.sections().find_map(|section| { - section.bindings().find_map(|(keystroke, a)| { + // Find the binding in reverse order, as the last binding takes precedence. + keymap.sections().rev().find_map(|section| { + section.bindings().rev().find_map(|(keystroke, a)| { if a.to_string() == action { Some(keystroke.to_string()) } else { diff --git a/crates/gpui/src/key_dispatch.rs b/crates/gpui/src/key_dispatch.rs index bd4c2564e7..3e5180eed1 100644 --- a/crates/gpui/src/key_dispatch.rs +++ b/crates/gpui/src/key_dispatch.rs @@ -393,8 +393,8 @@ impl DispatchTree { false } - /// Returns key bindings that invoke an action on the currently focused element, in precedence - /// order (reverse of the order they were added to the keymap). + /// Returns key bindings that invoke an action on the currently focused element. Bindings are + /// returned in the order they were added. For display, the last binding should take precedence. pub fn bindings_for_action( &self, action: &dyn Action, diff --git a/crates/gpui/src/keymap.rs b/crates/gpui/src/keymap.rs index 65aeba545f..03739feb55 100644 --- a/crates/gpui/src/keymap.rs +++ b/crates/gpui/src/keymap.rs @@ -67,7 +67,8 @@ impl Keymap { self.bindings.iter() } - /// Iterate over all bindings for the given action, in the order they were added. + /// Iterate over all bindings for the given action, in the order they were added. For display, + /// the last binding should take precedence. pub fn bindings_for_action<'a>( &'a self, action: &'a dyn Action, diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index da645750a5..0d496e49f9 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -292,6 +292,7 @@ impl MacPlatform { } => { let keystrokes = keymap .bindings_for_action(action.as_ref()) + .rev() .next() .map(|binding| binding.keystrokes()); diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index e1a32da316..71ded77611 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -3090,8 +3090,7 @@ impl<'a> WindowContext<'a> { /// binding for the action (last binding added to the keymap). pub fn keystroke_text_for(&self, action: &dyn Action) -> String { self.bindings_for_action(action) - .into_iter() - .next() + .last() .map(|binding| { binding .keystrokes() @@ -3744,8 +3743,8 @@ impl<'a> WindowContext<'a> { actions } - /// Returns key bindings that invoke an action on the currently focused element, in precedence - /// order (reverse of the order they were added to the keymap). + /// Returns key bindings that invoke an action on the currently focused element. Bindings are + /// returned in the order they were added. For display, the last binding should take precedence. pub fn bindings_for_action(&self, action: &dyn Action) -> Vec { self.window .rendered_frame @@ -3757,15 +3756,15 @@ impl<'a> WindowContext<'a> { } /// Returns key bindings that invoke the given action on the currently focused element, without - /// checking context. Bindings are returned returned in precedence order (reverse of the order - /// they were added to the keymap). + /// checking context. Bindings are returned in the order they were added. For display, the last + /// binding should take precedence. pub fn all_bindings_for_input(&self, input: &[Keystroke]) -> Vec { RefCell::borrow(&self.keymap).all_bindings_for_input(input) } /// Returns any bindings that would invoke an action on the given focus handle if it were - /// focused. Bindings are returned returned in precedence order (reverse of the order - /// they were added to the keymap). + /// focused. Bindings are returned in the order they were added. For display, the last binding + /// should take precedence. pub fn bindings_for_action_in( &self, action: &dyn Action, diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index 4506890a00..57db095bee 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -2,7 +2,7 @@ use std::rc::Rc; use crate::{settings_store::parse_json_with_comments, SettingsAssets}; use anyhow::anyhow; -use collections::{BTreeMap, HashMap, IndexMap}; +use collections::{HashMap, IndexMap}; use gpui::{ Action, ActionBuildError, AppContext, InvalidKeystrokeError, KeyBinding, KeyBindingContextPredicate, NoAction, SharedString, KEYSTROKE_PARSE_EXPECTED_MESSAGE, @@ -50,9 +50,12 @@ pub struct KeymapSection { /// This keymap section's bindings, as a JSON object mapping keystrokes to actions. The /// keystrokes key is a string representing a sequence of keystrokes to type, where the /// keystrokes are separated by whitespace. Each keystroke is a sequence of modifiers (`ctrl`, - /// `alt`, `shift`, `fn`, `cmd`, `super`, or `win`) followed by a key, separated by `-`. + /// `alt`, `shift`, `fn`, `cmd`, `super`, or `win`) followed by a key, separated by `-`. The + /// order of bindings does matter. When the same keystrokes are bound at the same context depth, + /// the binding that occurs later in the file is preferred. For displaying keystrokes in the UI, + /// the later binding for the same action is preferred. #[serde(default)] - bindings: Option>, + bindings: Option>, #[serde(flatten)] unrecognized_fields: IndexMap, // This struct intentionally uses permissive types for its fields, rather than validating during @@ -64,7 +67,7 @@ pub struct KeymapSection { } impl KeymapSection { - pub fn bindings(&self) -> impl Iterator { + pub fn bindings(&self) -> impl DoubleEndedIterator { self.bindings.iter().flatten() } } @@ -235,8 +238,7 @@ impl KeymapFile { } if let Some(bindings) = bindings { - for binding in bindings { - let (keystrokes, action) = binding; + for (keystrokes, action) in bindings { let result = Self::load_keybinding( keystrokes, action, @@ -548,7 +550,7 @@ impl KeymapFile { serde_json::to_value(root_schema).unwrap() } - pub fn sections(&self) -> impl Iterator { + pub fn sections(&self) -> impl DoubleEndedIterator { self.0.iter() } } diff --git a/crates/ui/src/components/keybinding.rs b/crates/ui/src/components/keybinding.rs index 16d976b018..4103924a18 100644 --- a/crates/ui/src/components/keybinding.rs +++ b/crates/ui/src/components/keybinding.rs @@ -19,7 +19,7 @@ impl KeyBinding { /// Returns the highest precedence keybinding for an action. This is the last binding added to /// the keymap. User bindings are added after built-in bindings so that they take precedence. pub fn for_action(action: &dyn Action, cx: &mut WindowContext) -> Option { - let key_binding = cx.bindings_for_action(action).last().cloned()?; + let key_binding = cx.bindings_for_action(action).into_iter().rev().next()?; Some(Self::new(key_binding)) } @@ -29,7 +29,11 @@ impl KeyBinding { focus: &FocusHandle, cx: &mut WindowContext, ) -> Option { - let key_binding = cx.bindings_for_action_in(action, focus).last().cloned()?; + let key_binding = cx + .bindings_for_action_in(action, focus) + .into_iter() + .rev() + .next()?; Some(Self::new(key_binding)) } @@ -198,7 +202,8 @@ impl KeyIcon { /// Returns a textual representation of the key binding for the given [`Action`]. pub fn text_for_action(action: &dyn Action, cx: &WindowContext) -> Option { - let key_binding = cx.bindings_for_action(action).last().cloned()?; + let bindings = cx.bindings_for_action(action); + let key_binding = bindings.last()?; Some(text_for_key_binding(key_binding, PlatformStyle::platform())) } @@ -209,13 +214,14 @@ pub fn text_for_action_in( focus: &FocusHandle, cx: &mut WindowContext, ) -> Option { - let key_binding = cx.bindings_for_action_in(action, focus).last().cloned()?; + let bindings = cx.bindings_for_action_in(action, focus); + let key_binding = bindings.last()?; Some(text_for_key_binding(key_binding, PlatformStyle::platform())) } /// Returns a textual representation of the given key binding for the specified platform. pub fn text_for_key_binding( - key_binding: gpui::KeyBinding, + key_binding: &gpui::KeyBinding, platform_style: PlatformStyle, ) -> String { key_binding