Better command line history in zsh with peco
Some years ago I bumped into peco, a Simplistic interactive
filtering tool written in Go; at that time there was a bit of hype around this kind of command line
tools, with several implementations published on Github. I settled on peco
because it was fast
enough, compared for example to the Python implementation, to be tolerable in my daily shell usage.
A nice and often overlooked feature of bash and zsh (provided by
readline) is reverse-i-search
, which
allows you to search and reuse previous commands from your shell history; unfortunately the
presentation of this command is quite basic and kinda hard to navigate, and this is where peco
brings value.
By adding this short snippet of code to your ~/.zshrc
you can use peco
to navigate the history
of your shell:
function exists() { which $1 &> /dev/null }
function peco_select_history() {
local tac
exists gtac && tac="gtac" || { exists tac && tac="tac" || { tac="tail -r" } }
BUFFER=$(fc -l -n 1 | eval $tac | peco --layout=bottom-up --query "$LBUFFER")
CURSOR=$#BUFFER # move cursor
zle -R -c # refresh
}
zle -N peco_select_history
bindkey '^R' peco_select_history
This is how it looks like when I press CTRL-R
and type “man”:
This become really useful when you configure zsh to have a huge history size:
SAVEHIST=10000
HISTSIZE=12000
This is really handy for command that you type over and over and you can’t really script, like pushing Chef files to the chef server.