-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Examples
Feel free to edit this page if you have a nice example of using fzf.
# fe [FUZZY PATTERN] - Open the selected file with the default editor
# - Bypass fuzzy finder if there's only one match (--select-1)
# - Exit if there's no match (--exit-0)
fe() {
local file
file=$(fzf --query="$1" --select-1 --exit-0)
[ -n "$file" ] && ${EDITOR:-vim} "$file"
}
# Equivalent to above, but opens it with `open` command
fo() {
local file
file=$(fzf --query="$1" --select-1 --exit-0)
[ -n "$file" ] && open "$file"
}# fd - cd to selected directory
fd() {
local dir
dir=$(find ${1:-*} -path '*/\.*' -prune \
-o -type d -print 2> /dev/null | fzf +m) &&
cd "$dir"
}# fda - including hidden directories
fda() {
local dir
dir=$(find ${1:-.} -type d 2> /dev/null | fzf +m) && cd "$dir"
}Suggested by @harelba and @dimonomid:
# cdf - cd into the directory of the selected file
cdf() {
local file
local dir
file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir"
}# fh - repeat history
fh() {
eval $(([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed 's/ *[0-9]* *//')
}# fh - repeat history
fh() {
print -z $(([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed 's/ *[0-9]* *//')
}Replacing eval with print -z will push the arguments onto the editing buffer stack, allowing you to edit the command before running it. It also means the command you run will appear in your history rather than just fh. Unfortunately this only works for zsh.
# utility function used to write the command in the shell
writecmd() {
perl -e '$TIOCSTI = 0x5412; $l = <STDIN>; $lc = $ARGV[0] eq "-run" ? "\n" : ""; $l =~ s/\s*$/$lc/; map { ioctl STDOUT, $TIOCSTI, $_; } split "", $l;' -- $1
}
# fh - repeat history
fh() {
([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed -re 's/^\s*[0-9]+\s*//' | writecmd -run
}
# fhe - repeat history edit
fhe() {
([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s | sed -re 's/^\s*[0-9]+\s*//' | writecmd
}This have been tested in bash.
# fkill - kill process
fkill() {
pid=$(ps -ef | sed 1d | fzf -m | awk '{print $2}')
if [ "x$pid" != "x" ]
then
kill -${1:-9} $pid
fi
}# fbr - checkout git branch
fbr() {
local branches branch
branches=$(git branch) &&
branch=$(echo "$branches" | fzf +s +m) &&
git checkout $(echo "$branch" | sed "s/.* //")
}# fco - checkout git commit
fco() {
local commits commit
commits=$(git log --pretty=oneline --abbrev-commit --reverse) &&
commit=$(echo "$commits" | fzf +s +m -e) &&
git checkout $(echo "$commit" | sed "s/ .*//")
}# ftags - search ctags
ftags() {
local line
[ -e tags ] &&
line=$(
awk 'BEGIN { FS="\t" } !/^!/ {print toupper($4)"\t"$1"\t"$2"\t"$3}' tags |
cut -c1-80 | fzf --nth=1,2
) && $EDITOR $(cut -f3 <<< "$line") -c "set nocst" \
-c "silent tag $(cut -f2 <<< "$line")"
}# fs [FUZZY PATTERN] - Select selected tmux session
# - Bypass fuzzy finder if there's only one match (--select-1)
# - Exit if there's no match (--exit-0)
fs() {
local session
session=$(tmux list-sessions -F "#{session_name}" | \
fzf --query="$1" --select-1 --exit-0) &&
tmux switch-client -t "$session"
}Integration with z, like normal z when used with arguments but displays an fzf prompt when used without.
unalias z
z() {
if [[ -z "$*" ]]; then
cd "$(_z -l 2>&1 | sed -n 's/^[ 0-9.,]*//p' | fzf)"
else
_z "$@"
fi
}Here is another version that also supports relaunching z with the arguments for the previous command as the default input by using zz
unalias z
z() {
if [[ -z "$*" ]]; then
cd "$(_z -l 2>&1 | sed -n 's/^[ 0-9.,]*//p' | fzf)"
else
_last_z_args="$@"
_z "$@"
fi
}
zz() {
cd "$(_z -l 2>&1 | sed -n 's/^[ 0-9.,]*//p' | fzf -q $_last_z_args)"
}Since z is not very optimal located on a qwerty keyboard I have these aliased as j and jj
alias j=z
alias jj=zz# fsfzf - browse file system
# https://github.com/D630/gist-bin-pub/tree/master/fsfzf
# Requiered: `find`, `sort`
# Optional: `file`, `w3m`, `elinks`
# In an interactive shell without alias or configured sourcing in
# your bash configs:
$ source fsfzf.sh <DIR>
$ source fsfzf.sh ~/ # tilde expansions
$ source fsfzf.sh .
$ source fsfzf.sh bin/ # programmable completion for pathnames
# As script:
$ fsfzf.sh # no arguments
$ fsfzf.sh <DIR>
$ fsfzf.sh ~/ # tilde expansions
$ fsfzf.sh .
$ fsfzf.sh bin/ # programmable completion for pathnamesadd this to your .vimrc
command! -nargs=1 AgFZF call fzf#run({
\'source': Arghandler(<f-args>),
\'sink' : function('AgHandler'),
\'options' : '-m'
\})
function! AgHandler(l)
let keys = split(a:l,':')
execute 'tabe +' . keys[-2] . ' ' . escape(keys[-1], ' ')
endfunction
function! Arghandler(l)
return "ag -i " . a:l . " | sed 's@\\(.[^:]*\\):\\(.[^:]*\\):\\(.*\\)@\\3:\\2:\\1@' "
endfunctionThen use :AgFZF followed by an ag-recogizable regex to pipe ag results into fzf for narrowing. Selected results are opened in new tabs so that you can open multiple positions within the same file (perhaps there's a better way of doing this).
command! FZFLines call fzf#run({
\ 'source': BuffersLines(),
\ 'sink': function('LineHandler'),
\ 'options': '--extended --nth=3..,',
\ 'tmux_height': '60%'
\})
function! LineHandler(l)
let keys = split(a:l, ':\t')
exec 'buf ' . keys[0]
exec keys[1]
normal! ^zz
endfunction
function! BuffersLines()
let res = []
for b in filter(range(1, bufnr('$')), 'buflisted(v:val)')
call extend(res, map(getbufline(b,0,"$"), 'b . ":\t" . (v:key + 1) . ":\t" . v:val '))
endfor
return res
endfunctioncommand! FZFMru call fzf#run({
\'source': v:oldfiles,
\'sink' : 'e ',
\'options' : '-m',
\})function! TagCommand()
return substitute('awk _!/^!/ { print \$1 }_ ', '_', "'", 'g')
\ . join(tagfiles(), ' ')
endfunction
command! FZFTag call fzf#run({
\ 'source' : TagCommand(),
\ 'sink' : 'tag',
\ })cnoremap <silent> <c-l> <c-\>eGetCompletions()<cr>
"add an extra <cr> at the end of this line to automatically accept the fzf-selected completions.
function! Lister()
call extend(g:FZF_Cmd_Completion_Pre_List,split(getcmdline(),'\(\\\zs\)\@<!\& '))
endfunction
function! CmdLineDirComplete(prefix, options, rawdir)
let l:dirprefix = matchstr(a:rawdir,"^.*/")
if isdirectory(expand(l:dirprefix))
return join(a:prefix + map(fzf#run({
\'options': a:options . ' --select-1 --query=' .
\ a:rawdir[matchend(a:rawdir,"^.*/"):len(a:rawdir)],
\'dir': expand(l:dirprefix)
\}),
\'"' . escape(l:dirprefix, " ") . '" . escape(v:val, " ")'))
else
return join(a:prefix + map(fzf#run({
\'options': a:options . ' --query='. a:rawdir }),
\'escape(v:val, " ")'))
"dropped --select-1 to speed things up on a long query
endfunction
function! GetCompletions()
let g:FZF_Cmd_Completion_Pre_List = []
let l:cmdline_list = split(getcmdline(), '\(\\\zs\)\@<!\& ', 1)
let l:Prefix = l:cmdline_list[0:-2]
execute "silent normal! :" . getcmdline() . "\<c-a>\<c-\>eLister()\<cr>\<c-c>"
let l:FZF_Cmd_Completion_List = g:FZF_Cmd_Completion_Pre_List[len(l:Prefix):-1]
unlet g:FZF_Cmd_Completion_Pre_List
if len(l:Prefix) > 0 && l:Prefix[0] =~
\ '^ed\=i\=t\=$\|^spl\=i\=t\=$\|^tabed\=i\=t\=$\|^arged\=i\=t\=$\|^vsp\=l\=i\=t\=$'
"single-argument file commands
return CmdLineDirComplete(l:Prefix, "",l:cmdline_list[-1])
elseif len(l:Prefix) > 0 && l:Prefix[0] =~
\ '^arg\=s\=$\|^ne\=x\=t\=$\|^sne\=x\=t\=$\|^argad\=d\=$'
"multi-argument file commands
return CmdLineDirComplete(l:Prefix, '--multi', l:cmdline_list[-1])
else
return join(l:Prefix + fzf#run({
\'source':l:FZF_Cmd_Completion_List,
\'options': '--select-1 --query='.shellescape(l:cmdline_list[-1])
\}))
endif
endfunctionhit <c-l> while in the ex commandline (i.e. after pressing :) to have fzf filter a list of vim's commandline auto-completions. Try :colo␣<c-l> (be sure to include the space) or :b␣<c-l>. There are special cases for handling file-searches, so that you can go deeper into the path than just one directory at a time, and so that you can add multiple files to the arglist at once. More special cases could be added. Some limitations: the auto-complete for :help and :tag are limited to 300 entries, so you may need to narrow it a bit.