Vim插件测试:如何捕获job_start输出的echon消息?
这个问题我之前在测试自己的Vim插件时也踩过坑,尤其是Vim8引入异步job之后,原来靠redir捕获输出的方法直接失效了。下面分享几个我亲测有效的原生VimScript方案,帮你搞定这个测试需求:
可行解决方案
1. 临时重定义echon命令主动捕获输出
这是最可靠的方案,能直接拦截所有echon调用——不管是同步执行的代码,还是异步job里的逻辑都能覆盖到。
测试时我们可以先备份原生echon的行为,再替换成自定义命令,把输出内容存到变量里,同时保留原有的消息显示效果:
" 初始化存储捕获内容的变量 let g:captured_echon = [] " 重定义echon:先记录消息,再执行原生逻辑 command! -nargs=* -override Echon call add(g:captured_echon, <f-args>) | execute('echon ' . <f-args>) " 触发你的插件操作(比如启动异步job的函数) call your_plugin_trigger_function() " 等待异步job完成(需要在插件的close_cb里设置g:job_finished = 1) let g:job_finished = 0 while !g:job_finished sleep 5m " 短暂休眠避免占用过多资源 endwhile " 现在g:captured_echon里就是所有echon输出的内容了 echo g:captured_echon " 测试完成后恢复原生echon命令 command! -override Echon echon <f-args> unlet g:captured_echon
2. 用messages命令提取历史消息
Vim自带的messages命令会记录所有输出到消息区的内容,包括echon的输出。这个方法不需要修改原有命令,但要注意提前清空历史消息,避免其他操作的输出干扰测试结果。
" 测试前清空所有历史消息 execute('messages clear') " 执行插件的异步job操作 call your_plugin_start_job() " 等待job完成(同样依赖close_cb设置的标志位) let g:job_done = 0 while !g:job_done call feedkeys("\<C-L>", 'n') " 刷新界面避免阻塞 sleep 10m endwhile " 获取所有消息并过滤掉错误提示(错误消息通常以E开头加数字) let all_messages = split(execute('messages'), "\n") let echon_output = filter(all_messages, 'v:val !~# "^E\d\+:"') " echon_output就是捕获到的纯消息内容 echo echon_output
额外提示
- 针对异步job的场景,必须等待job完全执行结束才能捕获消息——可以在插件的
close_cb回调里设置一个全局标志位,测试脚本通过循环等待这个标志位来确保job完成。 - 如果插件用
echohl设置了消息颜色,捕获到的内容会包含ANSI颜色代码(比如\e[31m),如果需要纯文本内容,可以用substitute去掉这些代码:let plain_text = substitute(captured_message, '\e\[[0-9;]*m', '', 'g')
内容的提问来源于stack exchange,提问作者alfredodeza
相关产品推荐
相关产品推荐

