问题
Picker 弹窗在 Vim 9.2 上输入时整个弹窗会闪烁,但在 Vim 9.1 上完全正常。
环境
- Vim 9.2 — 闪烁
- Vim 9.1 — 正常
- 两台机器使用相同终端模拟器,
lazyredraw 均为 0
复现
- 使用 Vim 9.2
- 打开 Picker(
<C-p> 或对应映射)
- 输入任意字符
整个弹窗(input + results)在每次按键时可见闪烁。
最小复现(无需 yac.vim)
let g:tp = popup_create(repeat(['test'], 10), #{
\ line: 5, col: 5,
\ minwidth: 40, maxwidth: 40,
\ minheight: 10, maxheight: 10,
\ border: [1,1,1,1],
\ filter: {id, key -> key == "\<Esc>"
\ ? [popup_close(id), 1][1]
\ : [popup_settext(id, repeat([key .. ' pressed'], 10)), 1][1]},
\ })
在 Vim 9.2 上按键时 popup 闪烁,9.1 上不闪。
分析
问题出在 Vim 9.2 的 popup 渲染管线变更。9.2 新增了 popup opacity 支持(patch 9.2.0017),可能改变了 popup 的重绘路径,导致每次 popup_settext() / popup_setoptions() 调用时 popup 区域会被先清除再重绘,产生可见的闪烁。
已尝试的 workaround(均无效)
set lazyredraw 包裹批量更新 — 无效
- 合并
win_execute() 调用 — 将 5-10 次 win_execute() 合并为 1 次 — 无效
- 使用 text properties — 将高亮嵌入
popup_settext() 调用实现原子更新,消除 clearmatches() + matchaddpos() 的中间无高亮状态 — 无效
以上所有优化均无法解决闪烁,说明问题在 Vim 9.2 内部的 popup 重绘机制,而非调用次数或调用方式。
相关 Vim issues
- vim/vim#4458 — Flicker in popup window(maintainer 确认 "when there is a popup all text is redrawn every time")
- vim/vim#11718 — Implement flicker free redraw and scroll(BSU/ESU synchronized updates)
- patch 9.1.1621 — 修复 cmdline popup menu 闪烁,通过推迟 screen update
当前状态
等待 Vim 上游修复。如果后续找到有效的 workaround 会更新此 issue。
问题
Picker 弹窗在 Vim 9.2 上输入时整个弹窗会闪烁,但在 Vim 9.1 上完全正常。
环境
lazyredraw均为 0复现
<C-p>或对应映射)整个弹窗(input + results)在每次按键时可见闪烁。
最小复现(无需 yac.vim)
在 Vim 9.2 上按键时 popup 闪烁,9.1 上不闪。
分析
问题出在 Vim 9.2 的 popup 渲染管线变更。9.2 新增了 popup opacity 支持(patch 9.2.0017),可能改变了 popup 的重绘路径,导致每次
popup_settext()/popup_setoptions()调用时 popup 区域会被先清除再重绘,产生可见的闪烁。已尝试的 workaround(均无效)
set lazyredraw包裹批量更新 — 无效win_execute()调用 — 将 5-10 次win_execute()合并为 1 次 — 无效popup_settext()调用实现原子更新,消除clearmatches()+matchaddpos()的中间无高亮状态 — 无效以上所有优化均无法解决闪烁,说明问题在 Vim 9.2 内部的 popup 重绘机制,而非调用次数或调用方式。
相关 Vim issues
当前状态
等待 Vim 上游修复。如果后续找到有效的 workaround 会更新此 issue。