• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

VIM中括号的自动补全与删除

很多现代 IDE 都有自动补全配对括号的功能,比如输入了左括号“(”,IDE 就自动在后面添加一个对应的右括号“)”,并且将光标移到括号中间。VIM 虽然没有直接提供这个功能,但要实现其实非常简单,只要在你的 .vimrc 文件中添加下面的内容就可以了:

" 插入匹配括号
inoremap ( ()<LEFT>
inoremap [ []<LEFT>
inoremap { {}<LEFT>

原理很简单,就是将左括号的键映射为一个新的操作,在输入左括号时,让 VIM 立刻输入右括号,同时再将光标左移一格到括号中间。

除了括号的自动补全,有时我们也需要括号的自动删除。比如在输入了左括号后突然发现输错了,本来只需要简单地按一下退格键,将刚才输入的左括号删除就行了,但现在 VIM 自动加了一个右括号,退格键只能删除左括号,这个自动加上右括号还得按一下 DELETE 键才能删掉。
所以,我们还需要一个功能,如果按退格键删除了左括号,那么也要自动地把对应的右括号删除。这个操作使用简单的键盘映射就有点难度了,需要借助函数,如下:

" 按退格键时判断当前光标前一个字符,如果是左括号,则删除对应的右括号以及括号中间的内容
function! RemovePairs()
let l:line = getline(".")
let l:previous_char = l:line[col(".")-1] " 取得当前光标前一个字符
 
if index(["(", "[", "{"], l:previous_char) != -1
let l:original_pos = getpos(".")
execute "normal %"
let l:new_pos = getpos(".")
 
" 如果没有匹配的右括号
if l:original_pos == l:new_pos
execute "normal! a\<BS>"
return
end
 
let l:line2 = getline(".")
if len(l:line2) == col(".")
" 如果右括号是当前行最后一个字符
execute "normal! v%xa"
else
" 如果右括号不是当前行最后一个字符
execute "normal! v%xi"
end
 
else
execute "normal! a\<BS>"
end
endfunction
" 用退格键删除一个左括号时同时删除对应的右括号
inoremap <BS> <ESC>:call RemovePairs()<CR>a

这样就比较完美了。不过在非括号时其实还有个小问题(比如“<行首>a<光标>bcde”这样的情况下,按了退格键后,“a”虽然被删除了,但光标不是移到行首,而是移到 b 的后面),但应该不会对使用造成太大影响。文章地址https://www.yii666.com/article/624797.html

另外,在自动补全了右括号之后,如果用户再输入右括号会怎么样呢?一般来说,比较合理的做法似乎是忽略掉这个后输入的多余的右括号,直接将光标向右移到一格。代码如下:

" 输入一个字符时,如果下一个字符也是括号,则删除它,避免出现重复字符
function! RemoveNextDoubleChar(char)
let l:line = getline(".")
let l:next_char = l:line[col(".")] " 取得当前光标后一个字符
 
if a:char == l:next_char
execute "normal! l"
else
execute "normal! i" . a:char . ""
end
endfunction
inoremap ) <ESC>:call RemoveNextDoubleChar(')')<CR>a
inoremap ] <ESC>:call RemoveNextDoubleChar(']')<CR>a
inoremap } <ESC>:call RemoveNextDoubleChar('}')<CR>a

posted on 2023-07-29 14:28  SOC验证工程师  阅读(753)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3