給 zsh 自定義命令新增引數自動補全

mzlogin發表於2022-02-12

有時我會自定義一些 zsh 命令,以便提升某些高頻操作的效率。本文記錄我給一個自定義命令新增引數自動補全的方法。

場景

我自定義了一個 zsh 命令 gmt,執行 gmt <b2>,可以將當前所在的 git 分支 merge 到 <b2> 這個分支。

它具體完成以下工作:

  1. 切換到 git 分支 <b2>
  2. <b2> 分支更新到最新;
  3. 詢問是否合併,輸入 y 則進行分支合併。

也就是用一條命令完成一個 git checkout b2git pull origin b2git merge b1 這樣的組合操作。

用了一段時間,可以省一些事,美中不足的就是有時候分支名稱比較長,只能手動輸入,沒有自動補全。

期望效果

  1. 輸入 gmt ,然後按 tab,自動提示本地的所有 git 分支名稱;
  2. 輸入 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/config-files,有需要可以參考下。

效果演示

參考

相關文章