
vimの検索機能を拡張するスクリプトを作成します。
完成イメージ
vimで検索するとき、ファイルをまたいで検索したくなることはないでしょうか。
例えば、File1で使う関数をFile2で定義しているとき、
中身がどうなっているか見たくなることありませんか?

今回は、そんな機能をvimスクリプトで作成していきます。
vimの検索機能
vimはノーマルモードで/(スラッシュ)を入力すると、検索機能が作動します。

そして、/(スラッシュ)の後に文字を続けてEnterを押すとその文字の位置までジャンプします。

そしてnを押すと次の位置までジャンプし、Nで前の位置までジャンプします。

ここで、複数のファイルで関数を定義、参照するようなプログラムを書いているとき、vimのバッファを使い、複数ファイルを開くことがあると思います。
そのとき、定義した関数、変数がどこで参照されているか、検索できれば非常に便利です。
vimの検索機能はそのファイルに閉じているため、nで次の文字にジャンプし、最終行まで達すると、ファイルの先頭にもどってしまいます。
そこで、検索機能を拡張し、ファイルの最終行に達したら別なバッファに自動で移動するコマンドを作成しました。
vimの検索機能を拡張する
n, N の拡張。拡張といっても、別なキーに割り当てています。
【通常】
「n」:次の文字に移動。最終行に達したらファイルの先頭に戻る。
「N」:前の文字に移動。ファイルの先頭に達したら最終行に戻る。
【拡張後】
「;」:次の文字に移動。最終行に達したら次のバッファに移動する。
「+」:前の文字に移動。ファイルの先頭に達したら前のバッファに移動する。
コード
下記のコードをvimrcに追加します。
function! New_next() abort
let s:now_line_num = line(".")
let s:now_column_num = col(".")
try
normal n
catch
:
endtry
if s:now_line_num > line(".") || s:now_line_num == line(".") && s:now_column_num == col(".")
:bnext
normal G
normal $
try
normal n
catch
:
endtry
endif
endfunction
function! New_prev() abort
let s:now_line_num = line(".")
let s:now_column_num = col(".")
try
normal N
catch
:
endtry
if s:now_line_num < line(".") || s:now_line_num == line(".") && s:now_column_num == col(".")
:bnext
normal gg
try
normal N
catch
:
endtry
endif
endfunction
command Newnext :call New_next()
command Newprev :call New_prev()
nnoremap ; :Newnext<CR>
nnoremap + :Newprev<CR>
解説
function! New_next() abort
「n」を拡張する関数です。
function!の「!」で同じ名前の関数があったときに上書きされます。
abortを付けると、関数内でErrorが起きるとそこで処理が中断されます。
let s:now_line_num = line(".")
let s:now_column_num = col(".")
現在の位置(何行、何列)を取得します。
line(“.”)でカーソルがある位置の行数、col(“.”)で列数が取得できます。
それをlet s:<変数名>に格納しています。
try
normal n
catch
:
endtry
try文で「n」で検索して、マッチする文字があればジャンプし、なければ何もしません。
normal <コマンド> で、ノーマルモードで使うコマンドを実行できます。
if s:now_line_num > line(".") || s:now_line_num == line(".") && s:now_column_num == col(".")
:bnext
normal G
normal $
try
normal n
catch
:
endtry
endif
位置が変わらない もしくは先ほど取得した位置よりも上(ファイルの下まで検索して先頭にもどったとき)であるとき、次のバッファに移動します。
:bnextは次のバッファに移動するExコマンドです。
ここで、バッファを移動してすぐ「n」を使うと、ファイルの先頭にマッチする文字があるとき、その文字を飛ばしてしまうので
norml G, normal $でファイルの末尾に移動してから「n」を使います。
function! New_prev() abort ではこれと逆のことをしています。
command Newnext :call New_next()
command Newprev :call New_prev()
nnoremap ; :Newnext<CR>
nnoremap + :Newprev<CR>
作成した関数を「;」、「+」に割り当てています。
まとめ
今回は、vimのn/Nを拡張する関数を作成しました。
内容はシンプルなので、簡単に理解していただけると思います。
コメント