Vim - 将键映射到执行其他操作的函数加上该键的原始功能

Vim - mapping a key to a function which does something else plus the orginal function of that key

目标是让键 j 执行可能复杂的任务 and 移动到下一行(后一个动作只执行就像 j 键的原始功能)。

我最初的尝试是这样映射 j 键:

nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>

(如您所见,我打算让 j 的行为取决于它前面的计数) 并适当地定义函数 MyFun

fu! MyFun(count)
  " do more stuff based on a:count
  normal j
endf

这是错误的,因为点击 j 现在会导致错误 E169: Command too recursive,因为 nnoremap 的非递归性,只要我的推论是正确的,适用于映射 {rhs} 的 "literal" 内容,而不适用于 "inside" 它的任何内容(换句话说, function 主体使用了含义j 在它被调用的那一刻,从而导致无限递归)。

因此我尝试了以下方法

nn , j
nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>
fu! MyFun(count)
  " do more stuff based on a:count
  normal ,
endf

然而这意味着我浪费了密钥 ,。我知道我可以避免浪费映射做

nn <Plug>Nobody j

但是我不知道如何使用 <Plug>Nobody (我的理解确实是它的使用仅在另一个非 nore 映射的 {rhs} 中)。

My initial attempt was to map j key this way

这里使用execute是多余的。够做:

nnoremap j :<C-U>call MyFun(v:count)<CR>

now results in the error E169: Command too recursive

那是因为 normal。要禁止重新映射,您必须使用 "bang"-form: normal! j。请参考 :normal 的文档,其第二段准确描述了您的用例:

If the [!] is given, mappings will not be used. Without it, when this command is called from a non-remappable mapping (:noremap), the argument can be mapped anyway.

此外,注意j通常支持计数,因此2j预计会向下移动两行。因此,您可能应该改为 execute 'normal!' a:count . 'j'