diagnostics: false-positive unresolved-tag warnings from non-taglink pipe patterns #51

Closed
opened 2026-03-18 00:32:20 +00:00 by barrettruth · 0 comments
barrettruth commented 2026-03-18 00:32:20 +00:00

Problem

The unresolved-tag diagnostic fires on |...| patterns that are not vimdoc taglinks. Running against the full neovim 0.12 runtime corpus (135 files, no external tags) produces 26 spurious unresolved-tag warnings. Two distinct root causes:

1. Blank line after > resets in_code, exposing code content to tag scanning

The parser resets in_code = false on any blank line (intended to handle fenced blocks). But neovim's docs commonly use a blank line between the > trigger and the code block body:

Example: >vim

    if $TERM =~ '^\(rxvt\|screen\|interix\|putty\)\(-.*\)\?$'

The blank line resets in_code, so the indented vim script is parsed as LineKind::Text. scan_inline then finds \|screen\| (vim regex alternation) and emits a spurious warning. Same pattern causes false positives in map.txt (Lua string.format('|%d| ', ...)), dev_tools.txt (histogram bar |@@@...@@@|), and others.

Files affected: tui.txt, map.txt, dev_tools.txt

Some false positives come from lines that are genuinely prose, not code at all:

• title (string|fun(bufnr:integer):string|nil): Title of the window.

The parser reads |fun(bufnr:integer):string| as a taglink. Similarly:

vim.o.winborder='+,-,+,|,+,-,+,|'

emits a warning for |,+,-,+,|.

Files affected: treesitter.txt, options.txt

Full list of false positives (neovim 0.12 corpus)

Tag Count Root cause
|screen|, |iterm| etc. 9 blank-line resets in_code (vim regex in >vim block)
|%d|, |<line1>,<line2>d| 2 blank-line resets in_code (Lua code in >lua block)
|@@@@...@@@@| 1 blank-line resets in_code (profiler output block)
|fun(bufnr:integer):string| 1 pipe in prose type annotation
|,+,-,+,| 1 pipe in option string value
|\\|, |screen\\| etc. 5 | in vim regex / backslash sequences

Expected behaviour

None of the above should produce diagnostics. The parser should either correctly classify these lines as CodeBody (root cause 1) or not parse |...| as a taglink when the content cannot be a valid tag name (root cause 2).

Notes

  • Root cause 1 likely has the higher impact — it corrupts code block detection for any file that uses blank lines for visual spacing inside fenced blocks.
  • Root cause 2 is harder: requires either a tighter tag-name grammar (no parens, no backslashes, no commas) or context awareness.
## Problem The `unresolved-tag` diagnostic fires on `|...|` patterns that are not vimdoc taglinks. Running against the full neovim 0.12 runtime corpus (135 files, no external tags) produces 26 spurious unresolved-tag warnings. Two distinct root causes: ### 1. Blank line after `>` resets `in_code`, exposing code content to tag scanning The parser resets `in_code = false` on any blank line (intended to handle fenced blocks). But neovim's docs commonly use a blank line between the `>` trigger and the code block body: ```vimdoc Example: >vim if $TERM =~ '^\(rxvt\|screen\|interix\|putty\)\(-.*\)\?$' ``` The blank line resets `in_code`, so the indented vim script is parsed as `LineKind::Text`. `scan_inline` then finds `\|screen\|` (vim regex alternation) and emits a spurious warning. Same pattern causes false positives in `map.txt` (Lua `string.format('|%d| ', ...)`), `dev_tools.txt` (histogram bar `|@@@...@@@|`), and others. **Files affected:** `tui.txt`, `map.txt`, `dev_tools.txt` ### 2. Pipes in prose text (type annotations, option strings) parsed as taglinks Some false positives come from lines that are genuinely prose, not code at all: ```vimdoc • title (string|fun(bufnr:integer):string|nil): Title of the window. ``` The parser reads `|fun(bufnr:integer):string|` as a taglink. Similarly: ```vimdoc vim.o.winborder='+,-,+,|,+,-,+,|' ``` emits a warning for `|,+,-,+,|`. **Files affected:** `treesitter.txt`, `options.txt` ## Full list of false positives (neovim 0.12 corpus) | Tag | Count | Root cause | |-----|-------|------------| | `\|screen\|`, `\|iterm\|` etc. | 9 | blank-line resets `in_code` (vim regex in `>vim` block) | | `\|%d\|`, `\|<line1>,<line2>d\|` | 2 | blank-line resets `in_code` (Lua code in `>lua` block) | | `\|@@@@...@@@@\|` | 1 | blank-line resets `in_code` (profiler output block) | | `\|fun(bufnr:integer):string\|` | 1 | pipe in prose type annotation | | `\|,+,-,+,\|` | 1 | pipe in option string value | | `\|\\\|`, `\|screen\\\|` etc. | 5 | `\|` in vim regex / backslash sequences | ## Expected behaviour None of the above should produce diagnostics. The parser should either correctly classify these lines as `CodeBody` (root cause 1) or not parse `|...|` as a taglink when the content cannot be a valid tag name (root cause 2). ## Notes - Root cause 1 likely has the higher impact — it corrupts code block detection for any file that uses blank lines for visual spacing inside fenced blocks. - Root cause 2 is harder: requires either a tighter tag-name grammar (no parens, no backslashes, no commas) or context awareness.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
barrettruth/vimdoc-language-server#51
No description provided.