fishの補完をhjklで選びたい


fishの補完選択

fish_greetingを古のAAにしているインターネット老人会の図:

zshからfishに乗り換えました
文法の違いとかで困るんじゃないかとか、今まで敬遠していたんですが、先週末思い切って乗り換えました

で、概ね設定は済んだのですが、最後までどうしてもうまくいかなかったのが、この補完の選択
↑の図だとhoge/fugaとかhoge/hogehogeとかhoge/piyoを候補で表示してくれてますが、これを選ぶのがツラい
なにがツラいってデフォルトだとキーバインドが全然わからない

viモードにする

fish_vi_key_bindingsを実行すると、キーバインドがviライクなモードに入ります
iでインサートモードに入ったり、Ctrl-[でコマンドモードに入ったり
しかしこれでもまだ問題は解決されません
補完候補は、ある程度文字を入力したあとTabを押して表示させるわけですが、
「ある程度文字を入力」
してるので当然インサートモードになります
コマンドモードであれば、hjklで補完候補を選択できるのですが、インサートモードではもちろんできません

できればzshの

bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'j' vi-down-line-or-history
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char

のように、「インサートモードでも補完候補選択に入ったらhjklで選べる」みたいなのがやりたいわけです

bind

というわけでキーバインドの設定を変更します
fishはbindを実行することでキーバインドを変更できます
今回の目的だと、このように設定するのが正解でした

  bind -M insert k "if commandline -P; commandline -f up-line; else; commandline -i k; end"
  bind -M insert j "if commandline -P; commandline -f down-line; else; commandline -i j; end"
  bind -M insert h "if commandline -P; commandline -f backward-char; else; commandline -i h; end"
  bind -M insert l "if commandline -P; commandline -f forward-char; else; commandline -i l; end"

なにをしているのか解説

bind -M insert k まずこれで「インサートモード中のkのキーのbind設定」を宣言
if commandline -P 「いまページャコンテンツを表示しているか(補完候補などを表示している状態かの判定)」
commandline -f up-line ↑の判定がtrueだったらup-lineコマンドを実行
else; commandline -i k ↑の判定がfalseだったら通常のkを入力

というbind設定になってます
こうすることで、補完候補表示時はhjklがカーソル移動になり、それ以外の場面では通常通りの文字入力にすることができます

感想

補完候補でカーソルを左に動かす、上に動かす、みたいなコマンドがどれなのか全然わからなくて超しんどかったです
でもよく考えたらデフォルトのキーバインドとかよく見ろよって話で、この辺見てたらすぐわかりました
あと、「普通にkを入力する」とか結構ハマりました
最初はcommandline -f self-insertとかしてたんですが、違うんですよね
commandline -i kでいいのか〜って気づくまで結構かかりました←

これでたのしいfishライフが送れそうです