1. 程式人生 > 其它 >使用模糊搜尋神器 FZF 來提升辦公效率

使用模糊搜尋神器 FZF 來提升辦公效率

技術標籤:┈┈【Ubuntu/CentOS管理】┈┈【開發工具IDE】linuxfzfgitfuzzy開發工具


title: 使用模糊搜尋神器 FZF 來提升辦公效率
date: 2021-02-15 00:32
author: gatieme
tags: linux
categories:
- linux
- debug
thumbnail:
blogexcerpt: FZF 是目前最快的模糊搜尋工具. 使用golang編寫. 結合其他工具(比如 ag 和 fasd)可以完成非常多的工作. 前段時間, 有同事給鄙人推薦了 FZF, 通過簡單的配置, 配合 VIM/GIT 等工具食用, 簡直事半功倍, 效率指數級提升, 因此推薦給大家.


日期作者GitHubCSDNBLOG
2021-02-15成堅-gatiemeAderXCoding/system/tools/fzf使用模糊搜尋神器 FZF 來提升辦公體驗Using FZF to Improve Productivit

1 fzf 介紹


fzf 是一款使用 GO 語言編寫的互動式的命令列工具, 可以用來查詢任何 列表內容、檔案、歷史命令、 本機繫結的host、 程序、 Git 分支、程序 等.

我們可以通過 FZF 結合 git 等工具來提升我們的辦公體驗.

github 倉庫地址

https://github.com/junegunn/fzf

2 fzf 安裝


FZF 目前已經在各大發行版的源中集成了, 比如 ubuntu 19.10 之後, 可以直接使用 apt 進行安裝

Package ManagerLinux DistributionCommand
APKAlpine Linuxsudo apk add fzf
APTDebian 9+/Ubuntu 19.10+sudo apt-get install fzf
Condaconda install -c conda-forge fzf
DNFFedorasudo dnf install fzf
NixNixOS, etc.nix-env -iA nixpkgs.fzf
PacmanArch Linuxsudo pacman -S fzf
pkgFreeBSDpkg install fzf
pkg_addOpenBSDpkg_add fzf
XBPSVoid Linuxsudo xbps-install -S fzf
ZypperopenSUSEsudo zypper install fzf

當然也可以使用 git clone 的方式安裝

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

關於更詳細的安裝方法可以參照 Installation

3 fzf 使用


3.1 FZF 基本使用


fzf 預設會啟用使用者互動查詢, 從標準輸入流(STDIN)讀取, 並將匹配內容輸出到標準輸出流(STDOUT)中:

find * -type f | fzf

fzf 如果沒有接受標準輸入流, 那麼就會直接進行檔案查詢(不包含隱藏檔案), 可以通過設定 FZF_DEFAULT_COMMAND 修改該預設動作:

3.2 FZF 基本操作


fzf # 直接輸入 fzf, 開啟檔案搜尋功能

注: 在 fzf 的使用者互動介面中, 使用者的操作有如下動作可選:

  • 使用CTRL-J/CTRL-K(或者CTRL-N/CTRL-P)進行上下選擇
  • 使用Enter選中條目, CTRL-C/CTRTRL-G/ESC進行退出操作
  • 在多選擇模式(-m), 使用TAB和Shift-TAB標記多個條目
  • Emacs 風格按鍵繫結
  • 支援滑鼠操作

3.3 搜尋


3.3.1 搜尋語法


fzf 預設會以 “extened-search” 模式啟動, 這種模式下不支援正則搜尋, 但是你可以輸入多個搜尋關鍵詞, 以空格分隔, fzf 會無序查詢匹配所有字串.

如 ^music .mp3$, sbtrkt !fire.

fzf 提供了一些增強功能的搜尋語法, 如下表所示:

標記匹配型別描述
sbtrkt模糊匹配內容匹配sbtrkt(字元匹配)
'wild精確匹配(單引號)內容包含單詞wild(單詞匹配)
^music字首精確匹配以music開頭
.mp3$字尾精確匹配以.mp3結尾
!fire反轉匹配內容不包含fire
!^music字首反轉匹配不以music開頭
!.mp3$字尾反轉匹配不以.mp3結尾

注: 如果不想使用模糊匹配或者不想"引用"每個文字, 可以使用 -e/--exact 選項. 注意如果使用 -e/--exact, 那麼 ' 就變成了解引用, 即:'abc表示匹配a,b和c(a,b,c有序), 而不僅僅是匹配abc.

3.3.2 或操作


fzf 以空格分隔, 預設使用的是 與 操作(無序), 如果想使用 或 操作, 那麼可以使用 | :

^core go$ | rb$ | py$ # 表示以`core`開頭, 且以`go`或`rb`或`py`結尾

注: | 前後必須帶空格.

3.3.3 模糊補全


在 bash 或 zsh 終端上, 可以通過輸入 ** 來觸發 fzf 對檔案/目錄的模糊補全(查詢), 如下例子所示:

# Files under current directory
# - You can select multiple items with TAB key
vim **<TAB>
  • 程序 ID 模糊補全

在使用kill命令時, fzf 會自動觸發其自動補全功能:

# Can select multiple processes with <TAB> or <Shift-TAB> keys
kill -9 <TAB>
  • 主機名補全

如下例子所示:

ssh **<TAB>
telnet **<TAB>
  • 自定義模糊補全

在 bash 上, fzf 的模糊補全功能只對一些預定義的命令集有效(具體命令集: complete | grep _fzf), 但是我們也可以為其他命令設定 fzf 模糊補全功能, 如下所示:

# 為 rg 增加模糊補全, rg -F "def main(" **<TAB>
complete -F _fzf_path_completion -o default -o bashdefault rg

# 為 tree 增加模糊補全, tree  **<TAB>
complete -F _fzf_dir_completion -o default -o bashdefault tree

fzf 目前有提供相關 API 供我們自定義模糊補全功能, 具體步驟如下:

  1. 首先自定義一個函式, 使用 fzf 提供的 API: _fzf_complete 提供補全功能:
# Custom fuzzy completion for "doge" command
#   e.g. doge **<TAB>
_fzf_complete_doge() {
  _fzf_complete "--multi --reverse" "[email protected]" < <(
    echo very
    echo wow
    echo such
    echo doge
  )
}
  1. 在 bash 中, 使用complete指令連結我們的自定義函式:
[ -n "$BASH" ] && complete -F _fzf_complete_doge -o default -o bashdefault doge
  1. 終端輸入: doge **<TAB>, 即可驗證結果

3.4 按鍵繫結


fzf 的安裝指令碼會為 bash, zsh 和 fish 終端設定以下按鍵繫結:

按鍵描述
CTRL-T命令列列印選中內容
CTRL-R命令列歷史記錄搜尋, 並列印輸出
ALT-C模糊搜尋目錄, 並進入(cd)

3.5 環境變數


namedescription example
FZF_DEFAULT_COMMAND輸入為 tty 時的預設命令 export FZF_DEFAULT_COMMAND=‘fd --type f’
FZF_DEFAULT_OPTS設定預設選項 export FZF_DEFAULT_OPTS="–layout=reverse --inline-info"
FZF_CTRL_T_COMMAND按鍵對映行為設定
FZF_CTRL_T_OPTS按鍵對映選項設定
FZF_CTRL_R_OPTS按鍵對映選項設定
FZF_ALT_C_COMMAND按鍵對映行為設定
FZF_ALT_C_OPTS按鍵對映選項設定

fzf 預設會以全屏方式顯示互動介面, 可以使用–height選項設定互動介面高度:

vim $(fzf --height 40%)

可以通過設定$FZF_DEFAULT_OPTS變數更改 fzf 預設行為:

# 設定 fzf 預設互動介面大小
export FZF_DEFAULT_OPTS='--height 40%' 

3.6 預覽視窗


可以通過提供 --preview 選項開啟預覽視窗, 並設定響應命令輸出到預覽視窗上.

# {} is replaced to the single-quoted string of the focused line
fzf --preview 'cat {}' # 預覽檔案內容
fzf --preview 'rg -F "def main(" -C 3 {}' # 預覽 Python 檔案 main 函式前後3行程式碼

3.7 高階配置


3.7.1 更改查詢引擎


預設情況下, fzf 使用的查詢引擎是系統自帶的 find 命令, 這裡我們可以對其進行更改, 換成更高效的查詢引擎.

# 使用 rg 進行搜尋
export FZF_DEFAULT_COMMAND='rg --files --hidden'

3.7.2 自定義命令


我們可以通過設定按鍵對映在 fzf 互動介面直接開啟外部程序 (execute, execute-silent) 執行我們選中的檔案

  • 通過快捷鍵執行外部程式
# 在互動介面選中檔案後, 按下 F1, 直接使用 vim 開啟
fzf --bind 'f1:execute(vim {})' 
  • 簡化命令

可以通過定義 shell 指令碼簡化 fzf 命令執行. 比如, 下面示例定義了一個函式, 結合ag實現傳參進行模糊搜尋, 並用 vim 開啟:

# fuzzy grep open via ag
vg() {
  local file

  file="$(ag --nobreak --noheading [email protected] | fzf -0 -1 | awk -F: '{print $1}')"

  if [[ -n $file ]]
  then
     vim $file
  fi
}
  • 自定義全域性快捷鍵觸發

像 fzf 其實已經有為我們提供了一些按鍵對映, 比如, 可以打印出選中檔案. 現在我們也仿照寫一個該功能指令碼, 全域性快捷鍵設為:

  1. 首先先寫目錄搜尋(fzf)並列印輸出功能指令碼:
# .bashrc
outputDir() {
    local dir
    dir=$(find ${1:-.} -type d 2> /dev/null | fzf +m)
    echo $dir
}

2)然後進行全域性按鍵對映:

# .bashrc
bind '"\er": redraw-current-line'
bind '"\C-g\C-o": "$(outputDir)\e\C-e\er"'

注:

  1. \e\C-e: shell-expand-line預設按鍵繫結, 這是最容易的方式進行按鍵繫結, 缺點就是它對於別名(alias)也會同樣進行展開.
  2. redraw-current-line: 在非 tmux 終端上, 該選項必須存在, 否則無法清除提示.
  3. 先source .bashrc, 然後按快捷鍵: , 執行結果如下:

3.7.3 為預覽視窗增加語法高亮:


預覽視窗支援 ANSI 顏色, 因此我們可以為檔案內容增加語法高亮. 我們藉助 bat 這個庫來為我們的文字顯示語法高亮功能:

建議安裝bat, 是一個Rust編寫的獨立程式
也可以安裝rougify(先安裝ruby, 然後gem intall rouge)

  1. 首先, 安裝 bat 庫. 具體步驟請檢視文件.
  2. 終端輸入以下內容:
fzf --preview '[[ $(file --mime {}) =~ binary ]] &&
                 echo {} is a binary file ||
                 (bat --style=numbers --color=always {} ||
                  highlight -O ansi -l {} ||
                  coderay {} ||
                  rougify {} ||
                  cat {}) 2> /dev/null | head -500'

結果如下:

4 用 FZF 提升其他工具的效率


4.1 Git 的好幫手


#---------------------
# modify by gatieme at 2021-02-01 20:47 for FZF
#---------------------
#export FZF_CTRL_T_OPTS="--layout=reserve --preview '(highlight -O ansi -l {} 2> /dev/null || cat {} || tree -C {}) 2> /dev/null | head -200'"
#export FZF_DEFAULT_OPTS="--height 99% -e --layout=reverse --preview '(highlight -O ansi -l {}' --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'"
export FZF_DEFAULT_OPTS="--height 99% -e --layout=reverse --preview '(bat --style=numbers --color=always {} ||  highlight -O ansi -l {} || coderay {} || rougify {} || cat {}) 2> /dev/null '  --color 'fg:#bbccdd,fg+:#ddeeff,bg:#334455,preview-bg:#223344,border:#778899'"


function fview()
{
  fzf -e --layout=reserve --preview="~/.file_view.sh {$2} $1"
}

function lsf()
{
  ls $1 | fview $1
}

function cdf()
{
  cd $(fdfind --type directory | fzf)
}

function gitlog()
{
  git log --oneline $* | fzf -e --multi --preview="git show {+1}"
}

function gitblame()
{
  git blame $1 | fzf -e --layout=reverse --preview="git show {1}" $2
}

function gitcheckout()
{
  git checkout $(git branch -a) | fzf --preview="git log --oneline {1}"
}

當然大家可以使用別的大神已經整合好的配置 wfxr/forgit

4.2 VIM 大殺器


fzf 本身並不是一個vim 外掛, 本來作者只提供了基本的wrapper函式(比如fzf#run). 但後來作者發現很多人並不熟悉 VIMScript, 所以就建立一個預設的 vim plugin.

如果對FZF和vim和結合感興趣可以看: VIM與模糊搜尋神器FZF的整合用法 - 從簡單到高階

5 參考資料


5.1 中文資料


由於開始對於 FZF 不甚瞭解, 因此本博文較多參考了 fzf - 命令列模糊搜尋神器模糊搜尋神器fzf. 在這裡對這兩位作者的成果表示尊重和感謝. 鄙人同一時間正在寫其他技術博文, 為了保證其他博文的細緻, 因此這篇略顯粗糙, 敬請諒解.

FZF wiki

模糊搜尋神器FZF番外篇

5.2 外文資料


Improving Vim Workflow With fzf

Using FZF to Improve Productivity

Boost Your Command-Line Productivity With Fuzzy Finder

Why you should be using fzf, the command line fuzzy finder

Improve Your Workflow in the Terminal with These fzf Tips

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可, 轉載請註明出處, 謝謝合作

知識共享許可協議

因本人技術水平和知識面有限, 內容如有紕漏或者需要修正的地方, 歡迎大家指正, 鄙人在此謝謝啦

轉載請務必註明出處, 謝謝, 不勝感激