fzf 簡化你的終端機開發生活

Posted on  Nov 3, 2018  in  開發工具  by  Amo Chen  ‐ 4 min read

FZF and Vim Talk - Dorian Karter 影片詳細介紹如何在 VIM 中使用 fzf ,也就是透過安裝 fzf.vim 為 VIM 裝上強大的模糊搜尋的功能。

然而 fzf 強大的功能並不僅限於 VIM ,對於經常使用終端機進行開發的開發者而言,也有很多地方其實可以結合 fzf 增加效率,例如 fzfを活用してTerminalの作業効率を高める 一文就結合 fzf 與 git ,令 git 的使用變得更順手。

本文將透過幾個實例介紹 fzf 如何與終端機開發生活的結合。

fzf 是什麼?

fzf 可以說是 command-line 版本的 macOS Finder ,但卻又更加靈活,讓人可以利用其功能打造屬於自己的 fzf 應用。

上方 fzf 開發者所提供的預覽圖,多多少少揭露 fzf 所具有的功能:

  1. 模糊搜尋
  2. 選擇搜尋結果
  3. 預覽搜尋結果

首先最底下是搜尋列,可以任意輸入字串, fzf 會用模糊搜尋(fuzzy search)的方式進行搜尋,所以就算沒有使用完整的關鍵字也沒關係,搜尋上方顯示的是搜尋結果,同時可以用方向鍵選擇感興趣的搜尋結果,同時位於右側的預覽視窗(preview window)中會顯示其內容。

雖然 fzf 預設是搜尋資料夾內的所有檔名,但 fzf 是可以接受 pipe 進來的資料,以行為單位搜尋,例如搜尋 22 通訊埠(port)通常是什麼服務(service):

$ alias fp="cat /etc/services | fzf"
$ fp

有興趣的話建議可以進一步閱讀官方的 README & Wiki 。

接著就透過幾個實例說明 fzf 各項功能。

本文環境

  • macOS 10.13.6
  • iTerm2 3.2.5
  • fzf 0.17.4
  • zsh 5.5.1

macOS 安裝指令:

$ brew install fzf

flsof4

在開發後端伺服器時經常會不小心碰到 IP 或者 Port 衝突的情況,所以經常要 lsof -Pn -i4 | grep <ip_or_port> 進行查詢,這種情況相當適合用 fzf 解決:

$ alias flsof4="lsof -Pn -i4 | awk '{printf \"%10s %6s %5s %4s %-20s\n\", \$1, \$2, \$3, \$8, \$9}' | fzf --border --cycle --ansi --header-lines=1"
$ flsof4

上述指令用 lsof -Pn -i4 列出現在主機正在執行的 IPv4 網路服務,接著用 awk 取出需要的欄位,最後丟給 fzf 處理。

--border 指的是為 fzf 顯示邊框。

--cycle 指的是啟用循環捲動,用方向鍵移動選擇列的話,到底部之後會從頂部開始,或者到頂部之後,會跳回底部開始。

--ansi 則是啟用支援 ANSI color ,所以有些指令用 ANSI color 顯示色彩的話, fzf 的顯示結果也同樣會顯示色彩。

--header-lines=1 則是指,第 1 行視為標題列,所以標題列就不會被搜尋。

gcob

用 git 切換 branch 時,也結合 fzf ,將 branch 列出來之後,交給 fzf 處理,選擇完按 Enter ,就會切換 branch :

$ alias gcob='git checkout $(git branch | fzf --cycle --border --ansi)'
$ gcob

gadd

編者有個習慣是在 git add 檔案之前,需要先稍微瞄一下 diff ,判斷要不要一起 commit 。

這些動作同樣可以結合 fzf 的預覽視窗(preview window)功能,顯示檔案的 diff 在預覽視窗,減少打指令的次數:

$ alias gadd="git status --short | fzf --multi --color=dark --cycle --border --ansi --preview-window=up:70% --preview=\"git diff --color {+2}\" | awk '{print \$2}'  | xargs git add"
$ gadd

--multi 指的是啟用多選的功能,所以可以按 Tab 同時選擇多個檔案。

--preview-window=up:70% 指的則是將預覽視窗顯示在上方,高度則佔整個視窗的 70% 。除了 up 之外還有 down , left , right 可選。

設定預覽視窗之後,還需要透過參數 --preview 設定要顯示的內容,因此 --preview=\"git diff --color {+2}\" 指的就是顯示檔案的 diff ,而 {+2} 指的就是選擇列所在的第 2 個欄位(預設以空格分隔,所以 {+1} 會取得 M?? )。

指令的最後則是結合 awk 與 xargs 將選擇的檔案交給 git add 。

gco

gadd 相同的技巧,也能夠應用在 git checkout 上,用來取消檔案變更:

$ alias gco="git diff --name-only | fzf --multi --color=dark --cycle --border --ansi --preview-window=up:70% --preview=\"git diff --color {+1}\" | xargs git checkout"

gustg

除了取消檔案變更,也可以將 staged 的檔案變回 modified:

$ alias gustg="git diff --name-only --cached | fzf --multi --color=dark --cycle --border --ansi --preview-window=up:70% --preview="git diff --color --staged {+1}" | xargs git reset HEAD"
$ gustg

gbrd

將 fzf 與 git branch -d 結合,讓刪除 branch 更加方便:

$ alias gbrd="git branch --color=always | fzf --multi --color=dark --cycle --border --ansi | sed 's/*//' | awk '{print \$1}' | xargs git branch -d"

fls

最後的範例(僅限 macOS)利用 fzf 提供的 key bindings 功能,讓我們可以設定快捷鍵在 fzf 的介面中觸發設定好的功能:

$ alias fls="fzf --multi --color=dark --cycle --border --ansi --preview-window=up:70% --preview=\"head -n 25 {+1}\" --bind 'ctrl-v:execute(vim {} < /dev/tty)' --bind 'ctrl-o:execute(open \$(dirname {}))' --bind 'ctrl-x:execute(echo {} | pbcopy)'"
$ fls

--bind 'ctrl-v:execute(vim {} < /dev/tty)' 按 Ctrl + v 會用 VIM 打開選擇列所選擇的檔案, execute() 內則可以放任何我們想要執行的功能,而 {} 就代表選擇列目前所選的字串。

--bind 'ctrl-o:execute(open \$(dirname {}))' 按 Ctrl + o 會打開該檔案的資料夾。

--bind 'ctrl-x:execute(echo {} | pbcopy)' 按 Ctrl + x 則會將檔案路徑複製到剪貼簿中。

總結

fzf 是十分強大的工具,運用得當的話,可以有效增加工作效率。除了本文介紹的幾個功能之外,其實還有許多功能讓人可以製作符合自己需求的 fzf 應用,建議可以閱讀官方文件,也許會有意想不到的收穫!

References

https://github.com/junegunn/fzf

https://www.youtube.com/watch?v=aXPQTesFdTI

https://qiita.com/kamykn/items/aa9920f07487559c0c7e

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!