Vim でプログラムを書くとき、カッコの補完があればいいなと思っていたので自作。
^G^Gで開き括弧と閉じ括弧を自動に補完する。
inoremap <C-g><C-g> <C-r>=CompleteParent()<CR>
function! CompleteParent() let str = getline('.') let pos = col('.') if pos == 1 || pos == col('$') || str[(pos - 1) :] !~ ')' \ || (str[0: (pos - 2)] !~ '(' && str[-1:] == ')') call setline('.', str .')') else let i = 0 let k = 0 while i < 100 let k = match(str[0: (pos - 2)], '(', k + 1) if k == -1 break endif let i += 1 endwhile let list = split(str[(pos - 1) :], ')', 1) let list[-(i + 2)] .= ')' call setline('.', str[0: (pos - 2)] .join(l:list, ')')) endif return "(\<left>" endfunction
余談 : col('.')の戻り値について。
Insertモードから<C-o>:でコマンド行に入っている状態でのcol('.')は、カーソル位置が「行末」のときも「行末の1文字前」のときも、col('$')と同じ値を返す。(コマンド実行時にInsertモードを抜けているため。)
Insertモード中にcol('.')の戻り値を扱いたいときは<C-r>=で関数を直接呼び出す。
戻り値をカーソル位置に挿入したくないなら:return ""
他のモード内でカーソル位置が行末か行末でないかを判断するような関数は存在しない。