fish shell 自動補全子命令

劉哇勇發表於2021-04-22

之前在 「建立 fish shell 自動補全檔案」 中介紹瞭如何建立 fish 的補全檔案,實現對命令的友好補全提示。通過形如 complete -c <command> -a ["引數列表"] 的指令碼來實現的。

比如 complete -c myprog -a "yes no" 可在輸入 myprog 後通過 TAB 喚起提示:

$ myprog<tab>
no yes

但如果 <comamnd> 包含子命令時,則需要麻煩些。比如拿 git commit 來說,為了實現在輸入該命令時提示一些資訊,實測如下形式是不行的:

complete -c git-commit -a "yes no"
complete -c "git commit" -a "yes no"

同時,想要實現 git commit -m<TAB> 在進行 git 提交時,進行一些提示,除了需要解決上面子命令判定的問題,還需要判定這裡的 -m 引數。

判斷子命令

檢視 fish 在 GitHub 的倉庫可發現,在 fish-shell/share/functions/ 目錄下提供了很多工具方法, 通過 __fish_seen_subcommand_from 配合 complete-n 引數可實現子命令的判定。

該工具方法需要結合 -n(condition)引數,指定一段 shell 指令碼,當指令碼返回 0 時所指定的自動補全才生效。

complete -f -c git -n '__fish_seen_subcommand_from commit' -a 'test' -d "the test command will appear after commit"

上述指令碼實現的效果,是在輸入 git commit 之後,TAB 會觸發 test 命令的自動補全,當且僅當 git 後跟的是 commit 這個子命令。

-s -l 的用法

一般命令會需要帶引數,這些引數或是通過 - 加縮寫或 -- 加完整的引數名稱提供。通過 -s(short)、 -l(long) 便可指定命令需要補全的引數名稱。

complete -f -c git -n '__fish_seen_subcommand_from commit' -s m --l message -d "specify the commit message"
complete -f -c git -n '__fish_seen_subcommand_from commit' -s f --l foo -d "argument foo"
complete -f -c git -n '__fish_seen_subcommand_from commit' -s b --l bar -d "argument bar"
complete -f -c git -n '__fish_seen_subcommand_from commit' -s b --l baz -d "argument baz"
complete -f -c git -n '__fish_seen_subcommand_from commit' -s b --l quz -d "argument quz"

上述指令碼實現的效果是,在輸入 git commit -<TAB> 後,引數列表會作為候選補全列出來:

$ git commit -
-b  --quz  (argument quz)  -m  --message  (specify the commit message)  --baz  (argument baz)
-f  --foo  (argument foo)  --bar                        (argument bar)

可以看到,預設情況下,這些引數按字母順序進行了重排,可通過 -k (keep order) 來保持書寫時指定的順序。-k 引數對於 -a 指定的命令也適用。

判定引數

通過 __fish_seen_argument 工具方法,可判定輸入的命令後有沒有跟指定引數。

complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'build' -d "Changes that affect the build system or \r\ntexternal dependencies (example scopes: gulp, broccoli, npm)"

這裡判定引數的寫法,和前面 -s -l 中介紹的一致。

上述指令碼實現的效果是,當輸入 git commit -m<TAB> 時會自動補上 build 命令。

到這裡就完成了子命令和引數的判定。接下來,就可以用於一些實用的場景,比如 Angular 的提交訊息規定了如下的形式:

<type>(<scope>): <short summary>

其中 <type> 包含如下可選值:

  • build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
  • ci: Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)
  • docs: Documentation only changes
  • feat: A new feature
  • fix: A bug fix
  • perf: A code change that improves performance
  • refactor: A code change that neither fixes a bug nor adds a feature
  • test: Adding missing tests or correcting existing tests

可通過前面介紹的方法,將這裡的 type 在進行 git commit 時給提示出來。

實現 Angular commit type 的自動提示

最後,實現這一效果的指令碼大概是這樣子:

complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'build' -d "Changes that affect the build system or \r\ntexternal dependencies (example scopes: gulp, broccoli, npm)"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'ci' -d "Changes to our CI configuration files and scripts (example scopes: Circle, BrowserStack, SauceLabs)"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'docs' -d "Documentation only changes"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'feat' -d "A new feature"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'fix' -d "A bug fix"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'perf' -d "A code change that improves performance"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'refactor' -d "A code change that neither fixes a bug nor adds a feature"
complete -k -f -c git -n '__fish_seen_subcommand_from commit; and __fish_seen_argument -s m -l message' -a 'test' -d "Adding missing tests or correcting existing tests"

相關倉庫 ?wayou/angular-commit-complete

相關資源

The text was updated successfully, but these errors were encountered:

相關文章