コンテンツにスキップ

argc-completions を活用した zsh と nushell のコマンド補完設定

はじめに

zsh と nushell で CLI のサブコマンドやオプションを補完するため、argc-completions を導入します。補完ツールを選んだ理由と、両方のシェルで使う設定手順を紹介します。

シェルの補完は、CLI ツールのコマンドを入力するときに候補を示して入力を助けてくれる機能です。しかし、各種ツールのサブコマンドやオプションは、デフォルトの機能だけでは十分に補完できない場合があります。そこで、メインで使っている zsh と、併用している nushell の両方で、補完をより便利にする設定をしたいと考えました。

argc-completionsは、複数のシェルに対応した補完ツールです。

補完ツールの比較と選定

本記事は、2024 年 11 月に nushell で動作を確認した構成の記録です。argc-completions、argc、zsh、nushell の正確なバージョンは記録していません。

自前で補完関数を書く方法もありますが、手間がかかるため、補完を支援してくれるツールを使うことにしました。調べたうえで検討したのは次の 3 つです。

ツール 対応シェル 検討した結果
zsh-completions zsh 補完スクリプトの配置が必要そう
carapace zsh、nushell、fish、elvish など 用意された補完が古い場合がある
argc-completions zsh、nushell、bash、fish など 1000 以上のコマンドに最初から対応

調べたり実際に使ってみたりした結果、最終的にargc-completionsを採用しました。デフォルトで多くのコマンドに対応しており、少ない作業で補完を使えるようになるためです。

zsh-completions を選ばなかった理由

zsh-completions は、補完スクリプトをツールごとに特定のディレクトリへ配置する必要があるように見えました。モダンなツールなら補完スクリプトを自動生成できるため、配置の手間はそれほどかかりません。とはいえ、スクリプトまで自動で用意してくれる他のツールのほうが魅力的でした。

carapace を選ばなかった理由

carapace は、デフォルトでいくつかのコマンドに対応しており、自分で補完用のスクリプトを書くこともできます。しかし、用意されている補完のサブコマンドやオプションが古く、最新のものに対応していないことがあったため、同様の機能を持つargc-completionsを選びました。

argc-completions の導入手順

導入手順は、リポジトリのREADMEに沿って進めます。README はargc-completionsの特徴として次の点を挙げています。

  • 1000 以上のコマンドの補完に対応
  • ヘルプテキストやマニュアルページから補完スクリプトを自動生成
  • 補完を動的に行うため、読み込むスクリプトが少なく、ターミナルの起動が速い
  • bash、zsh、fish、powershell、nushell などのシェルに対応

1. リポジトリのクローンとセットアップ

リポジトリを取得したら、補完エンジンのargcと YAML プロセッサのyqをdownload-tools.shでダウンロードします。そのうえで、利用しているシェルを引数にしてセットアップスクリプトを実行します。

1
2
3
4
git clone https://github.com/sigoden/argc-completions.git
cd argc-completions
./scripts/download-tools.sh
./scripts/setup-shell.sh zsh

2. シェル設定ファイルへの追記

setup-shell.shを実行すると、シェルの初期化ファイルへ追記するコードを表示したうえで、追記してよいかをy/Nで確認してきます。初期化ファイルは、zsh なら~/.zshrc、nushell ならconfig.nuです。yと答えると、zsh では次のコードが~/.zshrcへ追記され、ARGC_COMPLETIONS_ROOTにはクローン先の絶対パスが入ります。例の/home/user/argc-completionsは仮のパスです。

1
2
3
4
5
6
7
# argc-completions
export ARGC_COMPLETIONS_ROOT="/home/user/argc-completions"
export ARGC_COMPLETIONS_PATH="$ARGC_COMPLETIONS_ROOT/completions/linux:$ARGC_COMPLETIONS_ROOT/completions"
export PATH="$ARGC_COMPLETIONS_ROOT/bin:$PATH"
# To add completions for only the specified command, modify next line e.g. argc_scripts=( cargo git )
argc_scripts=( $(ls -p -1 "$ARGC_COMPLETIONS_ROOT/completions/linux" "$ARGC_COMPLETIONS_ROOT/completions" | sed -n 's/\.sh$//p') )
source <(argc --argc-completions zsh $argc_scripts)

nushell の場合は./scripts/setup-shell.sh nushellを実行すると、同じ流れでconfig.nuへ追記するコードが表示されます。補完の定義をtmp/argc-completions.nuへ書き出し、そのファイルをsourceで読み込む内容です。

1
2
3
4
5
6
# argc-completions
$env.ARGC_COMPLETIONS_ROOT = '/home/user/argc-completions'
$env.ARGC_COMPLETIONS_PATH = ($env.ARGC_COMPLETIONS_ROOT + '/completions/linux:' + $env.ARGC_COMPLETIONS_ROOT + '/completions')
$env.PATH = ($env.PATH | prepend ($env.ARGC_COMPLETIONS_ROOT + '/bin'))
argc --argc-completions nushell | save -f '/home/user/argc-completions/tmp/argc-completions.nu'
source '/home/user/argc-completions/tmp/argc-completions.nu'

実際の動作検証

2024 年 11 月に nushell でgit commitの補完を試したところ、次のようにオプションが説明付きで補完されました。

~/dev/tmp-devbox/argc-completions| git commit --[TAB]                               11/04/2024 06:44:43 AM
--all                   Tell the command to automatically stage files that have been modified and delete...
--patch                 Use the interactive patch selection interface to choose which changes to commit....
--reuse-message         Take an existing commit object, and reuse the log message and the authorship inf...
--reedit-message        Like -C, but with -c the editor is invoked, so that the user can further edit th...
--fixup                 Create a new commit which "fixes up" <commit> when applied with git rebase --aut...
--squash                Construct a commit message for use with rebase --autosquash.
--reset-author          When used with -C/-c/--amend options, or when committing after a conflicting che...
--short                 When doing a dry-run, give the output in the short-format.
--branch                Show the branch and tracking info even in short-format.
...省略

実行結果は省略しますが、zsh でも同様に補完が効くことを確認しました。

git の ref 補完が効かない問題

git のブランチ名や ref、タグ名の補完は、初期状態では効きませんでした。クローンしたargc-completionsのディレクトリでargc generate gitを実行すると、これらの補完も効くようになりました。

ただし、argc generate gitを実行すると定義ファイルが上書きされ、補完が弱くなります。そのため、補完が効くことを確認したら、更新されたファイルを元に戻すとよいでしょう。

まとめ

argc-completionsを使うと、1000 以上のコマンドの補完を、zsh と nushell の両方へ手間をかけずに導入できました。シェルやツールごとに補完スクリプトを用意せずに済むので、複数のシェルを使い分けている場合や、CLI ツールの補完を手早く強化したい場合に向いています。ただし、git の ref の補完のように初期状態で効かないものもあるので、よく使うコマンドは導入後に補完の効き方を確認しておくと安心です。

参考