有時我會自定義一些 zsh 命令,以便提升某些高頻操作的效率。本文記錄我給一個自定義命令添加參數自動補全的方法。
場景
我自定義了一個 zsh 命令 gmt,執行 gmt <b2>,可以將當前所在的 git 分支 merge 到 <b2> 這個分支。
它具體完成以下工作:
- 切換到 git 分支
<b2>; - 將
<b2>分支更新到最新; - 詢問是否合併,輸入
y則進行分支合併。
也就是用一條命令完成一個 git checkout b2、git pull origin b2、git merge b1 這樣的組合操作。
用了一段時間,可以省一些事,美中不足的就是有時候分支名稱比較長,只能手動輸入,沒有自動補全。
期望效果
- 輸入
gmt,然後按 tab,自動提示本地的所有 git 分支名稱; - 輸入
gmt fe,然後按 tab,自動補全以fe開頭的 git 分支名稱;
實現方法
在 zsh 配置文件中添加如下代碼:
compdef _git_merge_to_comp git_merge_to
_git_merge_to_comp()
{
local -a git_branches
git_branches=("${(@f)$(git branch --format='%(refname:short)')}")
_describe 'command' git_branches
}
注:git_merge_to 是一個自定義的函數,gmt 是這個函數的 alias。
這段代碼的意思就是使用 _git_merge_to_comp 這個函數來給 git_merge_to 命令做自動補全,自動補全的候選列表是當前項目的所有本地 git 分支名稱。
其中:
compdef、_describe 等的用法,可以參考 zsh 的官方文檔 Completion System。
git_branches=("${(@f)$(git branch --format='%(refname:short)')}") 的意思是,將 git branch --format='%(refname:short)' 命令的輸出按行分割後形成一個字符串數組,賦值給 git_branches 變量,這部分可以參考 How to properly collect an array of lines in zsh。
我的 zsh 配置都上傳到了 https://github.com/mzlogin/co...,有需要可以參考下。
效果演示
參考
- Completion System
- How to properly collect an array of lines in zsh