🔛
Vimでインデント幅の単位で左右移動する
この記事はVim駅伝の2023-09-20の記事です。
前回の記事はFohteさんのGhostText: Vim でブラウザのテキストエリアを入力するです。
次回の記事はstaticWagomUさんの闇の力への入門 ddc.vim編です。
Vimの左右移動の改善マッピングを紹介します。
インデントの内部で、インデント幅の単位で左右移動できるようになります。
※2024/03/29追記 quantized_lで無限ループにならないようlastcolの条件を追加
" カーソルがインデント内部ならtrue
function! s:in_indent() abort
return col('.') <= indent('.')
endfunction
" カーソルがインデントとずれた位置ならtrue
function! s:not_fit_indent() abort
return !!((col('.') - 1) % shiftwidth())
endfunction
function! s:quantized_h(cnt = 1) abort
if a:cnt > 1 || !&expandtab
execute printf('normal! %sh', a:cnt)
return
endif
normal! h
while s:in_indent() && s:not_fit_indent()
normal! h
endwhile
endfunction
function! s:quantized_l(cnt = 1) abort
if a:cnt > 1 || !&expandtab
execute printf('normal! %sl', a:cnt)
return
endif
normal! l
let lastcol = col('$') - 1
while s:in_indent() && s:not_fit_indent()
\ && col('.') != lastcol
normal! l
endwhile
endfunction
noremap h <cmd>call <sid>quantized_h(v:count1)<cr>
noremap l <cmd>call <sid>quantized_l(v:count1)<cr>
このマッピングは、h
l
を普通に使った場合およびカウントをつけて使った場合(3h
など)は通常の左右移動となります。また、タブ文字によるインデント(expandtab
が0)の場合でも通常の挙動と同じです。
効果を発揮するのは、以下のように、スペースでインデントされた構文の内部にカーソルがあるときです。このとき、インデント幅(shiftwidth
で算出)に揃うようにカーソルが移動します。具体的には、while
とnormal!
を使って、インデントに揃うまでh
l
を連打しています。
if a > 1
if b > 2
if c > 3
| hogehoge
^ ここにカーソル
endif
endif
endif
インデント内部ではh/lで2字移動する
行頭への移動には^
/0
で移動するのが高速ですが、インデント内部でささっと移動できるとたまに便利です。
普段の移動も邪魔しないので、興味があればお試しください。
Discussion