キーリピート時のCursorMoved autocmdを無効にする、行移動を検出する

動機

CursorMovedに重い処理を割り当てたいとか。
現在いる行に応じて表示を変更したい場合、CursorHoldだとレスポンスが遅いがCursorMovedだと無駄な更新が発生して重いとか。

実装

autocmd CursorMoved,CursorMovedI * call s:on_cursor_move()
function s:on_cursor_move()
	"normal/insertモードでのみ反応するようにしてある。
	"汎用性が必要ならこの辺変更できるようにしたほうがいいですね
	let l:m=mode()
	if m!='n' && m!='i'
		let b:line_changed=0
		let b:cursor_moved=0
		return 
	endif
	if !exists('b:last_visited_line')
		let b:last_visited_line=line('.')
		let b:line_changed=1
		let b:last_cursormove_time=0
		let b:cursor_moved=1
	endif
	"ms単位の時刻を取得 たぶん環境依存 てきとう
	"小数点より上、四桁以下になることがあるので修正した
	let l:ml=matchlist('0000'.reltimestr(reltime()),'\(\d\{4}\)\.\(\d\{3}\)')
	let l:now=str2nr(ml[1].ml[2])
	let l:timespan=now-b:last_cursormove_time
	let b:last_cursormove_time=now
	if l:timespan <= 200
		let b:line_changed=0
		let b:cursor_moved=0
		return 
	endif
	let b:cursor_moved=1
	if b:last_visited_line!=line('.')
		let b:line_changed=1
		let b:last_visited_line=line('.')
	else
		let b:line_changed=0
	endif
endfunction

function Is_line_changed()
	return b:line_changed
endfunction

function Is_cursor_moved()
	return b:cursor_moved
endfunction

解説、使用方法

上記のコードをvimrcに記述。
キーリピートを無効にしたいautocmd定義において

autocmd CursorMoved * if Is_cursor_moved() | <command> | endif

行移動を検出したいautocmd定義部において

autocmd CursorMoved * if Is_line_changed() | <command> | endif

などと記述。