ZSH: search history on up and down keys?
zsh provide this functionality by using
history-beginning-search-backward
history-beginning-search-forward
Ex.
bindkey "^[[A" history-beginning-search-backward
bindkey "^[[B" history-beginning-search-forward
Find exact Key code by
ctrl+vKEY
Ex.
ctrl+vUP
ctrl+vDOWN
ctrl+vPageUp
ctrl+vPageDown
etc.
In case if you are using mac the below works on OSX catalina.
bindkey "\e[5~" history-search-backward
bindkey "\e[6~" history-search-forward
This blog post from 2013 recommends a couple of keybinds that match all the words before the cursor.
# Cycle through history based on characters already typed on the line
autoload -U up-line-or-beginning-search
autoload -U down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "$key[Up]" up-line-or-beginning-search
bindkey "$key[Down]" down-line-or-beginning-search
If $key[Up]
and $key[Down]
don't work on your machine, you could try $terminfo[kcuu1]
and $terminfo[kcud1]
instead.
This is the documented behavior:
down-line-or-search
Move down a line in the buffer, or if already at the bottom line, search forward in the history for a line beginning with the first word in the buffer.
There doesn't seem to be an existing widget that does exactly what you want, so you'll have to make your own. Here's how to define a widget that behaves like up-line-or-search
, but using the beginning of the line (up to the cursor) rather than the first word as search string. Not really tested, especially not on multi-line input.
up-line-or-search-prefix () {
local CURSOR_before_search=$CURSOR
zle up-line-or-search "$LBUFFER"
CURSOR=$CURSOR_before_search
}
zle -N up-line-or-search-prefix
An alternate approach is to use history-beginning-search-backward
, but only call it if the cursor is on the first line. Untested.
up-line-or-history-beginning-search () {
if [[ -n $PREBUFFER ]]; then
zle up-line-or-history
else
zle history-beginning-search-backward
fi
}
zle -N up-line-or-history-beginning-search