模糊搜索神器FZF番外篇

模糊搜索神器FZF番外篇

Fuzzy finder

什麼是模糊搜索?
廣義的模糊搜索是指容許被搜索信息和搜索提問之間存在必定的差別,這種差別就是「模糊」在搜索中的含義。例如,查找名字Smith時,就會找出與之類似的Smithe, Smythe, Smyth, Smitt等。
但咱們這裏模糊搜索特指搜索關鍵詞離散且亂序。
看以下的搜索,個人關鍵詞是「a t dir go 15 6」, 搜索到的結果是「app/go/test/fixedbugs/issue15609.dir/call_amd64.s」
vmplayer_2018-08-20_18-53-11
能夠看到結果並非按照關鍵詞順序有序排列的php

爲何要用Fuzzy finder

  • 讓工具像有靈魂同樣
  • 節省你的寶貴時間
  • 輸入更少,實際作的更多
  • 自動處理

工具

最出名的fizzy finder固然是FZF, 這位韓國大神Junegunn Choi寫的幾個小工具都很神,證實了一個道理:牛人出品質量有保障。html

爲何選擇FZF

  • FZF很是酷,它是一個組合性的命令行工具
  • 是用Go寫的,很是快
  • 異步運行,可以處理很是大數量級的數據而不對調用工具產生影響
  • 能夠很是多的方面幫助你,而不單單是用來查找文件
  • 移植容易(無信賴), 靈活的窗口配置
  • vim集成

FZF定位

FZF只是一個模糊搜索的命令行工具,它須要結合其餘工具一塊兒來用,它的輸入要從其餘工具獲得,它的輸出通常也是送給其餘工具。node

有哪些工具能夠方便的和FZF一塊兒使用

目前比較多的是如下幾個工具git

  • Find (目錄搜索)
  • Grep (文本搜索)
  • Ag (文本搜索)
  • fd (目錄搜索)
  • ripgrep (文本搜索)

後兩個是最新出的兩個搜索方面的新秀,應該是目前速度最快的。shell

如何和ripgrep一塊兒使用

能夠設置使用rg來獲得文件列表json

export FZF_DEFAULT_COMMAND='rg --files --no-ignore --hidden --follow --glob "!{.git,node_modules}/*" 2> /dev/null'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND="rg --sort-files --files --null 2> /dev/null | xargs -0 dirname | uniq"

在.vimrc裏能夠寫上vim

let g:rg_command = '
  \ rg --column --line-number --no-heading --fixed-strings --ignore-case --no-ignore --hidden --follow --color "always"
  \ -g "*.{js,json,php,md,styl,jade,html,config,py,cpp,c,go,hs,rb,conf}"
  \ -g "!{.git,node_modules,vendor}/*" '

command! -bang -nargs=* F call fzf#vim#grep(g:rg_command .shellescape(<q-args>), 1, <bang>0)

這樣你在vim裏輸入:F <key word>就能夠進行相關rvapp

如何和fd一塊兒使用

也能夠設置用fd來獲得文件列表,由於fd和rg的walkthrough代碼是共享的,因此速度基本同樣異步

export FZF_DEFAULT_COMMAND='fd --type f --color=never'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND="fd --type d --color=never"

注意若是用time來比較rg和fd的速度時,每每會得出rg比fd快的結論,其實這是由於fd會彩色輸出結果。
若是用fd --type f --color=neverrg --files來比較的話,結果基本是同樣的工具

和各類shell配合

好比下面進入所選文件所在文件夾

# 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() {
  eval $( ([ -n "$ZSH_NAME" ] && fc -l 1 || history) | fzf +s --tac | sed 's/ *[0-9]* *//')
}

好比checkout git分支

# fbr - checkout git branch (including remote branches), sorted by most recent commit, limit 30 last branches
fbr() {
  local branches branch
  branches=$(git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format="%(refname:short)") &&
  branch=$(echo "$branches" |
           fzf-tmux -d $(( 2 + $(wc -l <<< "$branches") )) +m) &&
  git checkout $(echo "$branch" | sed "s/.* //" | sed "s#remotes/[^/]*/##")
}

總結

FZF實際上是膠水工具,它須要讀入其餘工具的輸出作爲輸入,而後或者調用其餘工具讀取它的輸出,或者把本身的輸出送給其餘工具做爲輸入。
理解了這一點就可以很好的結合fzf和其餘工具。
有任何有趣的點子,歡迎和本人分享

相關文章
相關標籤/搜索