Vimのquickfixとlocation listで好きな方法でファイルを開くプラグインを作った
始めに
普段Vimでgrep
した結果をlocation list
に流し込んで使ったりしています。
またLSPでquickfix list
も使ったりしています。
特定のファイルの特定行列にジャンプするのはとても便利ですが、
残念なことにデフォルトのファイルを開く方法は以下2とおりで少ないです。
-
Enter
で現在のウィンドウに表示 -
CTRL-W
+Enter
で横分割したウィンドウに表示
これではとても不便です。たとえば画面が小さいときは新しいタブで編集したいといったケースがあります。
そういったケースを実現するためにqfopen.vim
というプラグインを作りました。
本記事はプラグインの紹介と実現方法について書いていきます。
qfopen.vim
について
基本、ファイルを開くコマンドをユーザーが入力して決めるという使い方になります。
コマンドはsplit
やvsplit
といったものです。
そしてqfopen.vim
はコマンドを提供しておらず、プラグインキーマップを提供して、ユーザーが好きなキーでマッピングするという使い方になります。
自分の場合は次のようにマッピングしています。
augroup qfopen-bufenter
function! s:qfopen_keymap() abort
nmap <buffer> a <Plug>(qfopen-action)
nmap <buffer> <C-v> <Plug>(qfopen-open-vsplit)
nmap <buffer> <C-x> <Plug>(qfopen-open-split)
nmap <buffer> <C-t> <Plug>(qfopen-open-tab)
endfunction
au!
au FileType qf call s:qfopen_keymap()
augroup END
しくみ
getloclist()
と getqflist()
を使って、リスト情報(バッファIDや行数、列数など)を取得できます。
ただ、関数を実行するには現在のウィンドウはquickfix
なのかlocation
なのかを判別する必要があります。
そこでgetwininfo()
を使うことで、現在のウィンドウがlocation
かどうかの判別が可能になります。
location
の場合loclist
は1
になるので、それを判定すればよいのです。
function! s:is_location(winid) abort
let info = getwininfo(a:winid)
if empty(info)
return 0
endif
return info[0].loclist ==# 1
endfunction
これらの関数を使えば、対象ファイルを開いて指定した行と列にジャンプが可能になります。
実際にファイルを開く処理はとてもシンプルで、次のようになっています。
exe opener bufname(info.bufnr)
でウィンドウを開いた後にcall cursor(info.lnum, info.col)
で行列にカーソルを移動させています。
function! qfopen#open(opener) abort
let winid = win_getid()
if s:is_location(winid)
let list = getloclist(winid)
else
let list = getqflist()
endif
let info = list[line(".")-1]
let opener = a:opener
if opener =~# "vne*" || opener =~# "vs*"
let opener = "topleft " .. opener
endif
exe opener bufname(info.bufnr)
call cursor(info.lnum, info.col)
if a:opener !~# "tab*"
call win_execute(winid, "wincmd J")
endif
endfunction
最後に
業務で良くgrepを使うので、不便さがだいぶ改善されました。
みなさんも良ければ使ってみてください。
Discussion