如何在 vim 中映射具有两种不同行为的相同键?

how to map the same key with two different behavior in vim?

好的,这是我的问题,我想找到一种方法来根据点击次数映射具有两种不同行为的键。 例如,假设我想在按下键 ; 时在行尾添加一个 ; ,如果我按下 两次 将被删除。

注意:分号只是一个例子主要思想是如何切换键

nnoremap ; A;<esc>
nnoremap ;; $x

请注意,这将删除您行中的最后一个字符,无论它是什么。如果你想让它只删除最后一个字符,如果它是分号,你可以这样做:

nnoremap ;; $hf;x

这是可行的,因为如果 f 命令(查找)失败,重新映射将停止 运行,例如如果行尾没有分号。

编辑:

nnoremap ; A;<esc>hh2f;xx 

似乎如你所愿。它当然不是很整洁,但它确实有效。

这就可以了,尽管它有点疯狂...

nnoremap ; :if(getline('.')[col('$')-2]==';')\|exe "norm $x"\|else\|exe "norm A;"\|endif<cr><cr>

它获取当前行的最后一个字符(字符串索引是基于 0 的,col('$') returns 基于 1 的列刚好超过行尾,所以这就是为什么有一个 -2 在那里),将其与分号进行比较,然后从该行中删除或附加最后一个字符。

我不知道为什么最后需要两个<CR>exe 是因为 norm 将所有内容捕获到行尾,因此栏不会分开 "lines" 否则。

编辑更改要求: :-)

如果你想确保一个且只有一个分号出现在一行的末尾并且还要处理尾随空格(包括分号之间的空格),如果你不这样做的话,这实际上比切换最后一个分号要容易得多需要保留尾随空格。这也将确保一个分号之前没有任何空格,如果你真的想在分号之前留下空格删除第一个 \s*.

nnoremap ; :s/\v\s*(;\s*)*$/;/<cr>

如果您仍想切换但需要处理尾随空格,那么我们需要弄清楚您打算如何处理这些尾随空格。我的偏好只是删除它们,这样你就可以继续生活中更简单的事情......如果你愿意,可以将它连接到一个键上,我实际上是在 autocmd.[=20= 中处理 BufWritePre 时这样做的]

:%s/\s\*$//e