🐟

fish-shellのviモードを試してみた

2022/10/17に公開

fish-shellのviモードを試してみた

fish-shellではvi風の操作を可能にする viモード が標準で用意されています。
今回訳あってviモードを設定してみたら、思いのほか良かったのでご紹介です。[1]

こんな感じです

fish-shell viモードでのサンプルです
[2]

こちらのサンプルでは以下の操作を行なっています。

  1. b で1単語前に移動
  2. de で1単語削除
  3. u でundo
  4. ^ で行頭に移動
  5. f で前方文字検索(fll までジャンプ)
  6. R でリプレイスモードに切り替え、入力文字で上書き
  7. F で後方文字検索(FII までジャンプ)
  8. r で1文字リプレイス(rUU に上書き)
  9. A で行末に移動しインサートモードへ切り替え

このほかにも標準で色々な操作がviのキーバインドで行え、viでの操作に慣れている方にはきっと役立つと思います!

リファレンスはこちらです。
ただリファレンスに記載以上のことがキーバインドに設定されており、たとえば ~ で大文字小文字切り替えなんかもできます。
下記でviモード時に設定されるキーバインドを確認できますのでより詳しく見てみたい方はぜひご覧になってみてください。

$ functions fish_vi_key_bindings
function fish_vi_key_bindings --description 'vi-like key bindings for fish'
...
    # Default (command) mode
    bind -s --preset :q exit
    bind -s --preset -m insert \cc cancel-commandline repaint-mode
    bind -s --preset -M default h backward-char
    bind -s --preset -M default l forward-char
...
ends

設定方法

viモードを有効にするには ~/.config/config.fishfish_vi_key_bindings 追加するだけOKです。[3]

ただこれだと既存のキーバインド(ctrl + a で行頭など)は使えなくなってしまうので、そちらも残しておきたい場合は後述の設定が必要となってきます。

デフォルトのキーバインド (Emacsキーバインド) も残しつつviモードを有効化する方法

デフォルトのキーバインドも残しつつviモードのキーバインドを有効にするには、一度各モードでデフォルトのキーバインドを有効にした上でviモードを起動する必要があります。

# 各モードでデフォルトキーバインドを呼び出し
for mode in default insert visual
    fish_default_key_bindings -M $mode
end
fish_vi_key_bindings --no-erase

なおリファレンスに明記されているわけではないですが、fish_hybrid_key_bindings というキーバインドプリセットも用意されており、そちらを呼び出すことでも設定可能です。[4]

おまけ:Escキー以外でインサートモードから抜ける方法

普段Vimを使われている方の中には jjjk を入力することでインサートモードからノーマルモードに戻る設定を入れている方も多いのではないでしょうか?

fish-shellでもモードに対するバインドを設定することで同様のことが設定可能です。

bind -M insert -m default jk force-repaint

インサートモード時の jk のキーバインド変更しています。デフォルトモードに切り替えプロンプトを再描画するよう設定しています。(再描画しないとモードが切り替わりません。)

さいごに

viモードに設定してみてまだ数日しか経っていませんが、今のところイイ感じです。 文字検索などはviモードにしかなく慣れるほどカーソル移動が早くなるのを感じています。

皆さんもfish-shell、そしてviモードぜひ試してみてください!

最後に参考まで私の設定をのせておきます。viモードを試す際などご自由に活用ください!

fish_user_keybindings.fish
function fish_user_key_bindings
    for mode in default insert visual
        fish_default_key_bindings -M $mode
    end
    fish_vi_key_bindings --no-erase
    if test "$__fish_active_key_bindings" = fish_vi_key_bindings
        bind -M insert -m default jk force-repaint
    end
end

よろしければ気軽にフォローしていただけるとアヒルくんが喜びます。

Thank you for reading my post. Happy Development!!

脚注
  1. WindowsでVS Code使うとターミナル操作時に行末まで削除の Ctrl + k がVS Code操作のショートカットに取られてしまい難儀していたところ、viモードの存在を知り今回試すに至りました。(私が普段使っているMacだとVS Codeの操作は ⌘ + k になるので競合しない) ↩︎

  2. Tideというプロンプト設定プラグインを使っているので、fish-shellそのまま使用している場合と表示内容が異なっています。 がインサートモード、 がデフォルトモード、 がリプイスモードとなっていることを表しています。fish-shellそのまま利用した場合は [I] がインサートモード、 [N] がデフォルトモード、 [R] がリプレイスモードとなります。 ↩︎

  3. または ~/.config/fish/functions/fish_user_key_bindings.fish などに fish_user_key_bindings 関数を定義し、そこで fish_vi_key_bindings を呼び出すことでも設定可能です。 ↩︎

  4. その場合、キーバインド設定も fish_hybrid_key_bindings に設定されるため注意が必要です。たとえばプラグインなどでviモードである fish_vi_key_bindings への考慮はされているのですが fish_hybrid_keybindings にはそれがなく、想定通りに挙動しないということもありました。 ↩︎

Discussion