强制feedkeys立即粘贴字符

时间:2017-12-12 19:26:33

标签: vim

我正在编写一个插件来增强词汇量(例如自动关闭括号/引号,文件类型特定规则等),并且有些事情对我来说有意想不到的行为。插件规则如下所示:

{"key": "'", "pattern": '...', "keys": "'\<Left>"}

由于我正在收听 InsertCharPre 事件以检测已按下的键,因此使用setline直接编辑缓冲区有一些限制,例如(:help textlock)。所以我必须更改v:char变量或调用feedkeys而不是。 v:char的问题是,它无法使用特殊键(它只是插入一个转义序列),如&#34; \&#34;,&#34; \&#34;和插件中经常使用的其他(但是,#34; \&#34;似乎正确处理)。所以我唯一的选择是feedkeys,但如果key中有keys(见上文),vim会开始递归。我知道<C-v>插入模式映射,但是可能有很多这样的键会使添加新规则变得更复杂。如果没有其他选择,我认为,最好的决定是使用set paste选项,但是作为主题表明我有一些麻烦。

...
set paste

call feedkeys("'\<Left>")

set nopaste
...

似乎首先执行函数的整个主体,然后在paste已经nopaste时将字符插入缓冲区。进一步阅读feedkeys帮助没有成功(我尝试了不同的模式)。你可以尝试这个简单的代码来看看我在说什么:

function! s:Foo()
    startinsert

    call feedkeys("ff")

    stopinsert
endfunction

nnoremap <silent><CR> :call <SID>Foo()<CR>

Enter 后缓冲区不应包含任何文本,但如果您发表评论stopinsert命令,则一切都按预期进行。

Ps:我知道 lexima 插件但不想使用它。我试图解决探索 lexima 源代码的问题,但还有inoremap <expr>我也不想使用它。)。

1 个答案:

答案 0 :(得分:1)

feedkeys()是关于将密钥插入预先缓冲区。来自此缓冲区的密钥仅在当前命令/功能结束后消耗(或者如果您明确读取密钥,例如通过getchar())。这解释了你很难立即处理密钥;该功能并不意味着:-)要立即提交密钥,您可以使用:normal。是的,这不适用于文本锁。

根据您的问题,我认为使用feedkeys() n模式(即不重新映射密钥)应该有效。密钥不会受到用户映射的影响,因此您可以确切地知道哪些(内置)密钥需要进行转义。如果你真的需要支撑你的钥匙,例如更改'paste',您也必须将切换命令放在feedkeys()中:

:call feedkeys(":set paste\<CR>\<Left>:set nopaste\<CR>")