VimでVisual Studio Codeのような括弧補完がしたい
1.
{ + Enterで括弧を補完して改行する
inoremap {<Enter> {}<ESC>i<Enter><ESC>x<S-o>
2.
次の文字に依存して括弧を補完するかどうか決める
function! BracketComplement(num) abort let LList = ["(", "[", "{"] let RList = [")", "]", "}"] let pos = col(".") - 1 let str = getline(".") let tmpl = pos == 0 ? "" : str[:pos - 1] let tmpr = str[pos:] let out = "" let flg = 0 "次の文字がOKリストの要素であれば括弧を補完する let OK = [' ', '', ')', ']', '}'] for c in OK if tmpr[0] == c let flg = 1 endif endfor if flg let tmpl = tmpl . LList[a:num] . RList[a:num] else let tmpl = tmpl . LList[a:num] endif let str = tmpl . tmpr call setline('.', str) call cursor(line("."), pos+2) return out endfunction
3.
インサートモード中に閉じ括弧上で閉じ括弧を入力すると括弧から出る。
function! BracketOut(num) abort let List = [')', ']', '}'] let pos = col(".") - 1 let str = getline(".") let tmpl = pos == 0 ? "" : str[:pos - 1] let tmpr = str[pos:] if str[pos] == List[a:num] call cursor(line("."), pos+2) else let str = tmpl . List[a:num] . tmpr call setline('.', str) call cursor(line("."), pos+2) endif return '' endfunctio
4.
2と3の内容をシングルクオーテーション、ダブルクオーテーションにも対応させる。
function! QuotationFunc(num) abort let List = ['"', "'"] let pos = col(".") - 1 let str = getline(".") let tmpl = pos == 0 ? "" : str[:pos - 1] let tmpr = str[pos:] if str[pos] == List[a:num] call cursor(line("."), pos+2) else let flg = 0 "次の文字がOKリストの要素であれば括弧を補完する let OK = [' ', '', ')', ']', '}'] for c in OK if tmpr[0] == c let flg = 1 endif endfor if flg let tmpl = tmpl . List[a:num] . List[a:num] else let tmpl = tmpl . List[a:num] endif let str = tmpl . tmpr call setline('.', str) call cursor(line("."), pos+2) endif return "" endfunction
5.
隣接した括弧の開き記号を消すと同時に閉じ記号も削除する
function! DeleteParenthesesAdjoin() abort let pos = col(".") - 1 let str = getline(".") let parentLList = ["(", "[", "{", "\'", "\""] let parentRList = [")", "]", "}", "\'", "\""] let cnt = 0 let output = "" "カーソルが行末の場合 if pos == strlen(str) return "\b" endif for c in parentLList "カーソルの左右が同種の括弧 if str[pos-1] == c && str[pos] == parentRList[cnt] call cursor(line("."), pos + 2) let output = "\b" break endif let cnt += 1 endfor return output."\b" endfunction
引用:Vimで隣接した括弧の開き記号を消すと同時に閉じ記号も削除するスクリプト - Qiita
これらの関数を文字に割り当てる(これがないと動きません)
inoremap <silent> ( <C-r>=BracketComplement(0)<CR> inoremap <silent> [ <C-r>=BracketComplement(1)<CR> inoremap <silent> { <C-r>=BracketComplement(2)<CR> inoremap <silent> ) <C-r>=BracketOut(0)<CR> inoremap <silent> ] <C-r>=BracketOut(1)<CR> inoremap <silent> } <C-r>=BracketOut(2)<CR> inoremap <silent> " <C-r>=QuotationFunc(0)<CR> inoremap <silent> ' <C-r>=QuotationFunc(1)<CR> inoremap <silent> <BS> <C-r>=DeleteParenthesesAdjoin()<CR>