我试图在 VIM 中映射 Ctrl-y 以删除它在光标下匹配的括号之间找到的任何内容。它有效,但它也会擦除括号。这是我目前使用的:
imap <c-y> <Esc><Right>d%<Insert>
Run Code Online (Sandbox Code Playgroud)
这很好用,除非我说它也删除了光标下的内容(即匹配的括号)。我确实找到了这个:
diX
Run Code Online (Sandbox Code Playgroud)
X
成为您正在寻找的支架;[
,(
,'
,等。
该i
命令的问题是我不想为我定期执行此操作的每个括号映射一个新键,我喜欢%
它匹配光标下的任何内容,无论是字母s
甚至。
有什么办法可以让这个保留括号?
编辑:对不起,举个例子。我有以下文本示例,(* 代表光标):
(*text to be erased between brackets)
"*text to be erased between brackets"
'*text to be erased between brackets'
[*text to be erased between brackets]
{*text to be erased between brackets}
Run Code Online (Sandbox Code Playgroud)
基本上在每个示例中,我希望我的光标位于有问题的括号顶部,然后当我点击Ctrl-y
它时,它从插入模式移动到正常模式,删除光标下括号之间的所有文本或任何内容(在那个点下)因为我转移到正常模式然后<Right>
) 到同一个支架的下一个。
所以以上所有这些都会变成:
()
""
''
[]
{}
Run Code Online (Sandbox Code Playgroud)
无需移除周围的括号。随着d%
括号被删除。
不,%
只匹配一对和字母字符的另一半,例如s
不要成对出现:您只能使用(){}[]''""<>
.
此外,编辑是在正常模式下完成的,而不是插入模式。
在正常模式下,一种可能的顺序是v%holc
:
" []: normal mode cursor, |: insert mode cursor
[(]foo bar baz)
[(foo bar baz)]
[(foo bar baz])
([foo bar baz])
(|)
Run Code Online (Sandbox Code Playgroud)
所以下面的映射应该可以满足你的需求:
nnoremap <C-y> v%holc
Run Code Online (Sandbox Code Playgroud)
扩展此映射以使其适用于任何字符将不那么简单。
我应该补充一点ci(
,朋友们并不像你想象的那么累。
编辑
以下功能(以及相关的普通模式映射)不是很聪明,但完全符合您的要求;随意修改它。它是这样工作的:
如果您点击<C-y>
a ({[<
,当前字符与其兄弟 ( >]})
)之间的文本将被删除,您将进入插入模式。
如果你碰到<C-y>
任何其他字符,当前字符和它在该行上的下一个出现之间的文本将被删除,你将进入插入模式。
功能:
function! InPair()
let l:this_char = getline('.')[col('.')-1]
if this_char == '{' || this_char == '(' || this_char == '[' || this_char == '<'
execute "normal! di" . this_char
else
execute "normal! ldt" . this_char
endif
startinsert
endfunction
Run Code Online (Sandbox Code Playgroud)
映射:
nnoremap <C-y> :call InPair()<CR>
Run Code Online (Sandbox Code Playgroud)
它绝不是完美的,但它应该提供一个很好的起点。