🍣

Vim/Neovimでjumplistに影響を与えず<C-f>,<C-b>などの中規模移動を行う

2024/09/07に公開

はじめに

Vim/Neovimのカーソル移動方法として大きく3種類あると考えています。

  • /fooやLSPの定義ジャンプ等のbufferを跨ぐこともある大幅な移動
  • {,},C-f,C-b, C-dC-u等の具体的な目的はないが、遠くに目標があることが分かっておりザッピングするように走査していく中規模な移動
  • hjklやw,b,e,ge^,$,fなどの行内や1カーソルのみの小規模な移動

どれもVimを使う上では必須級の操作かと思います。(LSPを使うか否かはありますが)
自分としては目的が明確でない大幅な移動の際に C-dC-u(半ページ移動)を好んで使います。
C-f, C-bを使わないのは、移動後にどこにいるのかが相対的に認識しづらいかと個人的に感じるためです。認知負荷が高いのかなと思っています。)

生じた問題

今回なぜ記事を残しているかというと雑に中規模の移動を行った後jumplistをC-o,C-iで遡る際にストレスがあったというところになります。
もう少し具体的に説明すると、"C-dC-uの押下の度にjumplistにカーソル移動履歴が加えられてしまいC-o,C-iで遡ってしまう"でした。
個人的にはjumplistは冒頭で分類した大規模の移動履歴に限定したいなと思いました。

jumplistとは

helpには以下のように記述されています。

Jumps are remembered in a jump list.  With the CTRL-O and CTRL-I command you
can go to cursor positions before older jumps, and back again.  Thus you can
move up and down the list.  There is a separate jump list for each window.
The maximum number of entries is fixed at 100.

誤解を恐れず、ざっくり意訳するとjumplistというカーソル移動の履歴があって、
C-o, C-iでそれを行ったり来たりできるということですね。

解決策

解決策としては <Cmd>keepjumpsで元のキーに対してマッピングしてしまうことでした。
(vim-jpという日本最大のVimコミュニティで即レスにてご教示頂きました)
具体的には以下のようにマッピングしました。
※Neovimのluaで定義しています。

nmap('<C-d>', '<Cmd>keepjumps normal! <C-d><CR>')
nmap('<C-u>', '<Cmd>keepjumps normal! <C-u><CR>')
vmap('<C-d>', '<Cmd>keepjumps normal! <C-d><CR>')
vmap('<C-u>', '<Cmd>keepjumps normal! <C-u><CR>')
nmap('}', '<Cmd>keepjumps normal! }<CR>')
nmap('{', '<Cmd>keepjumps normal! {<CR>')
vmap('}', '<Cmd>keepjumps normal! }<CR>')
vmap('{', '<Cmd>keepjumps normal! {<CR>')

ヘルプを確認してみたところ以下のような記述となっていました。

Moving around in {command} does not change the |''|,
|'.| and |'^| marks, the |jumplist| or the
|changelist|.
Useful when making a change or inserting text
automatically and the user doesn't want to go to this
position.  E.g., when updating a "Last change"
timestamp in the first line:  

正直これは教えてもらわないと厳しい!と思いました。
Useful... からの記述にあるようにおそらく今回の自分の使い方は少々ハッキーな使い方なのかな?と感じました。
(本来は少し離れた位置にある文字列を編集する際に今のカーソル位置から移動して欲しくない際にこの記述を付与するという使い方なのかなと読み取りました。)

jumplistのみでなく g;, g,での履歴移動が可能なchangelistについても編集せずにコマンドを与えられるようです。(しかし、こちらに関しては用途は正直思い浮かびません。)

おわりに

途中にも書きましたが、今回vim-jpというコミュニティで質問させていただいたところ
ものの1分も経過しない内に回答して頂けました。本当に感謝です。

質問させて頂いたのは数ヶ月前だったのですが、そういえばと思い今(2024-09-07)GPT-4oに聞いてみたところちゃんと:keepjumpsを教えてくれました。質問のタイミングで4oのモデルがリリースされていたかは定かではないのですが、本当にいい時代になったなと感じました。

GitHubで編集を提案

Discussion