Alternative to Ctrl-R reverse search in bash
I'm using the fuzzy finder program FZF. I've written my own key bindings and shell scripts to utilize FZF as my tool of choice to reverse-search an interactive Bash shell's history. Feel free to copy and paste the code from my Config GitHub repository.
~/.bashrc configuration file
# Test if fuzzy finder program _Fzf_ is installed.
#
if type -p fzf &> /dev/null; then
# Test if _Fzf_ specific _Readline_ file is readable.
#
if [[ -f ~/.inputrc.fzf && -r ~/.inputrc.fzf ]]; then
# Make _Fzf_ available through _Readline_ key bindings.
#
bind -f ~/.inputrc.fzf
fi
fi
~/.inputrc.fzf configuration file ##
$if mode=vi
# Key bindings for _Vi_ _Insert_ mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set keymap vi-insert
"\C-x\C-a": vi-movement-mode
"\C-x\C-e": shell-expand-line
"\C-x\C-r": redraw-current-line
"\C-x^": history-expand-line
"\C-r": "\C-x\C-addi$(HISTTIMEFORMAT= history | fzf-history)\C-x\C-e\C-x\C-r\C-x^\C-x\C-a$a"
# Key bindings for _Vi_ _Command_ mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set keymap vi-command
"\C-r": "i\C-r"
"\ec": "i\ec"
$endif
fzf-history executable Bash script
#!/usr/bin/env bash
#
# Retrieve command from history with fuzzy finder
# ===============================================
# Tim Friske <[email protected]>
#
# See also:
# * man:bash[1]
# * man:fzf[1]
# * man:cat[1]
shopt -os nounset pipefail errexit errtrace
shopt -s extglob globstar
function print_help {
1>&2 cat \
<<'HELP'
usage:
HISTTIMEFORMAT= history | fzf-history
HELP
}
function fzf_history {
if [[ -t 0 ]]; then
print_help
exit
fi
local fzf_options=()
fzf_options+=(${FZF_DEFAULT_OPTS:-})
fzf_options+=('--tac' '-n2..,..' '--tiebreak=index')
fzf_options+=(${FZF_HISTORY_FZF_OPTS:-})
fzf_options+=('--print0')
local cmd='' cmds=()
while read -r -d '' cmd; do
cmds+=("${cmd/#+([[:digit:]])+([[:space:]])/}")
done < <(fzf "${fzf_options[@]}")
if [[ "${#cmds[*]}" -gt 0 ]]; then
(IFS=';'; printf '%s\n' "${cmds[*]}")
fi
}
fzf_history "$@"
key-bindings.bash sourceable Bash script
Taken and slightly adapted from FZF's Bash key bindings file here are the Emacs mode compatible key bindings for Bash's history reverse-search with Ctrl-R (untested):
if [[ ! -o vi ]]; then
# Required to refresh the prompt after fzf
bind '"\er": redraw-current-line'
bind '"\e^": history-expand-line'
# CTRL-R - Paste the selected command from history into the command line
bind '"\C-r": " \C-e\C-u\C-y\ey\C-u$(HISTTIMEFORMAT= history | fzf-history)\e\C-e\er\e^"'
fi
- Up arrow: only practical for very recent stuff.
grep blablabla ~/.bash_history
: you will have to set bash to save history to file after each command.
From my ~/.bashrc
You may want to find out what the commands do and tweak.
# don't put duplicate lines in the history. See bash(1) for more options
HISTCONTROL=ignorespace:ignoredups:erasedups
HISTFILESIZE=99999
HISTSIZE=99999
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
# append to the history file, don't overwrite it
shopt -s histappend
#history
shopt -s cmdhist
shopt -s histreedit
shopt -s histverify
shopt -s lithist