Tabby高亮异常
Tabby 颜色异常的根因并非 Tokyonight 覆盖了高亮,而是 Tabby 在 VimEnter 阶段与 ColorScheme 存在启动时序竞争,导致偶发错过 ColorScheme 事件而未正确刷新动态高亮组(TabbyHL_xxx),将 Tabby 延迟到 VeryLazy 加载后即可彻底规避该问题。
Tabby 偶发渲染异常
问题现象
相关 Profile 信息如下:
VimEnter
├── tabby.nvim 3.33ms
└── tokyonight.nvim 3.21ms
特点:
- 并非每次启动都能复现
- 手动执行
:colorscheme tokyonight后立即恢复正常 - 调整为
VeryLazy加载后问题消失
第一阶段:检查 TabLine 高亮
最初怀疑是 Tokyonight 与 Tabby 的高亮覆盖问题。
查看高亮组:
:hi TabLine
:hi TabLineSel
:hi TabLineFill
异常状态
TabLine xxx guifg=#3b4261 guibg=#1e2030
TabLineFill xxx guibg=#1b1d2b
TabLineSel xxx guifg=#1b1d2b guibg=#82aaff
正常状态
TabLine xxx guifg=#3b4261 guibg=#1e2030
TabLineFill xxx guibg=#1b1d2b
TabLineSel xxx guifg=#1b1d2b guibg=#82aaff
结果发现:
TabLine
TabLineFill
TabLineSel
在正常和异常状态下完全一致。
因此排除:
TabLine 高亮被 Tokyonight 覆盖
的可能性。
第二阶段:检查 Tabby 动态高亮
进一步查看 Tabby 自己生成的高亮组:
:filter Tabby hi
异常状态
TabbyHL_5198424_5198424_NONE xxx cleared
TabbyHL_NONE_5198424_NONE xxx cleared
正常状态
TabbyHL_1447454_1381918_NONE xxx guifg=#16161e guibg=#15161e
TabbyHL_8037111_1381918_NONE xxx guifg=#7aa2f7 guibg=#15161e
此时发现:
异常时:
TabbyHL_* -> cleared
正常时:
TabbyHL_* -> 正常存在
说明问题并不在:
TabLine
而在:
Tabby 动态生成的高亮组
上。
第三阶段:验证 ColorScheme 的影响
当异常出现时,执行:
:colorscheme tokyonight
结果:
Tabby 立即恢复正常
这是整个排查过程中最关键的线索。
排除的错误结论
最开始曾怀疑:
Tokyonight 执行 ColorScheme
↓
清理了 TabbyHL
↓
Tabby 没有重新生成
↓
导致异常
但这个推断与实际现象矛盾。
因为如果真是这样:
:colorscheme tokyonight
应该会再次清理 TabbyHL。
实际结果却是:
执行 ColorScheme 后恢复正常
因此该推断不成立。
最终原因分析
更符合实际情况的流程应该是:
正常启动
Tokyonight
↓
ColorScheme
↓
Tabby ColorScheme Handler
↓
重建 TabbyHL_*
↓
显示正常
异常启动
Tabby Setup
↓
Tokyonight ColorScheme 已触发
↓
Tabby 才完成初始化
↓
Tabby 错过本次 ColorScheme
↓
TabbyHL 未刷新
↓
显示异常
或者:
Tabby Setup
↕
ColorScheme
两者发生竞争条件(Race Condition)。
由于启动时:
tabby.nvim
tokyonight.nvim
都位于 VimEnter 阶段。
再加上插件内部可能存在:
vim.schedule(...)
异步逻辑,因此会出现时序漂移。
最终导致:
Tabby 偶发错过启动阶段唯一一次 ColorScheme 事件
从而无法正确刷新动态高亮组。
最终解决方案
将 Tabby 从:
event = "VimEnter"
调整为:
event = "VeryLazy"
例如:
{
"nanozuki/tabby.nvim",
event = "VeryLazy",
}
问题彻底消失。
为什么 VeryLazy 能解决问题
原始启动流程:
VimEnter
├── tabby
└── tokyonight
存在如下竞争关系:
Tabby Setup
↕
ColorScheme
导致:
Tabby 可能错过 ColorScheme
调整后的流程:
VimEnter
↓
tokyonight
↓
ColorScheme
↓
主题初始化完成
↓
VeryLazy
↓
Tabby Setup
此时:
主题状态已经稳定
Tabby 不再依赖启动阶段的 ColorScheme 回调。
而是直接基于最终主题状态生成:
TabbyHL_*
因此彻底规避了启动竞态问题。
最终结论
本次问题并非:
Tokyonight 覆盖了 TabLine 高亮
也并非:
Tokyonight 清理了 TabbyHL 且未重建
真正的根因是:
Tabby 依赖 ColorScheme 事件刷新动态高亮组
而在原有配置下:
tabby.nvim
tokyonight.nvim
同时位于 VimEnter 阶段。
启动过程中存在时序竞争,导致 Tabby 偶发错过启动时的 ColorScheme 事件,从而无法正确刷新动态高亮组。
具体表现为:
TabLine 正常
↓
TabbyHL_* 状态异常
↓
Tabby 颜色渲染错误
将 Tabby 延迟至:
event = "VeryLazy"
加载后,主题已经完成初始化,Tabby 能直接基于最终主题状态创建动态高亮组,因此问题得到彻底解决。
推荐配置
Tokyonight:
{
"folke/tokyonight.nvim",
lazy = false,
priority = 1000,
config = function()
vim.cmd.colorscheme("tokyonight")
end,
}
Tabby:
{
"nanozuki/tabby.nvim",
event = "VeryLazy",
}
推荐遵循如下加载顺序:
Colorscheme
↓
Statusline
↓
Tabline
↓
Winbar
这种加载方式对于 Tabby、Lualine、Bufferline、Heirline 等 UI 类插件通常最稳定。
- 原文作者:生如夏花
- 原文链接:https://DBL2017.github.io/post/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91/neovim/tabby%E5%81%B6%E5%8F%91%E6%B8%B2%E6%9F%93%E5%BC%82%E5%B8%B8%E6%8E%92%E6%9F%A5%E8%AE%B0%E5%BD%95/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
