この記事に続いてタブ間を自由に移動する方法について書きましたが、タブ自体を移動させる方法が抜けていました。要するに右の図のように、タブ自体の並びを変えたいわけです。
これを関数を定義して実現しようとしたら思いの外複雑でした。
<Tab>n
で右へ、<Tab>p
で左へ移動します。
<count>
を指定すると一気に遠くまで移動します。例: 3<Tab>n
なら 3 つ右のタブへ移動します。
- 移動できる範囲を超えたときは反対側に移動します。例: 一番右にタブがある状態で
<Tab>n
とすると、一番左へ移動します。
" 現在のタブを右へ移動
nnoremap <Tab>n :MyTabMoveRight<CR>
" 現在のタブを左へ移動
nnoremap <Tab>p :MyTabMoveLeft<CR>
command! -count=1 MyTabMoveRight call MyTabMove(<count>)
command! -count=1 MyTabMoveLeft call MyTabMove(-<count>)
function! MyTabMove(c)
let current = tabpagenr()
let max = tabpagenr('$')
let target = a:c > 1 ? current + a:c - line('.') :
\ a:c == 1 ? current :
\ a:c == -1 ? current - 2 :
\ a:c < -1 ? current + a:c + line('.') - 2 : 0
let target = target >= max ? target % max :
\ target < 0 ? target + max :
\ target
execute ':tabmove ' . target
endfunction
関数の中では、<count>
値に現在の行番号が含まれたりすることがあるんですけど、どういうわけですかね? これがなければもう少し簡潔になったのですが。