ZLE is what makes zsh's command line programmable: any editing action can be bound to any key.
Everything you type at the prompt goes through ZLE, the Zsh Line Editor. Every action, from moving the cursor to searching history, is a widget, and keymaps bind key sequences to widgets.
bindkey -eselects emacs-style keys (the default unless yourEDITORcontains "vi");bindkey -vselects vi mode.bindkeyalone lists all bindings;bindkey '^R'shows one.zle -allists all widgets.- Press Ctrl-V and then a key to see the sequence it sends, such as
^[[Afor Up in most terminals.
Useful bundled widgets: up-line-or-beginning-search makes Up search history for lines starting with what you already typed; edit-command-line opens the current line in $EDITOR. Bundled widget functions must be loaded with autoload -Uz name and registered with zle -N name before binding.
A custom widget is a shell function registered with zle -N. Inside it you can read and change special variables: BUFFER (the whole line), LBUFFER and RBUFFER (text left and right of the cursor) and CURSOR (position). zle -M "text" shows a message under the prompt, and calling zle accept-line runs the line. Key bindings and widgets belong in .zshrc, and should be set before plugins like syntax highlighting that wrap existing widgets.
Example
bindkey -e # emacs keys (-v for vi mode)
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey '^[[A' up-line-or-beginning-search # Up: history matching the typed prefix
bindkey '^[[B' down-line-or-beginning-search
autoload -Uz edit-command-line && zle -N edit-command-line
bindkey '^X^E' edit-command-line # edit the line in $EDITOR
# A custom widget: Alt-s puts sudo in front of the current line
prepend-sudo() {
[[ $BUFFER == sudo\ * ]] || BUFFER="sudo $BUFFER"
CURSOR=$#BUFFER # cursor to the end
zle -M "sudo added"
}
zle -N prepend-sudo
bindkey '^[s' prepend-sudo
bindkey '^R' # "^R" history-incremental-search-backwardRemember
- Widgets are actions; bindkey maps key sequences to them
- Custom widget = function + zle -N + bindkey
- BUFFER, LBUFFER, RBUFFER and CURSOR expose the command line
Watch out for
- Binding a bundled widget like edit-command-line without autoload and zle -N, which gives 'No such widget'.