You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:05:41