Summary
Switching window focus between two already-open windows (any window-movement command, e.g. <C-w><C-j> then <C-w><C-l>) can cause the first DiffText-highlighted span in the just-focused window to render with a missing or wrong foreground color, while its background color renders correctly. Reproduces reliably (100% over repeated runs) whenever at least 3 distinct highlight groups (distinct attribute/color combinations) are simultaneously in use somewhere in the window; with only 2, it doesn't reproduce. Does not depend on any color coincidence between groups, confirmed with arbitrary, unrelated colors. Only affects a redraw after a focus change, never the window's first paint.
Environment
COLORTERM=truecolor, termguicolors ondesert colorscheme (once the 3-group condition below is met)Reproduction
# dirA/test.py import os import sys from mypkg.logging import LogLevel, configure_logging from mypkg.other import Thing def f(): pass
# dirB/test.py import os import sys from mypkg.logging import ExtraSymbol, LogLevel, configure_logging from mypkg.other import Thing def f(): pass
vim -c 'DirDiff dirA dirB' (a file-list window plus two diff panes open automatically, since there's only one differing file). With ALE active and a colorscheme that gives ALE diagnostics their own sign/underline color and its ALEVirtualTextError its own color (true of dracula.vim and common in colorscheme+ALE integrations generally), a single real diagnostic on the changed line is enough by itself to supply the 2 extra highlight groups DiffText needs to hit the 3-group threshold; see "What's confirmed" for the fully synthetic, ALE-free version of this condition.<C-w><C-j> then <C-w><C-l> (or equivalent).ExtraSymbol in the just-focused pane renders with a missing or wrong foreground color.Before the focus switch, the same span renders correctly.
Does not reproduce:
DiffText spans in the same redrawvim -d fileA fileB / :vert diffsplit, even replicating the same window count (3, an extra blank window alongside the 2 diff panes), the same 3 distinct highlight groups (via matchadd()), and with ALE explicitly disabled and confirmed inactive (g:ale_enabled=0, no sign-column markers) - so DirDiff's own window/buffer setup contributes something beyond window count and highlight-group count that I haven't isolated furtherWhat's confirmed
synIDtrans(diff_hlID(line, col)) reports the identical resolved highlight at both a broken and a working occurrence of the same span in the same session, so highlight computation is correct; the bytes vim writes differ.
The 3-group threshold, isolated with tmux capture-pane -e -p (preserves the literal escape sequences vim sent), fully generic, no ALE, no dracula:
Only 2 distinct groups active (DiffText + one other), correct:
hi MyDiffText guifg=#000000 guibg=#FF00FF gui=NONE
hi! link DiffText MyDiffText
hi SomeGroup guifg=#FF5555 guibg=NONE gui=undercurl
...import [38;2;0;0;0m[48;2;255;0;255mExtraSymbol, [38;2;255;184;108m[48;2;40;42;54mLogLevel...
Foreground set to 0;0;0 (black), then background to 255;0;255 (magenta), then the text.
3 distinct groups active (DiffText + two others), broken:
hi MyDiffText guifg=#000000 guibg=#FF00FF gui=NONE
hi! link DiffText MyDiffText
hi SomeGroup guifg=#FF5555 guibg=NONE gui=undercurl
hi OtherGroup guifg=#FFB86C guibg=NONE gui=undercurl
...import [38;2;255;184;108m[48;2;255;0;255mExtraSymbol[38;2;0;0;0m, ...
Foreground is 255;184;108 (the third group's color, wrong, should be 0;0;0), applied before the background switch instead of after; the correct foreground only appears after ExtraSymbol, on the comma.
Reporting the byte-level evidence because it holds regardless of any further reduction.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
does a ctrl-l or :redraw fixes it? Can you reproduce in a GUI?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
The other foreground covers only "ExtraSymbol", not the comma after it,
which is still part of the DiffText span. That fits a highlight on the
name itself on top of DiffText: Vim then uses the foreground of that
highlight and the background of DiffText.
"ExtraSymbol" is an unused import in your example, and ALE lints the
buffer when the window gets focus and highlights such a name. Does it
still happen in the DirDiff setup with let g:ale_enabled = 0? And what
do :echo getmatches() and :echo prop_list(line('.')) give on that
line after the focus switch?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
does a
ctrl-lor:redrawfixes it? Can you reproduce in a GUI?
:redraw and :redraw!: tested both, neither changes the result.
GUI: reproduces. MacVim, real OS-level keystrokes via macOS System Events (not vim's own --remote-send), screenshots below.
Does it still happen in the DirDiff setup with
let g:ale_enabled = 0? And what do:echo getmatches()and:echo prop_list(line('.'))give on that line after the focus switch?
With g:ale_enabled = 0 (same DirDiff setup, unmodified dracula.vim, otherwise identical): does not happen.
getmatches() on that line, before the focus switch: [].
After the focus switch, it includes:
{'group': 'ALEWarning', 'id': 1004, 'priority': 10, 'pos1': [4, 27, 11]}
Line 4, column 27, length 11: that's "ExtraSymbol".
prop_list(line('.')) on that line, after the focus switch: [].
The original report's "3 or more distinct highlight groups" condition was measured with ALE active throughout, never tested against whether ALE placing this match was itself the variable. I'm withdrawing that framing.
Is a :match's foreground meant to take priority over DiffText's here?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Is a :match's foreground meant to take priority over DiffText's here?
Yes, the match's foreground is meant to win. A match is drawn on top
of the diff highlighting: whatever the match group sets wins, and the
rest comes from DiffText. That is why the background stays magenta.
The orange foreground comes from dracula, not from ALE or Vim.
ALEWarning is linked to DraculaWarnLine, which only asks for an
orange undercurl. But unless g:dracula_full_special_attrs_support is
set, dracula also copies the undercurl color into guifg, so terminals
without undercurl still show something. That gives
guifg=#FFB86C, i.e. the 255;184;108 in your capture.
dracula only turns that off in the GUI by default. In a terminal
that can draw a colored undercurl, set both the termcap entries and
the dracula flag, before the colorscheme is loaded:
let &t_Cs = "\e[4:3m"
let &t_Ce = "\e[4:0m"
let &t_8u = "\e[58:2::%lu:%lu:%lum"
let g:dracula_full_special_attrs_support = 1
Then it should look the same as in MacVim. Otherwise
let g:ale_set_highlights = 0 drops these matches altogether.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
@h-east that's the whole explanation, and both routes you named fix it, verified:
With the termcap + flag, before the colorscheme loads:
let &t_Cs = "\e[4:3m"
let &t_Ce = "\e[4:0m"
let g:dracula_full_special_attrs_support = 1
ExtraSymbol now renders with a colored undercurl and dark text on DiffText's orange background, same as MacVim.
g:ale_set_highlights = 0 also fixes it, at the cost of losing ALE's per-token highlighting entirely.
Not a vim bug. Thanks for tracing it all the way down.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()