Re-entrant SendKeystrokes (#20277)
Release Notes: - Improved `workspace::SendKeystrokes` to support re-binding keys. For example you can now do: `"x": ["workspace::SendKeystrokes", "\" _ x"]` in vim mode to ensure that `x` does not clobber your clipboard. - Improved key binding documentation
This commit is contained in:
parent
50069a2153
commit
38b1940251
4 changed files with 137 additions and 475 deletions
|
@ -1403,6 +1403,32 @@ async fn test_remap_nested_pineapple(cx: &mut gpui::TestAppContext) {
|
|||
cx.shared_state().await.assert_eq("🍍ˇ");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_remap_recursion(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
cx.update(|cx| {
|
||||
cx.bind_keys([KeyBinding::new(
|
||||
"x",
|
||||
workspace::SendKeystrokes("\" _ x".to_string()),
|
||||
Some("VimControl"),
|
||||
)]);
|
||||
cx.bind_keys([KeyBinding::new(
|
||||
"y",
|
||||
workspace::SendKeystrokes("2 x".to_string()),
|
||||
Some("VimControl"),
|
||||
)])
|
||||
});
|
||||
cx.neovim.exec("noremap x \"_x").await;
|
||||
cx.neovim.exec("map y 2x").await;
|
||||
|
||||
cx.set_shared_state("ˇhello").await;
|
||||
cx.simulate_shared_keystrokes("d l").await;
|
||||
cx.shared_clipboard().await.assert_eq("h");
|
||||
cx.simulate_shared_keystrokes("y").await;
|
||||
cx.shared_clipboard().await.assert_eq("h");
|
||||
cx.shared_state().await.assert_eq("ˇlo");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_escape_while_waiting(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
|
11
crates/vim/test_data/test_remap_recursion.json
Normal file
11
crates/vim/test_data/test_remap_recursion.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{"Exec":{"command":"noremap x \"_x"}}
|
||||
{"Exec":{"command":"map y 2x"}}
|
||||
{"Put":{"state":"ˇhello"}}
|
||||
{"Key":"d"}
|
||||
{"Key":"l"}
|
||||
{"Get":{"state":"ˇello","mode":"Normal"}}
|
||||
{"ReadRegister":{"name":"\"","value":"h"}}
|
||||
{"Key":"y"}
|
||||
{"Get":{"state":"ˇlo","mode":"Normal"}}
|
||||
{"ReadRegister":{"name":"\"","value":"h"}}
|
||||
{"Get":{"state":"ˇlo","mode":"Normal"}}
|
|
@ -752,7 +752,7 @@ pub struct Workspace {
|
|||
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||
database_id: Option<WorkspaceId>,
|
||||
app_state: Arc<AppState>,
|
||||
dispatching_keystrokes: Rc<RefCell<Vec<Keystroke>>>,
|
||||
dispatching_keystrokes: Rc<RefCell<(HashSet<String>, Vec<Keystroke>)>>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
_apply_leader_updates: Task<Result<()>>,
|
||||
_observe_current_user: Task<Result<()>>,
|
||||
|
@ -1784,6 +1784,11 @@ impl Workspace {
|
|||
}
|
||||
|
||||
fn send_keystrokes(&mut self, action: &SendKeystrokes, cx: &mut ViewContext<Self>) {
|
||||
let mut state = self.dispatching_keystrokes.borrow_mut();
|
||||
if !state.0.insert(action.0.clone()) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
let mut keystrokes: Vec<Keystroke> = action
|
||||
.0
|
||||
.split(' ')
|
||||
|
@ -1791,16 +1796,16 @@ impl Workspace {
|
|||
.collect();
|
||||
keystrokes.reverse();
|
||||
|
||||
self.dispatching_keystrokes
|
||||
.borrow_mut()
|
||||
.append(&mut keystrokes);
|
||||
state.1.append(&mut keystrokes);
|
||||
drop(state);
|
||||
|
||||
let keystrokes = self.dispatching_keystrokes.clone();
|
||||
cx.window_context()
|
||||
.spawn(|mut cx| async move {
|
||||
// limit to 100 keystrokes to avoid infinite recursion.
|
||||
for _ in 0..100 {
|
||||
let Some(keystroke) = keystrokes.borrow_mut().pop() else {
|
||||
let Some(keystroke) = keystrokes.borrow_mut().1.pop() else {
|
||||
keystrokes.borrow_mut().0.clear();
|
||||
return Ok(());
|
||||
};
|
||||
cx.update(|cx| {
|
||||
|
@ -1817,7 +1822,8 @@ impl Workspace {
|
|||
}
|
||||
})?;
|
||||
}
|
||||
keystrokes.borrow_mut().clear();
|
||||
|
||||
*keystrokes.borrow_mut() = Default::default();
|
||||
Err(anyhow!("over 100 keystrokes passed to send_keystrokes"))
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
|
|
@ -1,62 +1,50 @@
|
|||
# Key bindings
|
||||
|
||||
Zed can be configured via a simple JSON file located at `~/.config/zed/keymap.json`.
|
||||
Zed has a very customizable key binding system — you can tweak everything to work exactly how your fingers expect!
|
||||
|
||||
## Predefined keymaps
|
||||
|
||||
We have a growing collection of pre-defined keymaps in [zed repository's keymaps folder](https://github.com/zed-industries/zed/tree/main/assets/keymaps). Our current keymaps include:
|
||||
If you're used to a specific editor's defaults you can set a `base_keymap` in your [settings file](./configuring-zed.md). We currently have:
|
||||
|
||||
- VSCode (default)
|
||||
- Atom
|
||||
- JetBrains
|
||||
- SublimeText
|
||||
- TextMate
|
||||
- VSCode (default)
|
||||
- None (disables _all_ key bindings)
|
||||
|
||||
These keymaps can be set via the `base_keymap` setting in your `settings.json` file. Additionally, if you'd like to work from a clean slate, you can provide `"None"` to the setting.
|
||||
You can also enable `vim_mode`, which adds vim bindings too.
|
||||
|
||||
## Custom key bindings
|
||||
## User keymaps
|
||||
|
||||
### Accessing custom key bindings
|
||||
Zed reads your keymap from `~/.zed/keymap.json` on MacOS (or `~/.config/zed/keymap.json` on Linux). You can open the file within Zed with {#kb zed::OpenKeymap}, or via `zed: Open Keymap` in the command palette.
|
||||
|
||||
You can open `keymap.json` via `⌘` + `K`, `⌘` + `S`, the command palette, or the `Zed > Settings > Open Key Bindings` application menu item.
|
||||
The file contains a JSON array of objects with `"bindings"`. If no `"context"` is set the bindings are always active. If it is set the binding is only active when the [context matches](#contexts).
|
||||
|
||||
### Adding a custom key binding
|
||||
Within each binding section a [key sequence](#keybinding-syntax) is mapped to an [action](#actions). If conflicts are detected they are resolved as [described below](#precedence).
|
||||
|
||||
To customize key bindings, specify a context and the list of bindings to set. Re-mapping an existing binding will clobber the existing binding in favor of the custom one.
|
||||
|
||||
An example of adding a set of custom key bindings:
|
||||
For example:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"ctrl-w": "editor::SelectLargerSyntaxNode",
|
||||
"ctrl-shift-W": "editor::SelectSmallerSyntaxNode",
|
||||
"ctrl-c": "editor::Cancel"
|
||||
"ctrl-right": "editor::SelectLargerSyntaxNode",
|
||||
"ctrl-left": "editor::SelectSmallerSyntaxNode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProjectPanel && not_editing",
|
||||
"bindings": {
|
||||
"o": "project_panel::Open"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
You can see more examples in Zed's [`default.json`](https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-macos.json)
|
||||
You can see all of Zeds default bindings in the default keymaps for [MacOS](https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-macos.json) or [Linux](https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-linux.json).
|
||||
|
||||
_There are some key bindings that can't be overridden; we are working on an issue surrounding this._
|
||||
|
||||
### Disabling a key binding
|
||||
|
||||
Use `null` value to disable a key binding:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"alt-\\": null
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
If you want to debug problems with custom keymaps you can use `debug: Open Key Context View` from the command palette. Please file [an issue](https://github.com/zed-industries/zed) if you run into something you think should work but isn't.
|
||||
|
||||
### Keybinding syntax
|
||||
|
||||
|
@ -91,38 +79,76 @@ It is possible to match against typing a modifier key on its own. For example `s
|
|||
|
||||
### Contexts
|
||||
|
||||
Each key binding includes a `context` which determes when the key binding is active. If no context key is present it is considered to be in the `Global` context. The context is a boolean expression that can include the following:
|
||||
If a binding group has a `"context"` key it will be matched against the currently active contexts in Zed.
|
||||
|
||||
- Pane
|
||||
- Workspace
|
||||
- Editor
|
||||
- Menu
|
||||
- Terminal
|
||||
- Assistant
|
||||
- ProjectPanel
|
||||
- ProjectSearch
|
||||
- BufferSearch
|
||||
- Search
|
||||
- Dock
|
||||
- EmptyPane
|
||||
- SharedScreen
|
||||
- VimControl
|
||||
- vim_mode == normal
|
||||
- vim_mode == visual
|
||||
- vim_mode == insert
|
||||
- vim_mode == replace
|
||||
- vim_mode == operator
|
||||
- vim_mode == waiting
|
||||
Zed's contexts make up a tree, with the root being `Workspace`. Workspaces contain Panes and Panels, and Panes contain Editors, etc. The easiest way to see what contexts are active at a given moment is the key context view, which you can get to with `debug: Open Key Context View` in the command palette.
|
||||
|
||||
<!--
|
||||
TBD: Improve keybinding contexts documentation https://github.com/zed-industries/zed/issues/14718
|
||||
-->
|
||||
Contexts can contain extra attributes in addition to the name, so that you can (for example) match only in markdown files with `"context": "Editor && extension==md"`. It's worth noting that you can only use attributes at the level they are defined.
|
||||
|
||||
See also: [vim context docs](./vim.md#contexts)
|
||||
For example:
|
||||
|
||||
```
|
||||
# in an editor, it might look like this:
|
||||
Workspace os=macos
|
||||
Pane
|
||||
Editor mode=full extension=md inline_completion vim_mode=insert
|
||||
|
||||
# in the project panel
|
||||
Workspace os=macos
|
||||
Dock
|
||||
ProjectPanel not_editing
|
||||
```
|
||||
|
||||
Context expressions can contain the following syntax:
|
||||
|
||||
- `X && Y`, `X || Y` to and/or two conditions
|
||||
- `!X` to negate a condition
|
||||
- `(X)` for grouping
|
||||
- `X > Y` to match if a parent in the tree matches X and this layer matches Y.
|
||||
|
||||
If you're using Vim mode, we have information on how [vim modes influence the context](./vim.md#contexts)
|
||||
|
||||
### Actions
|
||||
|
||||
Pretty much all of Zed's functionality is exposed as actions. Although there is
|
||||
no explicitly documented list, you can find most of them by searching in the
|
||||
command palette, by looking in the default keymaps for
|
||||
[MacOS](https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-macos.json)
|
||||
or
|
||||
[Linux](https://github.com/zed-industries/zed/blob/main/assets/keymaps/default-linux.json), or by using Zed's autocomplete in your keymap file.
|
||||
|
||||
Most actions do not require any arguments, and so you can bind them as strings: `"ctrl-a": "language_selector::Toggle"`. Some require a single argument, and must be bound as an array: `"ctrl-a": ["workspace::ActivatePaneInDirection", "down"]`. Some actions require multiple arguments, and are bound as an array of a string and an object: `"ctrl-a": ["pane::DeploySearch", { "replace_enabled": true }]`.
|
||||
|
||||
### Precedence
|
||||
|
||||
When multiple keybindings have the same keystroke and are active at the same time, precedence is resolved in two ways:
|
||||
|
||||
- Bindings that match on lower nodes in the context tree win. This means that if you have a binding with a context of `Editor` it will take precedence over a binding with a context of `Workspace`. Bindings with no context match at the lowest level in the tree.
|
||||
- If there are multiple bindings that match at the same level in the tree, then the binding defined later takes precedence. As user keybindings are loaded after system keybindings, this allows user bindings to take precedence over builtin keybindings.
|
||||
|
||||
The other kind of conflict that arises is when you have two bindings, one of which is a prefix of the other. For example if you have `"ctrl-w":"editor::DeleteToNextWordEnd"` and `"ctrl-w left":"editor::DeleteToEndOfLine"`.
|
||||
|
||||
When this happens, and both bindings are active in the current context, Zed will wait for 1 second after you tupe `ctrl-w` to se if you're about to type `left`. If you don't type anything, or if you type a different key, then `DeleteToNextWordEnd` will be triggered. If you do, then `DeleteToEndOfLine` will be triggered.
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
### Disabling a binding
|
||||
|
||||
If you'd like a given binding to do nothing in a given context you can use
|
||||
`null` as the action. This is useful if you hit the keybinding by accident and
|
||||
want to disable it, or if you want to type the character that would be typed by
|
||||
the sequence (for example to disable the builtin `alt-t` binding), or if you
|
||||
want to disable multikey bindings starting with that key.
|
||||
|
||||
```
|
||||
"bindings": { "cmd-k": null }
|
||||
```
|
||||
|
||||
A `null` has the same precedence rules as normal actions. So disables all bindings that would match further up in the tree too. If you'd like a binding that matches further up in the tree to take precedence over a lower binding, you need to rebind it to the action you want in the context you want.
|
||||
|
||||
### Remapping keys
|
||||
|
||||
A common request is to be able to map from one sequence of keys to another. As of Zed 0.124.0 you can do this with the `workspace::SendKeystrokes` action.
|
||||
A common request is to be able to map from a single keystroke to a sequence. You can do this with the `workspace::SendKeystrokes` action.
|
||||
|
||||
```json
|
||||
[
|
||||
|
@ -148,11 +174,13 @@ A common request is to be able to map from one sequence of keys to another. As o
|
|||
There are some limitations to this, notably:
|
||||
|
||||
- Any asynchronous operation will not happen until after all your key bindings have been dispatched. For example this means that while you can use a binding to open a file (as in the `cmd-alt-r` example) you cannot send further keystrokes and hope to have them interpreted by the new view.
|
||||
- Other examples of asynchronous things are: communicating with a language server, changing the language of a buffer, anything that hits the network.
|
||||
- There is a limit of 100 simulated keys at a time, this is to avoid accidental infinite recursion if you trigger SendKeystrokes again inside your bindings.
|
||||
- Other examples of asynchronous things are: opening the command palette, communicating with a language server, changing the language of a buffer, anything that hits the network.
|
||||
- There is a limit of 100 simulated keys at a time.
|
||||
|
||||
The argument to `SendKeystrokes` is a space-separated list of keystrokes (using the same syntax as above). Due to the way that keystrokes are parsed, any segment that is not recognized as a keypress will be sent verbatim to the currently focused input field.
|
||||
|
||||
If the argument to `SendKeystrokes` contains the binding used to trigger it, it will use the next-highest-precedence definition of that binding. This allows you to extend the default behaviour of a key binding.
|
||||
|
||||
### Forward keys to terminal
|
||||
|
||||
If you're on Linux or Windows, you might find yourself wanting to forward key combinations to the built-in terminal instead of them being handled by Zed.
|
||||
|
@ -172,412 +200,3 @@ For example, `ctrl-n` creates a new tab in Zed on Linux. If you want to send `ct
|
|||
|
||||
You can also bind keys to launch Zed Tasks defined in your tasks.json.
|
||||
See the [tasks documentation](tasks.md#custom-keybindings-for-tasks) for more.
|
||||
|
||||
### All key bindings
|
||||
|
||||
#### Global
|
||||
|
||||
<!--
|
||||
TBD: Update these to reflect current bindings
|
||||
TBD: Add Column with Linux shortcuts
|
||||
-->
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ------------------------- | ------------ | ----------------------- |
|
||||
| Toggle focus | Collab Panel | `⌘ + Shift + C` |
|
||||
| Toggle inlay hints | Editor | `Control + :` |
|
||||
| Cancel | Menu | `Control + C` |
|
||||
| Cancel | Menu | `Control + Escape` |
|
||||
| Cancel | Menu | `Escape` |
|
||||
| Cancel | Menu | `⌘ + Escape` |
|
||||
| Confirm | Menu | `Enter` |
|
||||
| Secondary confirm | Menu | `Control + Enter` |
|
||||
| Secondary confirm | Menu | `⌘ + Enter` |
|
||||
| Select first | Menu | `Page Up` |
|
||||
| Select first | Menu | `Shift + Page Down` |
|
||||
| Select first | Menu | `Shift + Page Up` |
|
||||
| Select first | Menu | `⌘ + Up` |
|
||||
| Select last | Menu | `Page Down` |
|
||||
| Select last | Menu | `⌘ + Down` |
|
||||
| Select next | Menu | `Control + N` |
|
||||
| Select next | Menu | `Down` |
|
||||
| Select prev | Menu | `Control + P` |
|
||||
| Select prev | Menu | `Up` |
|
||||
| Confirm input | Picker | `Alt + Enter` |
|
||||
| Confirm input | Picker | `⌘ + Alt + Enter` |
|
||||
| Use selected query | Picker | `Shift + Enter` |
|
||||
| Close window | Workspace | `⌘ + Shift + W` |
|
||||
| Follow next collaborator | Workspace | `Control + Alt + ⌘ + F` |
|
||||
| Open | Workspace | `⌘ + O` |
|
||||
| Toggle zoom | Workspace | `Shift + Escape` |
|
||||
| Debug elements | Zed | `⌘ + Alt + I` |
|
||||
| Decrease buffer font size | Zed | `⌘ + -` |
|
||||
| Hide | Zed | `⌘ + H` |
|
||||
| Hide others | Zed | `Alt + ⌘ + H` |
|
||||
| Increase buffer font size | Zed | `⌘ + +` |
|
||||
| Increase buffer font size | Zed | `⌘ + =` |
|
||||
| Minimize | Zed | `⌘ + M` |
|
||||
| Open settings | Zed | `⌘ + ,` |
|
||||
| Quit | Zed | `⌘ + Q` |
|
||||
| Reset buffer font size | Zed | `⌘ + 0` |
|
||||
| Toggle full screen | Zed | `Control + ⌘ + F` |
|
||||
|
||||
#### Editor
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| -------------------------------- | ---------- | ------------------------------- |
|
||||
| Add selection above | Editor | `⌘ + Alt + Up` |
|
||||
| Add selection above | Editor | `⌘ + Control + P` |
|
||||
| Add selection below | Editor | `⌘ + Alt + Down` |
|
||||
| Add selection below | Editor | `⌘ + Control + N` |
|
||||
| Backspace | Editor | `Backspace` |
|
||||
| Backspace | Editor | `Control + H` |
|
||||
| Backspace | Editor | `Shift + Backspace` |
|
||||
| Cancel | Editor | `Escape` |
|
||||
| Confirm code action | Editor | `Enter` |
|
||||
| Confirm completion | Editor | `Enter` |
|
||||
| Confirm completion | Editor | `Tab` |
|
||||
| Confirm rename | Editor | `Enter` |
|
||||
| Context menu first | Editor | `Page Up` |
|
||||
| Context menu last | Editor | `Page Down` |
|
||||
| Context menu next | Editor | `Control + N` |
|
||||
| Context menu next | Editor | `Down` |
|
||||
| Context menu prev | Editor | `Control + P` |
|
||||
| Context menu prev | Editor | `Up` |
|
||||
| Copy | Editor | `⌘ + C` |
|
||||
| Cut | Editor | `⌘ + X` |
|
||||
| Cut to end of line | Editor | `Control + K` |
|
||||
| Select Next | Editor | `Control + D` |
|
||||
| Delete | Editor | `Delete` |
|
||||
| Delete line | Editor | `⌘ + Shift + K` |
|
||||
| Delete to beginning of line | Editor | `⌘ + Backspace` |
|
||||
| Delete to end of line | Editor | `⌘ + Delete` |
|
||||
| Delete to next subword end | Editor | `Control + Alt + D` |
|
||||
| Delete to next subword end | Editor | `Control + Alt + Delete` |
|
||||
| Delete to next word end | Editor | `Alt + D` |
|
||||
| Delete to next word end | Editor | `Alt + Delete` |
|
||||
| Delete to previous subword start | Editor | `Control + Alt + Backspace` |
|
||||
| Delete to previous subword start | Editor | `Control + Alt + H` |
|
||||
| Delete to previous word start | Editor | `Alt + Backspace` |
|
||||
| Delete to previous word start | Editor | `Alt + H` |
|
||||
| Delete to previous word start | Editor | `Control + W` |
|
||||
| Display cursor names | Editor | `Control + ⌘ + C` |
|
||||
| Duplicate line down | Editor | `Alt + Shift + Down` |
|
||||
| Duplicate line up | Editor | `Alt + Shift + Up` |
|
||||
| Find all references | Editor | `Alt + Shift + F12` |
|
||||
| Fold | Editor | `Alt + ⌘ + [` |
|
||||
| Format | Editor | `⌘ + Shift + I` |
|
||||
| Go to definition | Editor | `F12` |
|
||||
| Go to definition split | Editor | `Alt + F12` |
|
||||
| Go to declaration | Editor | `Ctrl + F12` |
|
||||
| Go to declaration split | Editor | `Alt + Ctrl + F12` |
|
||||
| Go to diagnostic | Editor | `F8` |
|
||||
| Go to implementation | Editor | `Shift + F12` |
|
||||
| Go to prev diagnostic | Editor | `Shift + F8` |
|
||||
| Go to type definition | Editor | `⌘ + F12` |
|
||||
| Go to type definition split | Editor | `Alt + ⌘ + F12` |
|
||||
| Hover | Editor | `⌘ + K, ⌘ + I` |
|
||||
| Indent | Editor | `⌘ + ]` |
|
||||
| Join lines | Editor | `Control + J` |
|
||||
| Move down | Editor | `Control + N` |
|
||||
| Move down | Editor | `Down` |
|
||||
| Move left | Editor | `Control + B` |
|
||||
| Move left | Editor | `Left` |
|
||||
| Move line down | Editor | `Alt + Down` |
|
||||
| Move line up | Editor | `Alt + Up` |
|
||||
| Move page down | Editor | `Control + V` |
|
||||
| Move page down | Editor | `Shift + Page Down` |
|
||||
| Move page up | Editor | `Alt + V` |
|
||||
| Move page up | Editor | `Shift + Page Up` |
|
||||
| Move right | Editor | `Control + F` |
|
||||
| Move right | Editor | `Right` |
|
||||
| Move to beginning | Editor | `⌘ + Up` |
|
||||
| Move to beginning of line | Editor | `Control + A` |
|
||||
| Move to beginning of line | Editor | `Home` |
|
||||
| Move to beginning of line | Editor | `⌘ + Left` |
|
||||
| Move to enclosing bracket | Editor | `Control + M` |
|
||||
| Move to end | Editor | `⌘ + Down` |
|
||||
| Move to end of line | Editor | `Control + E` |
|
||||
| Move to end of line | Editor | `End` |
|
||||
| Move to end of line | Editor | `⌘ + Right` |
|
||||
| Move to end of paragraph | Editor | `Control + Down` |
|
||||
| Move to next subword end | Editor | `Control + Alt + F` |
|
||||
| Move to next subword end | Editor | `Control + Alt + Right` |
|
||||
| Move to next word end | Editor | `Alt + F` |
|
||||
| Move to next word end | Editor | `Alt + Right` |
|
||||
| Move to previous subword start | Editor | `Control + Alt + B` |
|
||||
| Move to previous subword start | Editor | `Control + Alt + Left` |
|
||||
| Move to previous word start | Editor | `Alt + B` |
|
||||
| Move to previous word start | Editor | `Alt + Left` |
|
||||
| Move to start of paragraph | Editor | `Control + Up` |
|
||||
| Move up | Editor | `Control + P` |
|
||||
| Move up | Editor | `Up` |
|
||||
| Next screen | Editor | `Control + L` |
|
||||
| Outdent | Editor | `⌘ + [` |
|
||||
| Page down | Editor | `Page Down` |
|
||||
| Page up | Editor | `Page Up` |
|
||||
| Paste | Editor | `⌘ + V` |
|
||||
| Redo | Editor | `⌘ + Shift + Z` |
|
||||
| Redo selection | Editor | `⌘ + Shift + U` |
|
||||
| Rename | Editor | `F2` |
|
||||
| Reveal in File Manager | Editor | `Alt + ⌘ + R` |
|
||||
| Toggle hunk diff | Editor | `⌘ + '` |
|
||||
| Expand all hunk diffs | Editor | `⌘ + "` |
|
||||
| Revert selected hunks | Editor | `⌘ + Alt + Z` |
|
||||
| Select all | Editor | `⌘ + A` |
|
||||
| Select all matches | Editor | `⌘ + Shift + L` |
|
||||
| Select down | Editor | `Control + Shift + N` |
|
||||
| Select down | Editor | `Shift + Down` |
|
||||
| Select larger syntax node | Editor | `Control + Shift + Right` |
|
||||
| Select left | Editor | `Control + Shift + B` |
|
||||
| Select left | Editor | `Shift + Left` |
|
||||
| Select line | Editor | `⌘ + L` |
|
||||
| Select next | Editor | `⌘ + D` |
|
||||
| Select next | Editor | `⌘ + K, ⌘ + D` |
|
||||
| Select previous | Editor | `Control + ⌘ + D` |
|
||||
| Select previous | Editor | `⌘ + K, Control + ⌘ + D` |
|
||||
| Select right | Editor | `Control + Shift + F` |
|
||||
| Select right | Editor | `Shift + Right` |
|
||||
| Select smaller syntax node | Editor | `Control + Shift + Left` |
|
||||
| Select to beginning | Editor | `⌘ + Shift + Up` |
|
||||
| Select to beginning of line | Editor | `Control + Shift + A` |
|
||||
| Select to beginning of line | Editor | `Shift + Home` |
|
||||
| Select to beginning of line | Editor | `⌘ + Shift + Left` |
|
||||
| Select to end | Editor | `⌘ + Shift + Down` |
|
||||
| Select to end of line | Editor | `Control + Shift + E` |
|
||||
| Select to end of line | Editor | `Shift + End` |
|
||||
| Select to end of line | Editor | `⌘ + Shift + Right` |
|
||||
| Select to end of paragraph | Editor | `Control + Shift + Down` |
|
||||
| Select to next subword end | Editor | `Control + Alt + Shift + F` |
|
||||
| Select to next subword end | Editor | `Control + Alt + Shift + Right` |
|
||||
| Select to next word end | Editor | `Alt + Shift + F` |
|
||||
| Select to next word end | Editor | `Alt + Shift + Right` |
|
||||
| Select to previous subword start | Editor | `Control + Alt + Shift + B` |
|
||||
| Select to previous subword start | Editor | `Control + Alt + Shift + Left` |
|
||||
| Select to previous word start | Editor | `Alt + Shift + B` |
|
||||
| Select to previous word start | Editor | `Alt + Shift + Left` |
|
||||
| Select to start of paragraph | Editor | `Control + Shift + Up` |
|
||||
| Select up | Editor | `Control + Shift + P` |
|
||||
| Select up | Editor | `Shift + Up` |
|
||||
| Show character palette | Editor | `Control + ⌘ + Space` |
|
||||
| Show completions | Editor | `Control + Space` |
|
||||
| Show inline completion | Editor | `Alt + \` |
|
||||
| Tab | Editor | `Tab` |
|
||||
| Tab prev | Editor | `Shift + Tab` |
|
||||
| Toggle code actions | Editor | `⌘ + .` |
|
||||
| Toggle comments | Editor | `⌘ + /` |
|
||||
| Toggle git blame | Editor | `⌘ + Alt + G, B` |
|
||||
| Toggle line numbers | Editor | `⌘ + ;` |
|
||||
| Transpose | Editor | `Control + T` |
|
||||
| Undo | Editor | `⌘ + Z` |
|
||||
| Undo selection | Editor | `⌘ + U` |
|
||||
| Unfold lines | Editor | `Alt + ⌘ + ]` |
|
||||
|
||||
#### Editor (Full Only)
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| -------------------------------- | ------------- | -------------------- |
|
||||
| Inline assist | Assistant | `Control + Enter` |
|
||||
| Quote selection | Assistant | `⌘ + >` |
|
||||
| Deploy | Buffer Search | `⌘ + Alt + F` |
|
||||
| Deploy | Buffer Search | `⌘ + E` |
|
||||
| Deploy | Buffer Search | `⌘ + F` |
|
||||
| Accept partial inline completion | Editor | `Alt + Right` |
|
||||
| Go to hunk | Editor | `⌘ + F8` |
|
||||
| Go to prev hunk | Editor | `⌘ + Shift + F8` |
|
||||
| Newline | Editor | `Enter` |
|
||||
| Newline | Editor | `Shift + Enter` |
|
||||
| Newline above | Editor | `⌘ + Shift + Enter` |
|
||||
| Newline below | Editor | `⌘ + Enter` |
|
||||
| Next inline completion | Editor | `Alt + ]` |
|
||||
| Open excerpts | Editor | `Alt + Enter` |
|
||||
| Open excerpts split | Editor | `⌘ + K, Enter` |
|
||||
| Previous inline completion | Editor | `Alt + [` |
|
||||
| Toggle soft wrap | Editor | `Alt + Z` |
|
||||
| Toggle | Go To Line | `Control + G` |
|
||||
| Toggle | Outline | `⌘ + Shift + O` |
|
||||
|
||||
#### Editor (Auto Height Only)
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ------------- | ---------- | ------------------------- |
|
||||
| Newline | Editor | `Control + Enter` |
|
||||
| Newline | Editor | `Shift + Enter` |
|
||||
| Newline below | Editor | `Control + Shift + Enter` |
|
||||
|
||||
#### Pane
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ----------------------------- | -------------- | ----------------------------- |
|
||||
| Activate item 1 | Pane | `Control + 1` |
|
||||
| Activate item 2 | Pane | `Control + 2` |
|
||||
| Activate item 3 | Pane | `Control + 3` |
|
||||
| Activate item 4 | Pane | `Control + 4` |
|
||||
| Activate item 5 | Pane | `Control + 5` |
|
||||
| Activate item 6 | Pane | `Control + 6` |
|
||||
| Activate item 7 | Pane | `Control + 7` |
|
||||
| Activate item 8 | Pane | `Control + 8` |
|
||||
| Activate item 9 | Pane | `Control + 9` |
|
||||
| Activate last item | Pane | `Control + 0` |
|
||||
| Activate next item | Pane | `Alt + ⌘ + Right` |
|
||||
| Activate next item | Pane | `⌘ + }` |
|
||||
| Activate prev item | Pane | `Alt + ⌘ + Left` |
|
||||
| Activate prev item | Pane | `⌘ + {` |
|
||||
| Swap item to left | Pane | `Control + Shift + Page Up` |
|
||||
| Swap item to right | Pane | `Control + Shift + Page Down` |
|
||||
| Close active item | Pane | `⌘ + W` |
|
||||
| Close all items | Pane | `⌘ + K, ⌘ + W` |
|
||||
| Close clean items | Pane | `⌘ + K, U` |
|
||||
| Close inactive items | Pane | `Alt + ⌘ + T` |
|
||||
| Go back | Pane | `Control + -` |
|
||||
| Go forward | Pane | `Control + Shift + _` |
|
||||
| Reopen closed item | Pane | `⌘ + Shift + T` |
|
||||
| Split down | Pane | `⌘ + K, Down` |
|
||||
| Split left | Pane | `⌘ + K, Left` |
|
||||
| Split right | Pane | `⌘ + K, Right` |
|
||||
| Split up | Pane | `⌘ + K, Up` |
|
||||
| Toggle filters | Project Search | `Alt + ⌘ + F` |
|
||||
| Toggle focus | Project Search | `⌘ + F` |
|
||||
| Toggle focus | Project Search | `⌘ + Shift + F` |
|
||||
| Activate regex mode | Search | `Alt + ⌘ + G` |
|
||||
| Activate text mode | Search | `Alt + ⌘ + X` |
|
||||
| Cycle mode | Search | `Alt + Tab` |
|
||||
| Select all matches | Search | `Alt + Enter` |
|
||||
| Select next match | Search | `⌘ + G` |
|
||||
| Select prev match | Search | `⌘ + Shift + G` |
|
||||
| Toggle case sensitive | Search | `Alt + ⌘ + C` |
|
||||
| Toggle replace | Search | `⌘ + Shift + H` |
|
||||
| Toggle whole word | Search | `Alt + ⌘ + W` |
|
||||
| Close inactive tabs and panes | Workspace | `Control + Alt + ⌘ + W` |
|
||||
|
||||
#### Buffer Search Bar
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ---------------------- | ------------- | -------------------- |
|
||||
| Dismiss | Buffer Search | `Escape` |
|
||||
| Focus editor | Buffer Search | `Tab` |
|
||||
| Cycle mode | Search | `Alt + Tab` |
|
||||
| Focus search | Search | `⌘ + F` |
|
||||
| Next history query | Search | `Down` |
|
||||
| Previous history query | Search | `Up` |
|
||||
| Replace all | Search | `⌘ + Enter` |
|
||||
| Replace next | Search | `Enter` |
|
||||
| Select all matches | Search | `Alt + Enter` |
|
||||
| Select next match | Search | `Enter` |
|
||||
| Select prev match | Search | `Shift + Enter` |
|
||||
| Toggle replace | Search | `⌘ + Alt + F` |
|
||||
|
||||
#### Workspace
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| -------------------------------- | ----------------- | ----------------------- |
|
||||
| Toggle focus | Assistant | `⌘ + ?` |
|
||||
| Open recent | Branches | `Alt + ⌘ + B` |
|
||||
| Toggle | Command Palette | `⌘ + Shift + P` |
|
||||
| Deploy | Diagnostics | `⌘ + Shift + M` |
|
||||
| Toggle | File Finder | `⌘ + P` |
|
||||
| Toggle | Language Selector | `⌘ + K, M` |
|
||||
| Deploy search | Pane | `⌘ + Shift + F` |
|
||||
| Deploy search | Pane | `⌘ + Shift + H` |
|
||||
| Toggle focus | Project Panel | `⌘ + Shift + E` |
|
||||
| Toggle | Project Symbols | `⌘ + T` |
|
||||
| Open recent | Projects | `Alt + ⌘ + O` |
|
||||
| Toggle | Tab Switcher | `Control + Shift + Tab` |
|
||||
| Toggle | Tab Switcher | `Control + Tab` |
|
||||
| Rerun | Task | `Alt + T` |
|
||||
| Spawn | Task | `Alt + Shift + T` |
|
||||
| Toggle focus | Terminal Panel | ``Control + ` `` |
|
||||
| Toggle | Theme Selector | `⌘ + K, ⌘ + T` |
|
||||
| Activate pane 1 | Workspace | `⌘ + 1` |
|
||||
| Activate pane 2 | Workspace | `⌘ + 2` |
|
||||
| Activate pane 3 | Workspace | `⌘ + 3` |
|
||||
| Activate pane 4 | Workspace | `⌘ + 4` |
|
||||
| Activate pane 5 | Workspace | `⌘ + 5` |
|
||||
| Activate pane 6 | Workspace | `⌘ + 6` |
|
||||
| Activate pane 7 | Workspace | `⌘ + 7` |
|
||||
| Activate pane 8 | Workspace | `⌘ + 8` |
|
||||
| Activate pane 9 | Workspace | `⌘ + 9` |
|
||||
| Activate pane in direction down | Workspace | `⌘ + K, ⌘ + Down` |
|
||||
| Activate pane in direction left | Workspace | `⌘ + K, ⌘ + Left` |
|
||||
| Activate pane in direction right | Workspace | `⌘ + K, ⌘ + Right` |
|
||||
| Activate pane in direction up | Workspace | `⌘ + K, ⌘ + Up` |
|
||||
| Close all docks | Workspace | `Alt + ⌘ + Y` |
|
||||
| New file | Workspace | `⌘ + N` |
|
||||
| New terminal | Workspace | `Control + ~` |
|
||||
| New window | Workspace | `⌘ + Shift + N` |
|
||||
| Save | Workspace | `⌘ + S` |
|
||||
| Save all | Workspace | `⌘ + Alt + S` |
|
||||
| Save as | Workspace | `⌘ + Shift + S` |
|
||||
| Save without format | Workspace | `⌘ + K, S` |
|
||||
| Swap pane in direction | Workspace | `⌘ + K, Shift + Down` |
|
||||
| Swap pane in direction | Workspace | `⌘ + K, Shift + Left` |
|
||||
| Swap pane in direction | Workspace | `⌘ + K, Shift + Right` |
|
||||
| Swap pane in direction | Workspace | `⌘ + K, Shift + Up` |
|
||||
| Toggle bottom dock | Workspace | `⌘ + J` |
|
||||
| Toggle left dock | Workspace | `⌘ + B` |
|
||||
| Toggle right dock | Workspace | `⌘ + R` |
|
||||
| Unfollow | Workspace | `Escape` |
|
||||
| Open keymap | Zed | `⌘ + K, ⌘ + S` |
|
||||
|
||||
#### Project Panel
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ----------------------- | ------------- | --------------------- |
|
||||
| Collapse selected entry | Project Panel | `Left` |
|
||||
| Copy | Project Panel | `⌘ + C` |
|
||||
| Copy path | Project Panel | `⌘ + Alt + C` |
|
||||
| Copy relative path | Project Panel | `Alt + ⌘ + Shift + C` |
|
||||
| Cut | Project Panel | `⌘ + X` |
|
||||
| Delete | Project Panel | `Backspace` |
|
||||
| Delete | Project Panel | `Delete` |
|
||||
| Delete | Project Panel | `⌘ + Backspace` |
|
||||
| Delete | Project Panel | `⌘ + Delete` |
|
||||
| Expand selected entry | Project Panel | `Right` |
|
||||
| New directory | Project Panel | `Alt + ⌘ + N` |
|
||||
| New file | Project Panel | `⌘ + N` |
|
||||
| New search in directory | Project Panel | `Alt + Shift + F` |
|
||||
| Open | Project Panel | `Space` |
|
||||
| Paste | Project Panel | `⌘ + V` |
|
||||
| Rename | Project Panel | `Enter` |
|
||||
| Rename | Project Panel | `F2` |
|
||||
| Reveal in File Manager | Project Panel | `Alt + ⌘ + R` |
|
||||
|
||||
#### Project Search Bar
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ---------------------- | -------------- | -------------------- |
|
||||
| Search in new | Project Search | `⌘ + Enter` |
|
||||
| Toggle focus | Project Search | `Escape` |
|
||||
| Activate regex mode | Search | `Alt + ⌘ + G` |
|
||||
| Activate text mode | Search | `Alt + ⌘ + X` |
|
||||
| Cycle mode | Search | `Alt + Tab` |
|
||||
| Focus search | Search | `⌘ + Shift + F` |
|
||||
| Next history query | Search | `Down` |
|
||||
| Previous history query | Search | `Up` |
|
||||
| Replace all | Search | `⌘ + Enter` |
|
||||
| Replace next | Search | `Enter` |
|
||||
| Toggle replace | Search | `⌘ + Shift + H` |
|
||||
|
||||
#### Terminal
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| --------------------------- | ---------- | --------------------- |
|
||||
| Clear | Terminal | `⌘ + K` |
|
||||
| Copy | Terminal | `⌘ + C` |
|
||||
| Delete line | Terminal | `⌘ + Backspace` |
|
||||
| Move to beginning of line | Terminal | `⌘ + Left` |
|
||||
| Move to end of line | Terminal | `⌘ + Right` |
|
||||
| Move to next word end | Terminal | `Alt + Right` |
|
||||
| Move to previous word start | Terminal | `Alt + Left` |
|
||||
| Paste | Terminal | `⌘ + V` |
|
||||
| Show character palette | Terminal | `Control + ⌘ + Space` |
|
||||
|
||||
#### Assistant Editor
|
||||
|
||||
| **Command** | **Target** | **Default Shortcut** |
|
||||
| ------------------ | ---------- | -------------------- |
|
||||
| Assist | Assistant | `⌘ + Enter` |
|
||||
| Cycle message role | Assistant | `Control + R` |
|
||||
| Quote selection | Assistant | `⌘ + >` |
|
||||
| Split | Assistant | `Shift + Enter` |
|
||||
| Save | Workspace | `⌘ + S` |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue