VIM:条件键映射

5
在Vim中,我想在键映射中使用条件语句。
如果光标位于行首,我希望有以下映射:
imap <F1> <ESC>:syntax sync fromstart<CR>i

但是除此之外,这个映射关系是相同的(唯一的区别是最后一个字符)。
imap <F1> <ESC>:syntax sync fromstart<CR>a

在第二个映射中,如果在行的开头(当我们使用 a 回到插入模式时),光标没有回到正确位置。
我正在寻找解决此特定问题的方法,但我也想知道是否可以将条件放入 Vim 键映射中。
谢谢!
1个回答

8

对于您的一般问题,答案是:是的,映射可以包含条件逻辑。您可以通过几种方式实现这一点,最简单的方法是使用<expr>映射。以下是来自vim维基的示例:

inoremap <expr> <Esc>      pumvisible() ? "\<C-e>" : "\<Esc>"

这个例子会根据pumvisible()函数返回的true或false值,有条件地将Esc键映射为C-eEsc。在您的情况下,您需要找到(或定义)一个表达式来确定光标在哪一行。

另一种选择是编写包含所有逻辑的函数,并将键映射到该函数而不是表达式。

在您的特定情况下,这些都不是必要的。只需用<C-o>替换您映射中的<Esc>,并删除末尾的ai即可。

imap <F1> <C-o>:syntax sync fromstart<CR>

在插入模式下,C-o 命令可以让你执行一次普通模式命令,然后返回到插入模式。由于你的普通模式命令不会移动光标,因此应该回到你开始的插入模式。


谢谢@randymorris,非常准确!我有一个类似的情况,无法使用**<C-o>技巧:inoremap <C-Del> <Esc>ldei。在这里,我遇到了最后一个i**的同样问题。你对此有什么想法吗? - samusugiru
这似乎是一个非常奇怪的映射...删除到单词结尾,但保留光标后面的下一个字符。我的唯一建议是尝试编写一个使用“getpos()”和“setpos()”执行所需操作的函数,然后将一个键映射到该函数。 - Randy Morris
不要误会,你对使用vim相对较新吗?我这么问是因为这似乎是人们在使用vim时常遇到的问题。有时候需要一段时间才能适应vim使用的块状光标,实际上光标位置位于高亮字符之前而不是字符本身。老实说,试图通过添加类似这样的映射来解决这个问题将是一场失败的战斗。 - Randy Morris
我经常使用Vim,但并不是高级用户。这只是一个更接近Windows风格的单词删除的hack方法。这个映射在几乎所有情况下都有效,但在行末我真的需要 dea。我没有找到其他能够满足我的需求的解决方案。 - samusugiru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接