学习并使用 fzf
前言
fzf - 通用目的的模糊查询。
介绍
Pros
- No dependencies
- Blazingly fast
- e.g.
locate / | fzf
- e.g.
- Flexible layout
- Runs in fullscreen or in horizontal/vertical split using tmux
- The most comprehensive feature set
- Try
fzf --help
and be surprised
- Try
- Batteries included
- Vim/Neovim plugin, key bindings and fuzzy auto-completion
Installation
fzf project consists of the following:
fzf
executablefzf-tmux
script for launching fzf in a tmux pane- Shell extensions
- Key bindings (
CTRL-T
,CTRL-R
, andALT-C
) (bash, zsh, fish) - Fuzzy auto-completion (bash, zsh)
- Key bindings (
- Vim/Neovim plugin
You can download fzf executable alone, but it’s recommended that you install the extra stuff using the attached install script.
Using git (recommended)
Clone this repository and run install script.
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
Using Homebrew
On OS X, you can use Homebrew to install fzf.
brew install fzf
# Install shell extensions
/usr/local/opt/fzf/install
Install as Vim plugin
Once you have cloned the repository, add the following line to your .vimrc.
set rtp+=~/.fzf
Or you can have vim-plug manage fzf (recommended):
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Upgrading fzf
fzf is being actively developed and you might want to upgrade it once in a while. Please follow the instruction below depending on the installation method.
- git:
cd ~/.fzf && git pull && ./install
- brew:
brew update; brew reinstall fzf
- vim-plug:
:PlugUpdate fzf
Usage
fzf will launch curses-based finder, read the list from STDIN, and write the selected item to STDOUT.
find * -type f | fzf > selected
Without STDIN pipe, fzf will use find command to fetch the list of
files excluding hidden ones. (You can override the default command with
FZF_DEFAULT_COMMAND
)
vim $(fzf)
Using the finder
CTRL-J
/CTRL-K
(orCTRL-N
/CTRL-P)
to move cursor up and downEnter
key to select the item,CTRL-C
/CTRL-G
/ESC
to exit- On multi-select mode (
-m
),TAB
andShift-TAB
to mark multiple items - Emacs style key bindings
- Mouse: scroll, click, double-click; shift-click and shift-scroll on multi-select mode
Search syntax
Unless otherwise specified, fzf starts in “extended-search mode” where you can
type in multiple search terms delimited by spaces. e.g. ^music .mp3$ sbtrkt
!rmx
Token | Match type | Description |
---|---|---|
sbtrkt |
fuzzy-match | Items that match sbtrkt |
^music |
prefix-exact-match | Items that start with music |
.mp3$ |
suffix-exact-match | Items that end with .mp3 |
'wild |
exact-match (quoted) | Items that include wild |
!rmx |
inverse-fuzzy-match | Items that do not match rmx |
!'fire |
inverse-exact-match | Items that do not include fire |
If you don’t prefer fuzzy matching and do not wish to “quote” every word,
start fzf with -e
or --exact
option. Note that when --exact
is set,
'
-prefix “unquotes” the term.
A single bar character term acts as an OR operator. For example, the following
query matches entries that start with core
and end with either go
, rb
,
or py
.
^core go$ | rb$ | py$
Environment variables
FZF_DEFAULT_COMMAND
- Default command to use when input is tty
- e.g.
export FZF_DEFAULT_COMMAND='ag -g ""'
FZF_DEFAULT_OPTS
- Default options
- e.g.
export FZF_DEFAULT_OPTS="--reverse --inline-info"
Examples
Many useful examples can be found on the wiki page. Feel free to add your own as well.
fzf-tmux
script
fzf-tmux is a bash script that opens fzf in a tmux pane.
# usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
# (-[udlr]: up/down/left/right)
# select git branches in horizontal split below (15 lines)
git branch | fzf-tmux -d 15
# select multiple words in vertical split on the left (20% of screen width)
cat /usr/share/dict/words | fzf-tmux -l 20% --multi --reverse
It will still work even when you’re not on tmux, silently ignoring -[udlr]
options, so you can invariably use fzf-tmux
in your scripts.
Key bindings for command line
The install script will setup the following key bindings for bash, zsh, and fish.
CTRL-T
- Paste the selected files and directories onto the command line- Set
FZF_CTRL_T_COMMAND
to override the default command - Set
FZF_CTRL_T_OPTS
to pass additional options
- Set
CTRL-R
- Paste the selected command from history onto the command line- Sort is disabled by default to respect chronological ordering
- Press
CTRL-R
again to toggle sort - Set
FZF_CTRL_R_OPTS
to pass additional options
ALT-C
- cd into the selected directory- Set
FZF_ALT_C_COMMAND
to override the default command - Set
FZF_ALT_C_OPTS
to pass additional options
- Set
If you’re on a tmux session, fzf will start in a split pane. You may disable
this tmux integration by setting FZF_TMUX
to 0, or change the height of the
pane with FZF_TMUX_HEIGHT
(e.g. 20
, 50%
).
If you use vi mode on bash, you need to add set -o vi
before source
~/.fzf.bash
in your .bashrc, so that it correctly sets up key bindings for vi
mode.
Fuzzy completion for bash and zsh
Files and directories
Fuzzy completion for files and directories can be triggered if the word before
the cursor ends with the trigger sequence which is by default **
.
COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TAB>
# Files under current directory
# - You can select multiple items with TAB key
vim **<TAB>
# Files under parent directory
vim ../**<TAB>
# Files under parent directory that match `fzf`
vim ../fzf**<TAB>
# Files under your home directory
vim ~/**<TAB>
# Directories under current directory (single-selection)
cd **<TAB>
# Directories under ~/github that match `fzf`
cd ~/github/fzf**<TAB>
Process IDs
Fuzzy completion for PIDs is provided for kill command. In this case there is no trigger sequence, just press tab key after kill command.
# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 <TAB>
Host names
For ssh and telnet commands, fuzzy completion for host names is provided. The names are extracted from /etc/hosts and ~/.ssh/config.
ssh **<TAB>
telnet **<TAB>
Environment variables / Aliases
unset **<TAB>
export **<TAB>
unalias **<TAB>
Settings
# Use ~~ as the trigger sequence instead of the default **
export FZF_COMPLETION_TRIGGER='~~'
# Options to fzf command
export FZF_COMPLETION_OPTS='+c -x'
# Use ag instead of the default find command for listing candidates.
# - The first argument to the function is the base path to start traversal
# - Note that ag only lists files not directories
# - See the source code (completion.{bash,zsh}) for the details.
_fzf_compgen_path() {
ag -g "" "$1"
}
Supported commands
On bash, fuzzy completion is enabled only for a predefined set of commands
(complete | grep _fzf
to see the list). But you can enable it for other
commands as well like follows.
# There are also _fzf_path_completion and _fzf_dir_completion
complete -F _fzf_file_completion -o default -o bashdefault doge
Usage as Vim plugin
This repository only enables basic integration with Vim. If you’re looking for more, check out fzf.vim project.
(Note: To use fzf in GVim, an external terminal emulator is required.)
:FZF[!]
If you have set up fzf for Vim, :FZF
command will be added.
" Look for files under current directory
:FZF
" Look for files under your home directory
:FZF ~
" With options
:FZF --no-sort -m /tmp
" Bang version starts in fullscreen instead of using tmux pane or Neovim split
:FZF!
Similarly to ctrlp.vim, use enter key,
CTRL-T
, CTRL-X
or CTRL-V
to open selected files in the current window,
in new tabs, in horizontal splits, or in vertical splits respectively.
Note that the environment variables FZF_DEFAULT_COMMAND
and
FZF_DEFAULT_OPTS
also apply here. Refer to the wiki page for
customization.
fzf#run
For more advanced uses, you can use fzf#run([options])
function with the
following options.
Option name | Type | Description |
---|---|---|
source |
string | External command to generate input to fzf (e.g. find . ) |
source |
list | Vim list as input to fzf |
sink |
string | Vim command to handle the selected item (e.g. e , tabe ) |
sink |
funcref | Reference to function to process each selected item |
sink* |
funcref | Similar to sink , but takes the list of output lines at once |
options |
string | Options to fzf |
dir |
string | Working directory |
up /down /left /right |
number/string | Use tmux pane with the given size (e.g. 20 , 50% ) |
window (Neovim only) |
string | Command to open fzf window (e.g. vertical aboveleft 30new ) |
launcher |
string | External terminal emulator to start fzf with (GVim only) |
launcher |
funcref | Function for generating launcher string (GVim only) |
Examples can be found on the wiki page.
fzf#wrap
fzf#wrap([name string,] [opts dict,] [fullscreen boolean])
is a helper
function that decorates the options dictionary so that it understands
g:fzf_layout
, g:fzf_action
, and g:fzf_history_dir
like :FZF
.
command! -bang MyStuff
\ call fzf#run(fzf#wrap('my-stuff', {'dir': '~/my-stuff'}, <bang>0))
Tips
Rendering issues
If you have any rendering issues, check the following:
- Make sure
$TERM
is correctly set. fzf will use 256-color only if it contains256
(e.g.xterm-256color
) - If you’re on screen or tmux,
$TERM
should be eitherscreen
orscreen-256color
- Some terminal emulators (e.g. mintty) have problem displaying default
background color and make some text unable to read. In that case, try
--black
option. And if it solves your problem, I recommend including it inFZF_DEFAULT_OPTS
for further convenience. - If you still have problem, try
--no-256
option or even--no-color
.
Respecting .gitignore
, .hgignore
, and svn:ignore
ag or pt will do the filtering:
# Feed the output of ag into fzf
ag -g "" | fzf
# Setting ag as the default source for fzf
export FZF_DEFAULT_COMMAND='ag -g ""'
# Now fzf (w/o pipe) will use ag instead of find
fzf
# To apply the command to CTRL-T as well
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
git ls-tree
for fast traversal
If you’re running fzf in a large git repository, git ls-tree
can boost up the
speed of the traversal.
export FZF_DEFAULT_COMMAND='
(git ls-tree -r --name-only HEAD ||
find . -path "*/\.*" -prune -o -type f -print -o -type l -print |
sed s/^..//) 2> /dev/null'
Fish shell
It’s a known bug of fish
that it doesn’t allow reading from STDIN in command substitution, which means
simple vim (fzf)
won’t work as expected. The workaround is to store the result
of fzf to a temporary file.
fzf > $TMPDIR/fzf.result; and vim (cat $TMPDIR/fzf.result)
参考文件
- junegunn - http://junegunn.kr/
傲娇的使用Disqus