CDK のコマンドラインオプションとして指定するキーワードをいつも忘れてしまうので入力補完できないものかと調べてみました。

入力補完の機能は用意されているのか

CDK を(推奨された方法ではないようですが) npm install -g aws-cdk でインストールしてもコマンドラインオプションの入力補完はできません。実は自前でヘルプを見ながら completion を作ってしまったのですが、更新の盛んな CDK では持続可能なやり方ではなさそうです。調べてみると公式では yargs を使った入力補完のための機能が用意されているようです。

Github 公式リポジトリのこちらの Discussion で方法が紹介されていました。~/.zshrc に以下を追加すれば良いようです( bash の方はリンク先をご参照ください)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
###-begin-cdk-completions-###
_cdk_yargs_completions()
{
  local reply
  local si=$IFS
  IFS=$'
' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" cdk --get-yargs-completions "${words[@]}"))
  IFS=$si
  _describe 'values' reply
}
compdef _cdk_yargs_completions cdk
###-end-cdk-completions-###

7行目で cdk --get-yargs-completions ... と実行されています。このコマンドで completion 用の出力がされるようです。

上記を貼り付けても私の環境では入力補完は動作しなかったのですが、~/.zsh/completion/_cdk として以下の通り作成したら補完ができるようになりました。ファイル作成後、ターミナルを再起動するか、exec -l $SHELL します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#compdef cdk

_cdk() {

  local reply
  local si=$IFS

  IFS=$'\n'
  reply=($(COMP_CWORD="$(($CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" cdk --get-yargs-completions "${words[@]}"))
  IFS=$si

  _describe 'values' reply
}

_cdk "$@"

ハイライトした 1、8、15行目あたりが追加、変更したところです。

動作イメージ

サブコマンドの後のオプション(-- で始まるオプション)も補完できるようになりました。

CDK Completion

固定文字列を指定するオプションの補完

この状態でも十分なのですが、せっかくなので少しカスタマイズします。例えば cdk deploy の時の --require-approval の後には any-changebroadeningnever が指定できますが、前述の関数ではそこまで補完してくれません。--help で見た時の [string] [choices: ...] となっているやつです。

(こうなってるやつ) CDK option string choices

これらも補完したかったので、ベタ書きでスマートじゃないですが、先ほどのファイル ~/.zsh/completion/_cdk を以下のように変更します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#compdef cdk

_cdk() {

  if [[ ${words[@]} =~ --require-approval\ +[^\ -]*$ ]]; then
    # In case of "deploy"
    compadd never any-change broadening
    return 0
  elif [[ ${words[@]} =~ --progress\ +[^\ -]*$ ]]; then
    # In case of "deploy" or "watch"
    compadd bar events
    return 0
  elif [[ ${words[@]} =~ (--language|-l)\ +[^\ -]*$ ]]; then
    # In case of "init"
    compadd csharp fsharp go java javascript python typescript
    return 0
  elif [[ ${words[@]} =~ (--method|-m)\ +[^\ -]*$ ]]; then
    # In case of "deploy"
    compadd direct change-set prepare-change-set
    return 0
  fi

  local reply
  local si=$IFS

  IFS=$'\n'
  reply=($(COMP_CWORD="$(($CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" cdk --get-yargs-completions "${words[@]}"))
  IFS=$si

  _describe 'values' reply
}

_cdk "$@"

ハイライトした 5 - 21行を追加します。特定のオプションが入力されたら、固定文字列を候補として表示してあげる感じです。

GitHub にも上げておきました。

変更したら、exec -l $SHELL で再読み込みします。動くはずなのになーと思った時は ~/.zcompdump を削除してみるとリフレッシュされるかもしれません。

動作イメージ

CDK completion also string choices option

(ここで気づいたのですが CDK は F# でも書けるんですね…)

CDK をグローバルにインストールしていない場合

前述の Github の Discussion でも言及されていますが、CDK をグローバルにインストールしていない場合は他にちょっと手を加える必要があるようです。Discussion の内容そのままですが紹介します。

方法1 : ラッパー関数

.zshrc もしくは .bashrc に以下を追加

cdk() { npx -- cdk "$@" }

方法2 : エイリアスで npx の補完をリダイレクト(zsh のみ)

.zshrc に以下を追加

alias cdk="npx cdk"
compdef _precommand npx

方法3 : エイリアスと completealiases (zsh のみ)

.zshrc に以下を追加(zsh のエイリアスの補完を可能にする機能を使う。ただし他の機能を壊してしまうかもしれない、とのこと)

alias cdk="npx cdk"
setopt completealiases

まとめ

CDK コマンドの zsh での補完機能について紹介しました。機能追加が盛んなプロダクトではこのような補完機能はありがたいですね。

今回は実装しませんでしたが、スタック名指定する時の補完もできそうな気がします。

最後に・・・

この投稿は個人的なものであり、所属組織を代表するものではありません。ご了承ください。