一、括号自动完成与加强
1. 括号自动完成
功能描述:当输入(时自动生成(),并使光标指向),系统保持在insert mode分析:当键入(时,只需模拟输入()并使光标回退一个字符即可
代码1:
inoremap ( ()<LEFT>
2. 重复键入括号自动换行
功能描述:在目标一的基础上实现若光标前一字符为(,则自动换行并缩进,而非插入括号分析:要达到该效果,必需通过命令实现,调用命令有<C-O>,<ESC>, <C-R>三种途径
<C-O>对于eol与普通字符的处理方式不一样,所以这里采取ESC进入normal模式,<ESC>离开Insert模式恒回退一个字符
代码2:功能一的命令版
function! ParenOpen() normal! a() startinsert endfunction inoremap ( <ESC>:call ParenOpen()<CR>
代码 3:实现功能2
function! ParenOpen()
let line = getline('.')
let prev_char = line[col('.')-1]
if prev_char == '('
" 添加额外的字符;,以避免vim自动删除空白行
execute "normal! a\<CR>\<ESC>==O;"
return
end
" 同样需要添加;
execute "normal! a(;)\<ESC>i"
"当缩进被删除时,重新缩进当前行
if line == ''
normal! ==$h
end
endfunction
inoremap ( <ESC>:call ParenOpen()<CR>"_cl
3. 忽略重复键入的右括号
功能描术:若当前字符为),则忽略输入的),光标指向下一字符代码4
function! ParenClose()
let line = getline('.')
let char = line[col('.')]
if char == ')'
execute "normal! l"
else
normal! a)
end
endfunction
inoremap ) <ESC>:call ParenClose()<CR>a
4. 配对删除括号
功能描述:当删除(时,若()之间为空时,则连)一起删除分析:目前只能想到map <BS> 一条途径,通过正则判断括号间是否为空
代码5
function! ParenDelete()
let line = getline('.')
let prev_char = line[col('.')-1]
if prev_char == '(' && match(line,'^\s*)',col('.')) != -1
" 使用 cf) 代替df)使光标离开normal时左移一格用以a
normal! cf)
else
execute "normal! a\<BS>"
end
endfunction
inoremap <BS> <ESC>:call ParenDelete()<CR>a
二、代码总览:
function! ParenOpen()
let line = getline('.')
let prev_char = line[col('.')-1]
if prev_char == '('
" 添加额外的字符;,以避免vim自动删除空白行
execute "normal! a\<CR>\<ESC>==O;"
return
end
" 同样需要添加;
execute "normal! a(;)\<ESC>i"
"当缩进被删除时,重新缩进当前行
if line == ''
normal! ==$h
end
endfunction
function! ParenClose()
let line = getline('.')
let current_char = line[col('.')]
if current_char == ')'
execute "normal! l"
else
normal! a)
end
endfunction
function! ParenDelete()
let line = getline('.')
let prev_char = line[col('.')-1]
if prev_char == '(' && match(line,'^\s*)',col('.')) != -1
" 使用 cf) 代替df)使光标离开normal时左移一格用以a
normal! cf)
else
execute "normal! a\<BS>"
end
endfunction
" 函数ParenOpen执行后光标指向;,使用"_cl清除并进入insert模式
inoremap ( <ESC>:call ParenOpen()<CR>"_cl
inoremap ) <ESC>:call ParenClose()<CR>a
inoremap <BS> <ESC>:call ParenDelete()<CR>a
三、使用<C-R>代替<ESC>
<ESC>调用时会导致状态栏,-- 插入 -- 闪烁,修正代码为使用<C-R>代替<ESC>通过与=表达式寄存器实现括号的自动完成功能{/text}
脚本正好可以不进入Normal模式,如果函数中有normal xxx,那么不得不使用<ESC>作为入口了
function! ParenOpen()
let line = getline('.')
let prev_char = line[col('.')-2]
if prev_char == '('
return "\<CR>\<ESC>==O"
end
return "()\<Left>"
endfunction
function! ParenClose()
let line = getline('.')
let current_char = line[col('.')-1]
if current_char == ')'
return "\<Right>"
end
return ')'
endfunction
function! ParenDelete()
let line = getline('.')
let prev_char = line[col('.')-2]
if prev_char == '(' && match(line,'^\s*)',col('.')-1) != -1
return "\<Left>\<C-O>cf)"
end
return "\<BS>"
endfunction
inoremap <silent> ( <C-R>=ParenOpen()<CR>
inoremap <silent> ) <C-R>=ParenClose()<CR>
inoremap <silent> <BS> <C-R>=ParenDelete()<CR>
四、Vim插件Auto Pairs
Auto Pairs是根据此文进一步完善的插件。支持[]{}() ' "的括号自动完成与删除。详见: https://github.com/jiangmiao/auto-pairs
2011-06-11更新
-------------------
inoremap X <C-R>=foo()<CR> 可以用inoremap <expr> X<CR>代替
即上文可以改进为
inoremap <silent> <expr> ( ParenOpen() inoremap <silent> <expr> ) ParenClose() inoremap <silent> <expr> <BS> ParenDelete()
1218

被折叠的 条评论
为什么被折叠?



