Zsh Edit is a set of handy utilities for making life easier on the Zsh command line.
Tested to work with Zsh 5.8 and newer.
I recommend using Znap or installing the plugin manually. You can also install it using any 3rd-party framework or plugin manager you like, but I won't document that here.
Aust add this to your .zshrc
file:
znap source marlonrichert/zsh-edit
To update, run znap pull
.
- Clone the repo:
% git clone --depth 1 https://github.com/marlonrichert/zsh-edit.git
- Source the plugin in your
.zshrc
file:source <your plugins dir>/zsh-edit/zsh-edit.plugin.zsh
- Restart your shell:
exec zsh
To update:
% cd <your plugins dir>/zsh-edit
% git pull
Bind shell commands directly to keyboard shortcuts. What's more, when using these, your current command line will be left intact.
bind '^[:' 'cd ..'
bind '^[-' 'pushd -1' \
'^[=' 'pushd +0'
List duplicate keybindings in the main keymap or another one.
bind -d
bind -dM viins
List unused keybindings in the main keymap or another one.
bind -u
bind -uM emacs
Look up which combination of keys could generate an escape sequence listed by bind
or bindkey
.
% bind -n '^[[5~' '^[^[OA'
"^[[5~" PageUp
"^[^[OA" Alt-Up
Zsh Edit adds the keyboard shortcuts below to your main
and emacs
keymaps.
- By default, the
emacs
keymap is yourmain
keymap. - However, if you use
vi
mode, then yourmain
keymap will be theviins
keymap.
All key bindings can be modified through Zsh's bindkey
command, after sourcing Zsh Edit.
- Not all terminals support all key bindings.
- In some terminals, instead of Alt, you'll have to press Esc or Ctrl[.
- In many terminals, Home, End, PgUp and PgDn scroll the terminal buffer and don't send any keystrokes to the shell. To use these keys in the shell, you'll have to hold an additional modifier key, usually Shift. Refer to your terminal's documentation and/or settings for more info.
Command | emacs keymap |
main keymap |
|
---|---|---|---|
Redo (reverse Undo) | Alt/ | ||
Recover last line aborted with CtrlC or CtrlG | CtrlAltG | ||
Replace all | Ctrl] | ||
Reverse yank pop | AltY | ||
Repeat word up | Alt. | ||
Repeat word down | Alt, | ||
Repeat word left | CtrlAlt- | ||
Repeat word right | AltShift- | ||
Backward subword | CtrlAltB | Ctrl← | CtrlAlt← |
Forward subword | CtrlAltF | Ctrl→ | CtrlAlt→ |
Backward shell word | AltB | Alt← | Shift← |
Forward shell word | AltF | Alt→ | Shift→ |
Beginning of line | CtrlA | Home | CtrlX ← |
End of line | CtrlE | End | CtrlX → |
Beginning of buffer | Alt< | PgUp | CtrlX ↑ |
End of buffer | Alt> | PgDn | CtrlX ↓ |
Backward delete character | ⌫ | ||
Forward delete character | ⌦ | ||
Backward kill subword | CtrlH | Ctrl⌫ | AltCtrl⌫ |
Forward kill subword | CtrlAltD | Ctrl⌦ | AltCtrl⌦ |
Backward kill shell word | CtrlW | Alt⌫ | Shift⌫ |
Forward kill shell word | AltD | Alt⌦ | Shift⌦ |
Backward kill line | CtrlU | CtrlShift⌫ | CtrlX ⌫ |
Forward kill line | CtrlK | CtrlShift⌦ | CtrlX ⌦ |
Press Ctrl] followed by two characters and each substring consisting of one or more occurences of the first character will be replaced entirely with the second character. This is useful, for example, if you pasted a list of files separated by line breaks into the command line, but you need them to be separated with spaces instead.
If you've just pasted something or the region is active, only the pasted or selected text is affected. This way, you can find-and-replace selectively. Otherwise, this widget always operates on the whole command line.
Whenever you use yank (^Y
in emacs
), vi-put-after (p
in vicmd
) or vi-put-after
(P
in vicmd
) to paste a kill into the command line, Zsh Edit will list the contents of your kill ring (including
the cut buffer) below your command line. In addition, Zsh Edit eliminates all duplicate kills from your kill ring.
Thus, each entry listed is guaranteed to be unique.
Furthermore, after pasting, when you use yank-pop (^[y
in emacs
), Zsh Edit will show you which kill is
currently selected, making it easier to cycle to the right one. To view your clipboard at any time – without modifying
your command line – just press yank-pop by itself.
Finally, Zsh Edit adds a new widget reverse-yank-pop, which lets you cycle in the opposite direction. It is
bound to ^[Y
in the emacs
keymap.
Zsh's widgets forward-word, backward-word, kill-word and backward-kill-word fail to stop on many of the positions that we humans see as word boundaries:
# Zsh with default WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' moves/deletes way too much:
# > > > > >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/*.ext
# < < < < <
# Zsh with WORDCHARS='' is bit better, but skips punctuation clusters & doesn't find subWords:
# > > > > > > > >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/*.ext
# < < < < < < < < <
Zsh Edit adds new widgets with better parsing rules that can find all the word boundaries that matter to us as humans. Additionally, it adds smarter movement: If the cursor is inside a word, it will move to the beginning or end of that same word, not the next one. This way, you can quickly toggle between the beginning and the end of each word.
For example:
# Zsh Edit with WORDCHARS=''
# > > > > > > > > > > > > >
% ENV_VAR=value command --option-flag camelCaseWord ~/dir/?*.ext
# < < < < < < < < < < < < <
To stop a character from being treated as a subword separator, simply add it to $WORDCHARS
. For example, by treating
~
, *
and ?
as word characters, you can get more precise subword movement in path strings:
# Zsh Edit with WORDCHARS='~*?'
# > > > > >
% cd ~/dir/?*.ext
# < < < < <
If you don't want to change your $WORDCHARS
globally, you can instead use the following:
zstyle ':edit:*' word-chars '~*?'
This will change $WORDCHARS
only for the widgets provided by Zsh Edit.
© 2020-2023 Marlon Richert
This project is licensed under the MIT License. See the LICENSE file for details.