模糊搜索神器fzf

前言

fzf是目前最快的fuzzy finder。使用golang編寫。結合其餘工具(好比ag和fasd)能夠完成很是多的工做。
讓你經過輸入模糊的關鍵詞就能夠定位文件或文件夾。當你的思惟也習慣了模糊匹配後,在工做中能夠大幅提升你的工做效率。
模糊搜索的概念以下,你記得文件名含有con, te, go, 那麼你只須要把全部文件送給fzf, 而後在窗口裏輸入con te go就能夠了,無論實現名是test_continus_go仍是go_cont_test都會匹配上。git

安裝

使用gitgithub

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

升級

cd ~/.fzf && git pull && ./install

原生使用

fzf默認會從STDIN讀入數據,而後將結果輸出到STDOUTgolang

find * -type f | fzf > selected

上面命令從find的搜索結果中讀入,輸出到文件selected中shell

fzf裏的快捷鍵

在finder(輸出交換窗口)裏,vim

  • Ctrl-J/Ctrl-K/Ctrl-N/Ctrlk-N能夠用來將光標上下移動
  • Enter鍵用來選中條目, Ctrl-C/Ctrl-G/Esc用來退出
  • 在多選模式下(-m), TAB和Shift-TAB用來多選
  • Mouse: 上下滾動, 選中, 雙擊; Shift-click或shift-scoll用於多選模式

佈局

fzf默認全屏模式,你能夠定製高度segmentfault

vim $(fzf --height 40%)

你能夠經過$FZF_DEFAULT_OPTS來設定默認值ruby

export FZF_DEFAULT_OPTS='--height 40% --reverse --border'

搜索語法

fzf默認會以「extened-search"模式啓動, 這種模式下你能夠輸入多個以空格分隔的搜索關鍵詞, 如^music .mp3$, sbtrkt !fire.svg

Token Match type Description
sbtrkt fuzzy-match 匹配sbtrkt
^music prefix-exact-match 以music開頭
.mp3$ suffix-exact-match 以.mp3結尾
'wild exact-match(quoted) 精確包含wild
!fire inverse-exact-match 不包含fire
!.mp3$ inverse-suffix-exact-match 不以.mp3結尾

若是你不想用fuzzy match, 能夠用fzf -e作精確匹配
|能夠作or匹配, 好比函數

^core go$|rb$|py$

表示以core開頭,以go或rb或py結尾的工具

環境變量

  • FZF_DEFAULT_ COMMAND

    • 設定默認輸入
    • 好比`export FZF_DEFAULT_ COMMAND='ag -g ""'
  • FZF_DEFAULT_OPTS

    • 設定默認選項
    • 好比`export FZF_DEFAULT_OPTS="--reverse --inline-info"

命令行下的快捷鍵

CTRL-T

在命令行下按下ctrl-t會打開fzf窗口,若是你選中某個條目並按下Enter, 選中的條目會被拷貝到命令行上
若是想同時預覽文件內容,可使用--preview選項

export FZF_CTRL_T_OPTS="--preview '(highlight -O ansi -l {} 2> /dev/null || cat {} || tree -C {}) 2> /dev/null | head -200'"

也能夠用--select-1--exit-0
前者是若是隻有一個條目,那麼自動選中並退出fzf
後者是若是條目爲空,自動退出
上面兩個選項對ALT-C也有用

CTRL-R

在命令行下按下ctrl-r, fzf會列出history命令,選中條目並離開fzf的話, 選中條目會被拷到命令行上
在zsh下可使用下面的方法來按下C-XC-R來直接執行

fzf-history-widget-accept() {
  fzf-history-widget
  zle accept-line
}
zle    -N    fzf-history-widget-accept
bindkey '^X^R' fzf-history-widget-accept

ALT-C

在命令行上按下alt-c, 會列出當前文件夾下的目錄,選中條目會自動進入到相應目錄
圖片描述

命令行下的模糊完成

默承認以經過**來觸發文件或目錄的自動完成

COMMAND [DIRECTORY/][FUZZY_PATTERN]**<TBA>

好比

vim **<TAB>
vim ../mult**<TAB>
cd ~/github/fzf**<TBA>

預覽窗口

若是使用--preview選項, fzf會自動用外部程序打開如今條目的文件, {}會被fzf選中行內容代替

fzf --preview 'cat {}'

建議安裝rougify(先安裝ruby, 而後gem intall rouge)
而後在.zshrc裏用函數或別名

fzfp() {
fzf --preview '[[ $(file --mime {}) =~ binary ]] && echo {} is a binary file || (rougify {}  || highlight -O ansi -l {} || coderay {} || cat {}) 2> /dev/null | head -500'
alias tt='fzf --preview '"'"'[[ $(file --mime {}) =~ binary ]] && echo {} is a binary file || (rougify {}  || highlight -O ansi -l {} || coderay {} || cat {}) 2> /dev/null | head -500'"'"

函數是更好的方式, 用alias的話,爲了繞開'的問題,須要用一個雙引號加一個間引號再加一個雙引號才能生成一個單引號
圖片描述
上圖左側是文件列表,右側是rougify生成的預覽窗口,能夠用鼠標上下滾動,遺憾的是用鍵盤無法移動光標到右側窗口進行上下滾動。

fzf示例

interactive cd

安裝

wget https://github.com/changyuheng/zsh-interactive-cd/blob/master/zsh-interactive-cd.plugin.zsh
cp zsh-interactive-cd.plugin.zsh ~/.fzf/shell
echo 'source ~/.fzf/shell/zsh-interactive-cd.plugin.zsh' >> ~/.zshrc

cd後按ctrl-i就會打開fzf finder窗口
inactive_cd

z

# fasd & fzf change directory - jump using `fasd` if given argument, filter output of `fasd` using `fzf` else
z() {
    [ $# -gt 0 ] && fasd_cd -d "$*" && return
    local dir
    dir="$(fasd -Rdl "$1" | fzf -1 -0 --no-sort +m)" && cd "${dir}" || return 1
}

changing directory

# 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"
}
# fdr - cd to selected parent directory
fdr() {
  local declare dirs=()
  get_parent_dirs() {
    if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
    if [[ "${1}" == '/' ]]; then
      for _dir in "${dirs[@]}"; do echo $_dir; done
    else
      get_parent_dirs $(dirname "$1")
    fi
  }
  local DIR=$(get_parent_dirs $(realpath "${1:-$PWD}") | fzf-tmux --tac)
  cd "$DIR"
}
# cf - fuzzy cd from anywhere
# ex: cf word1 word2 ... (even part of a file name)
# zsh autoload function
cf() {
  local file

  file="$(locate -Ai -0 $@ | grep -z -vE '~$' | fzf --read0 -0 -1)"

  if [[ -n $file ]]
  then
    if [[ -d $file ]]
    then
        cd -- $file
    else
        cd -- ${file:h}
    fi
  fi
}

v

# fasd & fzf change directory - open best matched file using `fasd` if given argument, filter output of `fasd` using `fzf` else
v() {
    [ $# -gt 0 ] && fasd -f -e ${EDITOR} "$*" && return
    local file
    file="$(fasd -Rfl "$1" | fzf -1 -0 --no-sort +m)" && vi "${file}" || return 1
}

fzf的vim插件

在.vimrc裏用vunble安裝

set rtp+=/home/harriszh/.fzf/
...
Plugin 'junegunn/fzf.vim'
...

而後FZF等命令就可使用了
建議要安裝ag,並把FZF_DEFAULT_COMMAND改爲ag

更多信息

若是對FZF和vim和結合感興趣能夠看: VIM與模糊搜索神器FZF的集成用法 - 從簡單到高級
若是對FZF和各類工具的配合使用請看: 模糊搜索神器FZF番外篇

後言

fzf是很是強大的膠水工具,利用它和ag, fasd及shell command能夠實現很是絢爛的功能。更多例子見wiki
若是上文有錯誤的地方,歡迎聯繫做者

相關文章
相關標籤/搜索