↔️

vim-incopenでファイル名順で前後のファイルを開く

2024/11/15に公開

この記事はVim駅伝の269本目の記事です。

ファイルを開いているとき、同じディレクトリにあるファイル名順で隣のファイルを開きたい、
といった場面はあるでしょうか?

abc001
|-- abc001_1.rb
|-- abc001_2.rb
|-- abc001_3.rb <-- 今このファイルを開いていて
`-- abc001_4.rb <-- このファイルを開きたい

そんなとき、ファイルがカレントディレクトリにあるのであれば、:eや:tabnewから開くことができますし、ファイルがカレントディレクトリに無かったとしても、:eや:tabnewの後に%:hと入力してタブでディレクトリ名を補完した上でファイルを開くこともできます。あるいは、プロジェクトが大きくファイルがたくさんあるのであれば、任意のファジーファインダーを利用して開くこともあるでしょう。

とはいえ、状況によってはより気軽に開きたいもの。例えば、コンテストに提出するプログラムが連番で並んでいるとき、試験的なスクリプトが連番で並んでいるとき、章立てされたファイルが連番で並んでいるとき、交互のファイルの行き来を頻繁にしたい場面はときにあると思います。

そんなとき、vim-incopenというVimプラグインを利用すると、ファイル名順で並んだファイルの行き来を気軽にすることができます。この記事ではvim-incopenの使い方を紹介します。

https://github.com/nil-two/vim-incopen

使い方

次の2つのExコマンドを利用して、
ファイル名順で次、ファイル名順で前のファイルを開くことができます。

" ファイル名順で次のファイルを開く
Nextopen
" ファイル名順で前のファイルを開く
Prevopen

:Nextopenでファイル名順で次のファイル、:Prevopenでファイル名順で前のファイルが開かれます。次のように記事冒頭の状況であれば、:Nextopenabc001_4.rb:Prevopenabc001_2.rbを開くことができます。

abc001
|-- abc001_1.rb
|-- abc001_2.rb <-- :Prevopenを実行すると開かれる
|-- abc001_3.rb <-- 今このファイルを開いている
`-- abc001_4.rb <-- :Nextopenを実行すると開かれる

しかし、Exコマンドなので手間としてはあまり変わっていないところ。
キーマップを定義したいところです。次のようにvimrcで設定をすると、))で次のファイル、((で前のファイルを開くことができます。

" ファイル名順で次のファイルを開く
nmap <silent>)) <Plug>(nextopen)
" ファイル名順で前のファイルを開く
nmap <silent>(( <Plug>(prevopen)

先ほどの記事冒頭の状況であれば、))abc001_4.rb((abc001_2.rbを開くことができます。基本的にはこれだけですが、状況によってはこれだけでも結構便利なものです。

また、ケースとしては珍しいかもしれませんが、
ファイル名の数値をインクリメント、デクリメントしたファイルを開くこともできます。
ファイル名の数値をインクリメント、デクリメントしたファイルを開くには、次のExコマンド、キーマップでインクリメント、デクリメントしたファイルを開きます。状況によってはこちらを使うのも一つです。こちらであれば、ディレクトリに存在しないファイルであっても開くことができます。

" ファイル名の数値をインクリメントしたファイルを開く
Incopen
" ファイル名の数値をデクリメントしたファイルを開く
Decopen
" ファイル名の数値をインクリメントしたファイルを開く
nmap <silent>)) <Plug>(incopen)
" ファイル名の数値をデクリメントしたファイルを開く
nmap <silent>(( <Plug>(decopen)

ファイル名順以外で前後のファイルを開きたいとき

vim-incopenが開くことができるのは、同じディレクトリにあるファイル名順で隣にあるファイルだけです。状況によっては前後のファイルというものが、同じディレクトリにあるファイル名順で隣にあるファイルであるとは限らない状況もあります。

例えば、Railsのコントローラーとモデル、Cの.cファイルと.hファイルなど。
これらは前後のファイルというよりは、対応するファイルですが、
今開いているファイルの次に開きたいファイルであるという点では同じです。

そんなとき、vim-altrというVimプラグインを利用するとそれらのファイルを開きやすいです。

https://github.com/kana/vim-altr

vim-altrでは、次のようにvimrcで設定をして対応するファイルのパターンを定義します。
パターンを定義しておくと、後述の方法で次のファイル、前のファイルを開くことができます。

" %.cと%.hを行き来できるようにする
call altr#define('%.c', '%.h')
" autoload/%.vim, doc/%.txt, plugin/%.vimを行き来できるようにする
call altr#define('autoload/%.vim', 'doc/%.txt', 'plugin/%.vim')

パターンの定義方法についてはドキュメントに分かりやすくまとめられているので、
詳しくはドキュメントを参照することをおすすめしますが、パターンは上記のようにaltr#define()を使って定義します。altr#define()にはパターンのリストを書くようになっていて、ワイルドカードは%で指定できます。パターンのリストは2つだけでなく、3つ以上にすることもでき、3つ以上ある場合は次へでリストの中の次のファイル、前へでリストの中の前のファイルが開かれるようになります。

vim-altrで次のファイル、前のファイルを開く方法ですが、
Exコマンドを利用して開く場合は、次の2つの関数を利用して、
次のファイル、前のファイルを開くことができます。

" ファイル名順で次のファイルを開く
call altr#forward()
" ファイル名順で前のファイルを開く
call altr#back()

キーマップももちろんあります。
次のようにvimrcで設定をすると、))で次のファイル、((で前のファイルを開くことができます。

" ファイル名順で次のファイルを開く
nmap <silent>)) <Plug>(altr-forward)
" ファイル名順で前のファイルを開く
nmap <silent>(( <Plug>(altr-back)

ファイル名順でではなくパターンで前後のファイルを開きたい場合はこちらがおすすめです。
vim-altrについては作者の方が解説をしている記事もあるので、是非参照してみてください。

https://www.timedia.co.jp/tech/vim-altr/

おわりに

vim-incopenはプロジェクトが小さく、連番のファイルが登場するときに便利なプラグインになっているので、よければお試しください。

vim-incopenはVimperatorを参考にしたプラグインです。
Vimperatorは昔存在したブラウザをVim風のキーバインドで操作できるFirefoxアドオンで、
Vimperatorは今はもうFirefoxのアップデートによって動かなくなってしまったのですが、
Vimperatorが有する機能の一つとして、<C-a><C-x>でURLの数字をインクリメント、デクリメントして開くという機能が搭載されていました。

http://vimperator.org/

vim-incopenのIncopen、Decopenはこれを再現したものです。
利用頻度としてはIncopen、DecopenよりNextopen、Prevopenのほうが多いので、
名前にもなっているIncopenはあまり使う機会が無いのですが、ときどき使う場面があります。

Discussion