-
-
Notifications
You must be signed in to change notification settings - Fork 7
11.Treesitter
markdown-plus uses Treesitter to understand document structure when it is available, and falls back to regex parsing when it is not. The plugin works either way — Treesitter just makes it more accurate.
- Neovim 0.11+ (for
vim.treesitter.get_node) - The
markdownandmarkdown_inlineparsers
You almost certainly already have these. Neovim ships the Markdown parsers
in its own runtime — :help treesitter lists Markdown under "Nvim includes
these parsers", and both markdown and markdown_inline are bundled. On a
stock Neovim 0.11+ install, there is nothing to do.
Check with:
:checkhealth markdown-plusIf the parsers really are missing (an unusual build, or a stripped-down distribution), install them with a parser manager such as nvim-treesitter:
:TSInstall markdown markdown_inlineNote that :TSInstall is provided by nvim-treesitter, not by Neovim — it won't
exist unless you have that plugin. markdown-plus does not require it.
Both parsers matter. markdown handles block structure (lists, code blocks,
tables, blockquotes) and markdown_inline handles inline structure (bold,
italic, strikethrough, code spans, links). markdown-plus only asks for the
markdown parser directly — markdown_inline is pulled in as an injected
language, so if it is missing, inline format detection quietly drops to regex.
Note
:checkhealth markdown-plus only verifies the markdown parser, so a missing
markdown_inline will not be reported. See Verifying It Works
for how to confirm the injected parser directly.
| Area | What it buys you |
|---|---|
| List detection | Reliable parsing of markers, ordered/unordered, task items and nesting |
| Code block detection | markdown-plus knows exactly where fences begin and end, so the list keys defer inside one |
| Format region detection | Bold, italic, strikethrough and inline code are recognized as regions, not just strings |
Code block detection is the one you feel most. Every shared list key (<CR>,
<Tab>, <S-Tab>, <BS>, o, O) defers inside a fence, so a
- item written inside a ```markdown block is left alone.
Important
That deferral belongs to the list handlers. The formatting toggles have no
fenced-code guard — <localleader>mb inside a fence will still bold the text.
The code block actions operate inside fences deliberately.
If Treesitter is missing, the parser is not installed, or a specific element fails to parse, markdown-plus falls back to regex parsing for that operation. There is no configuration to set and nothing breaks — you just lose some precision in ambiguous documents.
Parsers are cached per buffer against changedtick, so repeated operations
between edits do not re-parse.
Treesitter is what makes the formatting toggles feel smart rather than literal.
Put the cursor anywhere inside a formatted region and the toggle applies to all of it — you do not have to select it or sit on a particular word.
This is **some bold text** here
↑ cursor anywhere in here
Press <localleader>mb →
This is some bold text hereWithout Treesitter this only reliably works on a single word.
Applying a different format to already-formatted text nests it rather than mangling the markers:
This is **bold** text
↑ cursor here
Press <localleader>mi →
This is ***bold*** textThe word is now both bold and italic — markdown-plus wrapped the existing
**bold** region rather than breaking its markers.
markdown-plus works out whether you are nesting a new format or toggling the existing one.
If your visual selection is fully contained inside a formatted region, toggling that format removes it from the whole container rather than splitting it into fragments:
This is **some bold text** here
└─ selected ─┘
Press <localleader>mb →
This is some bold text here==highlight== and ++underline++ are not part of the standard
markdown_inline grammar. They are always detected with regex, even when
Treesitter is installed and working.
In practice this means the region-level smartness above applies to bold, italic,
strikethrough and inline code, but <localleader>m= and <localleader>mu
behave more literally. This is a grammar limitation, not a bug.
:checkhealth markdown-plusIf something looks wrong:
- Confirm the parser loads —
:lua =vim.treesitter.get_parser(0, "markdown") ~= nil - Confirm the buffer filetype —
:set filetype?should reportmarkdown - Confirm Neovim is 0.11 or newer —
:version
You can also inspect the tree directly:
:InspectTreePut the cursor inside some **bold** text and check that the node under it is
strong_emphasis. If it is not, markdown_inline is missing or not injected.
- Troubleshooting
- Usage Examples — the formatting section
:help markdown-plus-treesitter