zfをline-wise化して直感的な挙動にするマッピング

by
カテゴリ:

Vim駅伝2024/09/06の記事です。

Vimのzfコマンドは、モーションまたはビジュアルモードによる選択範囲に対して折り畳みを作ります。

私はよく、vjjjzfみたいな感じで、ビジュアル選択した範囲を折り畳んだり、folke/flash.nvimと組み合わせて文法上の意味のある範囲(関数全体とかマークダウンの章とか)を折り畳む使い方をしてます。

しかし、選択範囲がchar-wiseだと折り畳み範囲の最後が空行な場合に、追加で一行折り畳んでしまいます。以下のようなマッピングで、zfを強制line-wise化するといいでしょう。

nnoremap zf zfV
vnoremap <expr> zf mode() ==# 'V' ? 'zf' : 'Vzf'

設定がない場合に以下のようなマークダウンにおいて、1行目からvjjjzfしてみると、言わんとすることが分かると思います。

# foo

hoge

# bar

fuga

vjjjなので、ビジュアルにハイライトしている範囲は4行なのに、折り畳みが5行になってしまうのです。

--- 5 lines: # foo ----------------------------

fuga

これはchar-wiseなビジュアルモードだと、空行の選択が改行の選択になってしまっているからですね。

理屈はわかるものの、使いづらいです。

こんな時は、Vjjjzfとline-wiseなビジュアルモードを使えばOKです。 zf{motion}の場合もzfV{motion}すると、モーションをline-wiseに強制できます。これで解決ではあるものの、ストローク数が増えるのは難点です。

というわけで、冒頭で示したとおり、zfが必ずline-wiseになるようマッピングしてしまうといいです。

nnoremap zf zfV
vnoremap <expr> zf mode() ==# 'V' ? 'zf' : 'Vzf'

ENJOY!!