Skip to content

fix(inline): remove hl_mode combine from link extmarks to prevent ghost underlines#516

Closed
ImmanuelHaffner wants to merge 2 commits into
OXY2DEV:mainfrom
ImmanuelHaffner:fix-inline-ghost-underlines
Closed

fix(inline): remove hl_mode combine from link extmarks to prevent ghost underlines#516
ImmanuelHaffner wants to merge 2 commits into
OXY2DEV:mainfrom
ImmanuelHaffner:fix-inline-ghost-underlines

Conversation

@ImmanuelHaffner

Copy link
Copy Markdown
Contributor

The concealing extmark in link_hyperlink and link_image hides the ](https://…) portion of a link/image, which can span hundreds of bytes. With hl_mode = "combine" on that extmark, the virtual-text highlight (e.g. the link underline) bleeds across every concealed byte — so when the hidden URL is long enough to soft-wrap, Neovim's phantom screen rows get painted with "ghost" underlines/highlights.

Removing hl_mode = "combine" from the two conceal extmarks fixes it. (Comments added explaining why it must not be re-added.)

A fixture (test/inline_conceal_wrap.md) is included with a vim: set wrap linebreak modeline; open it in a narrow window and confirm no stray underline appears on wrapped rows below the link labels.

…st underlines

Remove hl_mode="combine" from the concealing extmarks in link_hyperlink and link_image. When a link URL is concealed, the virtual text highlight (e.g. underline) bled across every concealed byte, producing ghost underlines on phantom screen rows created by soft-wrap of the hidden text.
Repro for the hl_mode="combine" ghost-underline fix. Long concealed
link/image URLs that soft-wrap create phantom screen rows; with
hl_mode="combine" on the conceal extmark, the link highlight bleeds
across every concealed byte and paints those rows. Open in a narrow
window (the file carries a 'vim: set wrap linebreak' modeline) and
confirm no stray underline/highlight appears on wrapped rows below the
link labels. Covers long hyperlinks, images, links in narrow table
cells, and several concealed links on one wrapping line.
@OXY2DEV

OXY2DEV commented Jul 3, 2026

Copy link
Copy Markdown
Owner

This is considered an unresolvable issue as not using hl_mode = "combine" breaks rendering when using certain combinations(mainly when non whitespace characters are used as paddings).

And the issue doesn't fully resolve with this as Vim's matchparen would still cause the highlights to bleed occasionally.

Until Neovim has resolved conceal related issues I don't think changing the hl_mode is the most desirable solution.

@OXY2DEV OXY2DEV closed this Jul 3, 2026
@ImmanuelHaffner

Copy link
Copy Markdown
Contributor Author

What we make this a strict opt-in through config? I use it in my fork, and it works well. Definitely better than status quo.

We could have in the conf some

experimental = {
  link_conceal = 'combine',
}

or similar.

@OXY2DEV

OXY2DEV commented Jul 3, 2026

Copy link
Copy Markdown
Owner

@ImmanuelHaffner What colorscheme are you using? I can't reproduce the issue on catppuccin, tokyonight & cyberdream.

@ImmanuelHaffner

Copy link
Copy Markdown
Contributor Author

To reproduce set wrap, put cursor line on a cell with concealed text wrapping, e.g. long URL.
I can repro this independent of colorscheme (tested default and catpuccin and my night-owl fork).

It's also unaffected by set cursorline.

And i just realized that my attempted fix doesn't fix anything by itself. My larger table rendering PR doesn't have this issue. I need to see if i can file a localized, well justified fix for this issue without opening again this can of worms of table rendering.

image image

@ImmanuelHaffner

Copy link
Copy Markdown
Contributor Author

The issue manifests only on text on the cursor line, when set wrap is enabled, and when the table row is too wide for the window and is wrapped.
Only under these circumstances does the issue manifest.
Further, one needs to be in insert or visual mode or have hybrid mode enabled.

@ImmanuelHaffner

Copy link
Copy Markdown
Contributor Author

Nailed it, the issue is linebreak. with set nolinebreak, the odd behavior is gone. and the ghost lines themselves are a neovim peculiarity that need fixing in the editor, IIUC.

@ImmanuelHaffner ImmanuelHaffner deleted the fix-inline-ghost-underlines branch July 3, 2026 22:21
@OXY2DEV

OXY2DEV commented Jul 4, 2026

Copy link
Copy Markdown
Owner

@ImmanuelHaffner I still can't reproduce the issue on my machine.

Screenshot_2026-07-04-07-12-04-78_84d3000e3f4017145260f7618db1d683

Please create a repro.lua with the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants