fzf/README.md

491 lines
14 KiB
Markdown
Raw Normal View History

2013-10-23 23:25:19 -04:00
fzf - Fuzzy finder for your shell
=================================
2013-10-22 21:26:55 -04:00
fzf is a general-purpose fuzzy finder for your shell.
2013-10-29 09:14:11 -04:00
![](https://raw.github.com/junegunn/i/master/fzf.gif)
2013-10-28 02:50:46 -04:00
2013-10-23 23:25:19 -04:00
It was heavily inspired by [ctrlp.vim](https://github.com/kien/ctrlp.vim) and
the likes.
2013-10-22 21:26:55 -04:00
Installation
------------
2015-02-16 23:15:16 -05:00
fzf project consists of the followings:
- `fzf` executable
- `fzf-tmux` script for launching fzf in a tmux pane
2015-02-16 23:15:16 -05:00
- Shell extensions
- Key bindings (`CTRL-T`, `CTRL-R`, and `ALT-C`) (bash, zsh, fish)
2015-03-06 04:57:36 -05:00
- Fuzzy auto-completion (bash only)
2015-02-16 23:15:16 -05:00
You can [download fzf executable][bin] alone, but it's recommended that you
install the extra stuff using the attached install script.
[bin]: https://github.com/junegunn/fzf-bin/releases
2015-03-06 04:57:36 -05:00
#### Using git (recommended)
2015-02-16 23:15:16 -05:00
Clone this repository and run
2013-10-22 21:26:55 -04:00
[install](https://github.com/junegunn/fzf/blob/master/install) script.
```sh
git clone https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
2013-10-22 21:26:55 -04:00
```
2015-03-06 04:57:36 -05:00
#### Using curl
2015-02-16 23:15:16 -05:00
2014-04-25 06:16:33 -04:00
In case you don't have git installed:
```sh
mkdir -p ~/.fzf
2014-04-25 06:45:07 -04:00
curl -L https://github.com/junegunn/fzf/archive/master.tar.gz |
2014-04-25 06:16:33 -04:00
tar xz --strip-components 1 -C ~/.fzf
~/.fzf/install
```
2015-03-06 04:57:36 -05:00
#### Using Homebrew
2015-02-16 23:15:16 -05:00
On OS X, you can use [Homebrew](http://brew.sh/) to install fzf.
2015-02-16 23:15:16 -05:00
```sh
brew install fzf
2013-10-22 21:26:55 -04:00
2015-02-17 10:22:17 -05:00
# Install shell extensions - this should be done whenever fzf is updated
$(brew info fzf | grep /install)
2015-02-16 23:15:16 -05:00
```
2014-03-30 21:15:38 -04:00
2015-03-06 04:57:36 -05:00
#### Install as Vim plugin
2013-10-22 21:26:55 -04:00
2014-03-03 21:25:50 -05:00
Once you have cloned the repository, add the following line to your .vimrc.
2013-10-22 21:26:55 -04:00
2014-03-03 21:25:50 -05:00
```vim
set rtp+=~/.fzf
```
2013-10-22 21:26:55 -04:00
2015-03-06 04:57:36 -05:00
Or you can have [vim-plug](https://github.com/junegunn/vim-plug) manage fzf
(recommended):
2014-09-02 00:06:05 -04:00
```vim
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': 'yes \| ./install' }
```
2013-10-22 21:26:55 -04:00
Usage
-----
fzf will launch curses-based finder, read the list from STDIN, and write the
selected item to STDOUT.
```sh
find * -type f | fzf > selected
```
Without STDIN pipe, fzf will use find command to fetch the list of
2013-11-01 23:56:43 -04:00
files excluding hidden ones. (You can override the default command with
`FZF_DEFAULT_COMMAND`)
2013-10-22 21:26:55 -04:00
```sh
vim $(fzf)
2013-10-22 21:26:55 -04:00
```
2015-03-06 04:57:36 -05:00
#### Using the finder
2013-11-09 13:56:18 -05:00
2015-03-06 04:57:36 -05:00
- `CTRL-J` / `CTRL-K` (or `CTRL-N` / `CTRL-P)` to move cursor up and down
- `Enter` key to select the item, `CTRL-C` / `CTRL-G` / `ESC` to exit
- On multi-select mode (`-m`), `TAB` and `Shift-TAB` to mark multiple items
- Emacs style key bindings
- Mouse: scroll, click, double-click; shift-click and shift-scroll on
multi-select mode
2015-03-06 04:57:36 -05:00
#### Extended-search mode
2013-11-15 12:21:39 -05:00
With `-x` or `--extended` option, fzf will start in "extended-search mode".
2013-11-15 12:21:39 -05:00
In this mode, you can specify multiple patterns delimited by spaces,
such as: `^music .mp3$ sbtrkt !rmx`
2013-11-15 11:55:33 -05:00
| Token | Description | Match type |
| -------- | -------------------------------- | -------------------- |
| `^music` | Items that start with `music` | prefix-exact-match |
| `.mp3$` | Items that end with `.mp3` | suffix-exact-match |
| `sbtrkt` | Items that match `sbtrkt` | fuzzy-match |
| `!rmx` | Items that do not match `rmx` | inverse-fuzzy-match |
| `'wild` | Items that include `wild` | exact-match (quoted) |
| `!'fire` | Items that do not include `fire` | inverse-exact-match |
If you don't need fuzzy matching and do not wish to "quote" every word, start
fzf with `-e` or `--extended-exact` option.
2015-03-06 04:57:36 -05:00
Examples
--------
2013-10-22 21:26:55 -04:00
2015-03-06 04:57:36 -05:00
Many useful examples can be found on [the wiki
page](https://github.com/junegunn/fzf/wiki/examples). Feel free to add your
own as well.
2014-05-02 10:38:36 -04:00
2013-12-21 10:22:23 -05:00
Key bindings for command line
-----------------------------
The install script will setup the following key bindings for bash, zsh, and
fish.
- `CTRL-T` - Paste the selected file path(s) into the command line
- `CTRL-R` - Paste the selected command from history into the command line
- `ALT-C` - cd into the selected directory
2013-11-08 11:16:39 -05:00
If you're on a tmux session, `CTRL-T` will launch fzf in a new split-window. You
may disable this tmux integration by setting `FZF_TMUX` to 0, or change the
2014-03-28 04:15:32 -04:00
height of the window 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.
2014-05-06 02:39:44 -04:00
If you want to customize the key bindings, consider editing the
installer-generated source code: `~/.fzf.bash`, `~/.fzf.zsh`, and
`~/.config/fish/functions/fzf_key_bindings.fish`.
2013-11-08 11:16:39 -05:00
2015-03-06 04:57:36 -05:00
`fzf-tmux` script
-----------------
[fzf-tmux](bin/fzf-tmux) is a bash script that opens fzf in a tmux pane.
2015-03-06 04:57:36 -05:00
```sh
# usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
# (-[udlr]: up/down/left/right)
2015-03-06 04:57:36 -05:00
# select git branches in horizontal split below (15 lines)
git branch | fzf-tmux -d 15
2015-03-06 04:57:36 -05:00
# select multiple words in vertical split on the left (20% of screen width)
cat /usr/share/dict/words | fzf-tmux -l 20% --multi --reverse
2015-03-06 04:57:36 -05:00
```
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.
2015-03-06 04:57:36 -05:00
Fuzzy completion for bash
-------------------------
#### Files and directories
2013-11-29 03:49:48 -05:00
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>`
```sh
2013-11-19 11:42:57 -05:00
# Files under current directory
# - You can select multiple items with TAB key
vim **<TAB>
2013-11-19 11:42:57 -05:00
# Files under parent directory
vim ../**<TAB>
# Files under parent directory that match `fzf`
vim ../fzf**<TAB>
2013-11-19 11:42:57 -05:00
# Files under your home directory
vim ~/**<TAB>
2013-11-19 11:42:57 -05:00
# Directories under current directory (single-selection)
cd **<TAB>
2013-11-19 11:42:57 -05:00
# Directories under ~/github that match `fzf`
cd ~/github/fzf**<TAB>
```
#### Process IDs
Fuzzy completion for PIDs is provided for kill command. In this case
2013-11-29 03:49:48 -05:00
there is no trigger sequence, just press tab key after kill command.
```sh
# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 <TAB>
```
#### Host names
2013-11-29 04:09:51 -05:00
For ssh and telnet commands, fuzzy completion for host names is provided. The
names are extracted from /etc/hosts and ~/.ssh/config.
```sh
ssh **<TAB>
telnet **<TAB>
```
#### Environment variables / Aliases
```sh
unset **<TAB>
export **<TAB>
unalias **<TAB>
```
2013-11-19 11:42:57 -05:00
#### Settings
```sh
2013-11-19 11:42:57 -05:00
# Use ~~ as the trigger sequence instead of the default **
export FZF_COMPLETION_TRIGGER='~~'
2013-11-19 11:42:57 -05:00
# Options to fzf command
export FZF_COMPLETION_OPTS='+c -x'
```
2014-01-07 03:07:02 -05:00
Usage as Vim plugin
-------------------
(Note: To use fzf in GVim, an external terminal emulator is required.)
2014-03-25 06:55:52 -04:00
2015-03-06 04:57:36 -05:00
#### `:FZF[!]`
2014-03-27 11:58:07 -04:00
If you have set up fzf for Vim, `:FZF` command will be added.
2014-01-07 03:07:02 -05:00
```vim
" Look for files under current directory
:FZF
" Look for files under your home directory
:FZF ~
" With options
:FZF --no-sort -m /tmp
```
2014-03-27 11:58:07 -04:00
Note that the environment variables `FZF_DEFAULT_COMMAND` and `FZF_DEFAULT_OPTS`
2014-03-25 06:55:52 -04:00
also apply here.
If you're on a tmux session, `:FZF` will launch fzf in a new split-window whose
2014-03-28 04:15:32 -04:00
height can be adjusted with `g:fzf_tmux_height` (default: '40%'). However, the
bang version (`:FZF!`) will always start in fullscreen.
2014-03-27 11:58:07 -04:00
In GVim, you need an external terminal emulator to start fzf with. `xterm`
command is used by default, but you can customize it with `g:fzf_launcher`.
2014-06-14 14:18:29 -04:00
```vim
" This is the default. %s is replaced with fzf command
let g:fzf_launcher = 'xterm -e bash -ic %s'
" Use urxvt instead
let g:fzf_launcher = 'urxvt -geometry 120x30 -e sh -c %s'
2014-06-14 14:18:29 -04:00
```
If you're running MacVim on OSX, I recommend you to use iTerm2 as the launcher.
Refer to the [this wiki
page](https://github.com/junegunn/fzf/wiki/fzf-with-MacVim-and-iTerm2) to see
how to set up.
2015-03-06 04:57:36 -05:00
#### `fzf#run([options])`
2014-03-25 06:55:52 -04:00
For more advanced uses, you can call `fzf#run()` function which returns the list
of the selected items.
`fzf#run()` may take an options-dictionary:
2014-06-14 14:18:29 -04:00
| 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 |
| `options` | string | Options to fzf |
| `dir` | string | Working directory |
| `tmux_width` | number/string | Use tmux vertical split with the given height (e.g. `20`, `50%`) |
| `tmux_height` | number/string | Use tmux horizontal split with the given height (e.g. `20`, `50%`) |
| `launcher` | string | External terminal emulator to start fzf with (Only used in GVim) |
2014-03-25 06:55:52 -04:00
2015-03-06 04:57:36 -05:00
##### Examples
2014-03-25 06:55:52 -04:00
If `sink` option is not given, `fzf#run` will simply return the list.
2014-01-07 03:07:02 -05:00
```vim
2014-03-25 06:55:52 -04:00
let items = fzf#run({ 'options': '-m +c', 'dir': '~', 'source': 'ls' })
2014-01-07 03:07:02 -05:00
```
2014-03-25 06:55:52 -04:00
But if `sink` is given as a string, the command will be executed for each
selected item.
2014-01-07 03:07:02 -05:00
```vim
2014-03-25 06:55:52 -04:00
" Each selected item will be opened in a new tab
let items = fzf#run({ 'sink': 'tabe', 'options': '-m +c', 'dir': '~', 'source': 'ls' })
2014-01-07 03:07:02 -05:00
```
2014-03-25 06:55:52 -04:00
We can also use a Vim list as the source as follows:
2014-01-07 03:07:02 -05:00
```vim
2014-03-25 06:55:52 -04:00
" Choose a color scheme with fzf
2014-03-27 11:58:07 -04:00
nnoremap <silent> <Leader>C :call fzf#run({
2014-03-25 06:55:52 -04:00
\ 'source':
\ map(split(globpath(&rtp, "colors/*.vim"), "\n"),
\ "substitute(fnamemodify(v:val, ':t'), '\\..\\{-}$', '', '')"),
\ 'sink': 'colo',
\ 'options': '+m',
\ 'tmux_width': 20,
\ 'launcher': 'xterm -geometry 20x30 -e bash -ic %s'
2014-03-27 11:58:07 -04:00
\ })<CR>
2014-01-07 03:07:02 -05:00
```
2014-03-25 06:55:52 -04:00
`sink` option can be a function reference. The following example creates a
handy mapping that selects an open buffer.
```vim
" List of buffers
function! BufList()
2014-03-25 06:55:52 -04:00
redir => ls
silent ls
redir END
return split(ls, '\n')
endfunction
function! BufOpen(e)
2014-03-25 06:55:52 -04:00
execute 'buffer '. matchstr(a:e, '^[ 0-9]*')
endfunction
2014-03-27 11:58:07 -04:00
nnoremap <silent> <Leader><Enter> :call fzf#run({
\ 'source': reverse(BufList()),
\ 'sink': function('BufOpen'),
2014-04-12 07:02:04 -04:00
\ 'options': '+m',
\ 'tmux_height': '40%'
2014-03-25 06:55:52 -04:00
\ })<CR>
```
2014-01-07 03:07:02 -05:00
2015-03-06 04:57:36 -05:00
More examples can be found on [the wiki
page](https://github.com/junegunn/fzf/wiki/Examples-(vim)).
#### Articles
2014-04-25 06:16:33 -04:00
- [fzf+vim+tmux](http://junegunn.kr/2014/04/fzf+vim+tmux)
2013-11-10 05:51:32 -05:00
Tips
----
2015-03-06 04:57:36 -05:00
#### Rendering issues
2014-03-08 20:43:59 -05:00
If you have any rendering issues, check the followings:
1. Make sure `$TERM` is correctly set. fzf will use 256-color only if it
contains `256` (e.g. `xterm-256color`)
2014-03-08 21:52:35 -05:00
2. If you're on screen or tmux, `$TERM` should be either `screen` or
2014-03-08 20:43:59 -05:00
`screen-256color`
3. 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 in
`FZF_DEFAULT_OPTS` for further convenience.
4. If you still have problem, try `--no-256` option or even `--no-color`.
2013-12-21 10:22:23 -05:00
2015-03-06 04:57:36 -05:00
#### Respecting `.gitignore`, `.hgignore`, and `svn:ignore`
2014-04-06 02:25:58 -04:00
[ag](https://github.com/ggreer/the_silver_searcher) or
[pt](https://github.com/monochromegane/the_platinum_searcher) will do the
filtering:
```sh
# Feed the output of ag into fzf
ag -l -g "" | fzf
# Setting ag as the default source for fzf
export FZF_DEFAULT_COMMAND='ag -l -g ""'
# Now fzf (w/o pipe) will use ag instead of find
fzf
```
2015-03-06 04:57:36 -05:00
#### `git ls-tree` for fast traversal
2014-05-01 23:52:06 -04:00
If you're running fzf in a large git repository, `git ls-tree` can boost up the
speed of the traversal.
```sh
# Copy the original fzf function to __fzf
declare -f __fzf > /dev/null ||
2014-09-14 00:53:53 -04:00
eval "$(echo "__fzf() {"; declare -f fzf | \grep -v '^{' | tail -n +2)"
2014-05-01 23:52:06 -04:00
# Use git ls-tree when possible
fzf() {
if [ -n "$(git rev-parse HEAD 2> /dev/null)" ]; then
FZF_DEFAULT_COMMAND="git ls-tree -r --name-only HEAD" __fzf "$@"
else
__fzf "$@"
fi
}
```
#### Using fzf with tmux panes
2014-05-17 22:01:30 -04:00
2015-03-06 04:57:36 -05:00
The supplied [fzf-tmux](bin/fzf-tmux) script should suffice in most of the
cases, but if you want to be able to update command line like the default
`CTRL-T` key binding, you'll have to use `send-keys` command of tmux. The
following example will show you how it can be done.
2014-05-17 22:01:30 -04:00
```sh
# This is a helper function that splits the current pane to start the given
# command ($1) and sends its output back to the original pane with any number of
# optional keys (shift; $*).
fzf_tmux_helper() {
[ -n "$TMUX_PANE" ] || return
local cmd=$1
shift
tmux split-window -p 40 \
"bash -c \"\$(tmux send-keys -t $TMUX_PANE \"\$(source ~/.fzf.bash; $cmd)\" $*)\""
}
# This is the function we are going to run in the split pane.
# - "find" to list the directories
# - "sed" will escape spaces in the paths.
# - "paste" will join the selected paths into a single line
fzf_tmux_dir() {
fzf_tmux_helper \
'find * -path "*/\.*" -prune -o -type d -print 2> /dev/null |
fzf --multi |
sed "s/ /\\\\ /g" |
paste -sd" " -' Space
}
# Bind CTRL-X-CTRL-D to fzf_tmux_dir
bind '"\C-x\C-d": "$(fzf_tmux_dir)\e\C-e"'
```
2015-03-06 04:57:36 -05:00
#### Fish shell
It's [a known bug of fish](https://github.com/fish-shell/fish-shell/issues/1362)
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.
```sh
function vimf
if fzf > $TMPDIR/fzf.result
vim (cat $TMPDIR/fzf.result)
end
end
function fe
set tmp $TMPDIR/fzf.result
fzf --query="$argv[1]" --select-1 --exit-0 > $tmp
if [ (cat $tmp | wc -l) -gt 0 ]
vim (cat $tmp)
end
end
```
2015-03-06 04:57:36 -05:00
#### Handling UTF-8 NFD paths on OSX
Use iconv to convert NFD paths to NFC:
```sh
find . | iconv -f utf-8-mac -t utf8//ignore | fzf
```
2014-04-06 02:25:58 -04:00
2013-10-22 21:26:55 -04:00
License
-------
[MIT](LICENSE)
2013-10-22 21:26:55 -04:00
Author
------
Junegunn Choi