Interact with this post using Mastodon or
Bring the power of fzf into your zsh
Published on
If you’ve been following this blog, you know that I’m fzf
addict. I use it for a lot of things in noevim (e.g. file search, paths integration, notes
…), to search for online videos with ytfzf
, and in zsh
. Today I’d like to talk about the latter.
I use fzf developed by junegunn to browse my files (which I now find it way faster and efficient than using a file browser), as a replacement to the default zsh history, and to search text within files.
╭── Files browsing
zsh
is by default awesome for files browsing as it can for example automagically complete a command like cd /u/b/fir
into cd /usr/bin/firefox
. In case, there would be several options to complete a command, zsh
would let me circle through them. You can further improve this, especially if you don’t remember the exact path of a file.
For that, there is the completion.zsh
script from junegunn. Place it in you $USER/.config/fzf folder, reload zsh
and you’re done. Yes, it’s that simple!
Calling for autocompletion will open an fzf window where you can fuzzy search anything. Now that you improved your workflow, make it your own. You can change the command to search files, use fzf-tmux
, and change any regular fzf
options by adding something like that in your .zshrc
:
export FZF_DEFAULT_COMMAND='fd -H -L . ~' # set fd options
export YTFZF_CONFIG_DIR=$HOME/.config/ytfzf #define ytfzf path
export FZF_TMUX='1' # use fzf-tmux
export FZF_TMUX_OPTS='-h 40% -w 100% -x 0 -y 40' # set fzf-tmux window properties
# 1. change the search result to the directory selected with a the right arrow
# 2. set a fzf-tmux preview window based on filetype:
# .txt, .sh., .md,. .org, .norg files are previewed with a cat command
# .zip files are previwed with an unzip command
# .tar files are previwed with a tar command
# .pdf files are previwed with a pdftotext command
# all other files will trigger an eza command
export FZF_COMPLETION_OPTS='--reverse --keep-right --info=inline -e -m --bind "right:execute(tree -i -f -L 1 {} | fzf)" --preview="if echo {} | grep -Eq \".txt$|.sh$|.md$|.org$|.norg$\"; then cat {} | head -20; \
elif echo {} | grep -q \".zip$\"; then unzip -l {}; \
elif echo {} | grep -q \".tar$\"; then tar -tf {}; \
elif echo {} | grep -q \".pdf$\"; then pdftotext {} - | head -20; \
else eza -A --group-directories-first {}; fi"'
export FZF_COMPLETION_TRIGGER="" # allow using Tab to call for completion
# define the command and exclude some paths from files search to increase performance
_fzf_compgen_path() {
fd -H -L --exclude=/proc --exclude=/media/work . /
}
# define the command and exclude some paths from directories search to increase performance
_fzf_compgen_dir() {
fd -H -L --type d --exclude=/proc --exclude=/media/work . /
}
Note that I’m using commands like fd, cat, eza . Feel free to use anything you like.
As a last trick, I would highly recommend adding setopt autocd
to your .zshrc
. With that, you won’t have to type cd
anymore to jump into a directory.
╭── Searching text within files
If you’re not familiar with ripgrep-all I highly recommend you take a look at it (mentioned in a previous post ). It’s a wonderful tool to look for text within files. Running it will output a list of the files that contain your text as well as an excerpt with your highlighted text.
You can combine the power of fzf
to this command, so you will have a window with a list of files that contain your text on the left and on the right you will see the excerpt of interest for each file when you select one.
To achieve that, you only have to add something like that in you .zshrc
file (or any zsh file where you store your aliases):
alias rgf='rga-fzf'
rga-fzf() {
RG_PREFIX="rga --files-with-matches"
local file
file="$(
FZF_DEFAULT_COMMAND="$RG_PREFIX '$1' '$2'" \
fzf-tmux -p -h 40% -w 100% -x 0 -y 40 --reverse --keep-right --info=inline -e --preview="[[ ! -z {} ]] && rga --pretty --colors=match:fg:229,160,57 -C=3 {q} {}")"
}
Note that I use fzf-tmux but you can use fzf only as well. You can of course go as crazy as you’d like with the fzf
options.
╭── Improved version of the zsh history
If you noticed, during the previous explanation I had a line where I change the default keybinding for autocompletion. This is because an additional script comes in addition to the autocompletion one: the key-bindings.zsh script.
Within this script there are keybinding to:
- paste the selected file path(s) into the command line (already done automatically if you followed the instructions in this post)
- cd into the selected directory (which could be automated with the tweak above)
- paste the selected command from history into the command line
If you want to access a nice history in the form of a list that you can fuzzy find, then just copy this script in your $USER/.config/fzf/ folder and reload zsh
. I love this function, it makes finding and reusing a previous command so easy.
╭── Conclusion
Be aware that following instructions in this post may made of you an fzf addict as well and I won’t take responsibility for that :)
Once you start using fzf
, you’ll instantly realize hoe much time you save in your workflow.
Thanks for your read. Hope it's been useful to you.
✄ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈
More food for thoughts? Check other posts about: #Zsh #Zsh-Plugins