Vim で名前を付けてウィンドウを split する
元ネタ:Vimで画面分割して指定行に移動する - daisuzu's notes
上記の記事を読んでいて、
『既にウィンドウが開いていれば split しないでウィンドウにさせればいいんじゃないかなー』
と思ったのがきっかけ。
元々、ウィンドウ名をどうにかしたいとはいましたし。
ってことで、バッファ名のようにウィンドウ名を処理するような Vim script を書いてみました。
[ソース]
function! s:is_number(str) return (type(a:str) == type(0)) || (a:str =~ '^\d\+$') endfunction function! s:winnrlist(...) return a:0 \ ? range(1, tabpagewinnr(a:1, "$")) \ : range(1, tabpagewinnr(tabpagenr(), "$")) endfunction function! s:winlist(...) let tabnr = a:0 == 0 ? tabpagenr() : a:1 return map(s:winnrlist(tabnr), '{ \ "winnr" : v:val, \ "name" : gettabwinvar(tabnr, v:val, "name") \ }') endfunction function! s:winnr(...) return a:0 == 0 ? winnr() \ : a:1 ==# "$" ? winnr("$") \ : a:1 ==# "#" ? winnr("#") \ : !s:is_number(a:1) ? (filter(s:winlist(), 'v:val.name ==# a:1') + [{'winnr' : '-1'}])[0].winnr \ : a:1 endfunction function! s:winname(...) return a:0 == 0 ? s:winname(winnr()) \ : a:1 ==# "$" ? s:winname(winnr("$")) \ : a:1 ==# "#" ? s:winname(winnr("#")) \ : !s:is_number(a:1) ? (filter(s:winlist(), 'v:val.name ==# a:1') + [{'name' : ''}])[0].name \ : (filter(s:winlist(), 'v:val.winnr ==# a:1') + [{'name' : ''}])[0].name endfunction function! s:split(cmd, name) let winnr = s:winnr(a:name) if winnr == -1 silent execute a:cmd let w:name = a:name else silent execute winnr . "wincmd w" endif endfunction " ウィンドウ名を指定して split する " 既に存在するウィンドウ名であればそこに移動する command! -count=0 -nargs=1 \ Split call s:split("split", <q-args>) | if <count> | silent execute <count> | endif " 行番号を指定して preview ウィンドウを開く " 123ss nnoremap <silent> ss :<C-u>execute v:count."Split preview"<CR>
[使い方]
" 名前を付けてウィンドウを分割する " 既に存在しているウィンドウ名であれば、分割しないでカーソルが移動するだけ :Split mami " ウィンドウを分割して行番号に移動するキーマッピング " 機能的には元ネタになった機能と同様の処理 " 123 行目に移動する場合のキーマッピング 123ss
いろいろと書いてありますが、重要なのは :Split コマンドの部分。
ガーッと書いてみたけど思ったよりも応用が効きそうな感じ。
例えば、ファイルを開く場合もウィンドウ名を指定して開くことでレイアウトを維持する云々とか。
別ウィンドウを開いて検索とかも出きそう。
ただ、あくまでもウィンドウを対象としているのでバッファが違っていると変な挙動になりそう。
次はタブ名とかどうにかしたいなぁ。