Let’s make completion (autocomplete) and search more convenient with fzf, a command-line software equipped with fuzzy search (fuzzy finder) functionality, which provides features such as command history search and file selection using these capabilities.
Installation is super simple.
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
junegunn/fzf: A command-line fuzzy finder Examples · junegunn/fzf Wiki
- Search syntax
Basically, a normal search performs fuzzy search, so if you want an exact search, you should search likeToken Match type Description sbtrkt fuzzy-match Items that match sbtrkt ‘wild exact-match (quoted) Items that include wild ^music prefix-exact-match Items that start with music .mp3$ suffix-exact-match Items that end with .mp3 !fire inverse-exact-match Items that do not include fire !^music inverse-prefix-exact-match Items that do not start with music !.mp3$ inverse-suffix-exact-match Items that do not end with .mp3
On multi-select mode (-m), TAB and Shift-TAB to mark multiple items
'something.
Now, let me introduce how to use it.
String Search Becomes More Convenient
This can be used for searching within files. You can use it when you want to search the results of —help, for example.
cat <<EOT |fzf
hoge
fuga
foo
EOT

Command History Search Becomes More Convenient
This is probably the most convenient and handy feature of fzf.
You probably know that you can view command history with ctrl-R, but this makes it more convenient.
Completion (Autocomplete) Becomes More Convenient
fzf’s autocomplete is not triggered by pressing tab twice, but by typing ** (two asterisks) and then tab.
cd **<TAB>
cd ~/github/fzf**<TAB>
head /docker/**<TAB>
However, some are overridden by normal autocomplete. Try each one.
kill -9 <TAB>
Implementing Custom Autocomplete
fzf also allows you to create your own tab completion candidates.

You can specify strings like this,
_fzf_complete_history() {
_fzf_complete "--multi --reverse" "$@" < <(
echo very
echo wow
echo such
echo history
)
}
[ -n "$BASH" ] && complete -F _fzf_complete_history -o default -o bashdefault history
With some ingenuity, you can also pass command execution results. Very convenient.
_fzf_complete_sym() {
_fzf_complete "--multi --reverse" "$@" < <(command ls -1 ${HOME}/sym)
}
[ -n "$BASH" ] && complete -F _fzf_complete_sym -o default -o bashdefault sym
Code I Actually Use
Here’s some code I actually wrote and use as examples.
Completes scripts frequently connected to man [commandName].
It becomes like man bash > ~/tmp.txt && sublime_text ~/tmp.txt, but I’m displaying manual pages with sublime from WSL via x11 forwarding from a Windows environment. It’s more convenient to view man pages with sublime, whether for copy-pasting or searching, or rather I’m more used to it.
_fzf_complete_man() {
_fzf_complete "--multi --reverse" "$@" < <(
# view the man pages with sublime via x-server
echo "> ~/tmp.txt && sublime_text ~/tmp.txt "
)
}
[ -n "$BASH" ] && complete -F _fzf_complete_man -o default -o bashdefault man
sym [dirname] allows easy navigation to your favorite directories from any directory.
In my case, I have some symbolic links to Windows file system in my sym folder, mainly for videos and music, so when I want to listen to classical music on random shuffle, I do sym cla**->sym _Classic to move to the directory, then shufmusic, something like that.

sym(){
: <<'HELP'
e.g. sym
e.g. sym hinabita
e.g. sym **
HELP
[ ! -z ${1} ] && cd "${HOME}/sym/${1}" || cd "${HOME}/sym"
}
_fzf_complete_sym() {
_fzf_complete "--multi --reverse" "$@" < <(command ls -1 ${HOME}/sym)
}
[ -n "$BASH" ] && complete -F _fzf_complete_sym -o default -o bashdefault sym
Interesting Samples
When you select from command history, the command is executed immediately. Honestly, the efficiency is the same as selecting from ctrl-R and pressing enter, so I don’t think it’s worth implementing. However, it can be utilized in built-in systems.
# fh - repeat history
fh() {
eval $( ([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s --tac | sed 's/ *[0-9]* *//')
}