我正在编写一个插件来增强词汇量(例如自动关闭括号/引号,文件类型特定规则等),并且有些事情对我来说有意想不到的行为。插件规则如下所示:
{"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>
我也不想使用它。)。
答案 0 :(得分:1)
feedkeys()
是关于将密钥插入预先缓冲区。来自此缓冲区的密钥仅在当前命令/功能结束后消耗(或者如果您明确读取密钥,例如通过getchar()
)。这解释了你很难立即处理密钥;该功能并不意味着:-)要立即提交密钥,您可以使用:normal
。是的,这不适用于文本锁。
根据您的问题,我认为使用feedkeys()
n
模式(即不重新映射密钥)应该有效。密钥不会受到用户映射的影响,因此您可以确切地知道哪些(内置)密钥需要进行转义。如果你真的需要支撑你的钥匙,例如更改'paste'
,您也必须将切换命令放在feedkeys()
中:
:call feedkeys(":set paste\<CR>\<Left>:set nopaste\<CR>")