Language server protocol (LSP)¶
rumdl includes a built-in LSP server for real-time Markdown linting in your editor.
Starting the server¶
# Default: use stdio (for editor integration)
rumdl server
# With custom config
rumdl server --config .rumdl.toml
# Verbose logging (for debugging)
rumdl server --verbose
# TCP mode (for debugging)
rumdl server --port 9257
Capabilities¶
The rumdl LSP server provides:
- Diagnostics: Real-time linting as you type
- Code actions: Quick fixes for auto-fixable issues
- Document formatting: Format entire document (
rumdl fmt) - Range formatting: Format selected text
- Completion: Language suggestions for fenced code blocks
Code block language completion¶
When typing a fenced code block, rumdl provides intelligent completions for language labels.
Type ```py and completions will appear for languages starting with "py" (Python, etc.).
The completion uses GitHub Linguist data (799+ languages) and respects your MD040 configuration:
[MD040]
# Only suggest these languages
allowed-languages = ["Python", "JavaScript", "Rust"]
# Or exclude specific languages
disallowed-languages = ["HTML"]
# Prefer specific aliases
preferred-aliases = { Python = "py", JavaScript = "js" }
Features:
- Triggers after
```or~~~fence markers - Supports extended fences (4+ backticks for nested blocks)
- Filters by
allowed-languagesanddisallowed-languages - Prioritizes
preferred-aliasesin results - Shows canonical language name in completion details
Editor configuration¶
Neovim (nvim-lspconfig)¶
Add to your Neovim configuration:
-- if you do not use nvim-lspconfig, add this rumdl config
vim.lsp.config("rumdl", {
cmd = { "rumdl", "server" },
filetypes = { "markdown" },
root_markers = { ".git" },
})
vim.lsp.enable("rumdl")
Helix¶
Add to languages.toml:
[language-server.rumdl]
command = "rumdl"
args = ["server"]
[[language]]
name = "markdown"
language-servers = ["rumdl"]
formatter = { command = "rumdl", args = ["check", "--fix", "--stdin"] }
Note: The
[[language]]block replaces the Helix defaults. Add any other language servers you use (e.g.,marksman) to thelanguage-serverslist. rumdl was merged into Helix's built-in config after the 25.07.1 release, so manual configuration will not be needed once the next Helix version ships.
VS Code¶
Install the rumdl VS Code extension from the marketplace.
The extension automatically manages the LSP server.
Zed¶
Add to your Zed settings:
{
"lsp": {
"rumdl": {
"binary": {
"path": "rumdl",
"arguments": ["server"]
}
}
},
"languages": {
"Markdown": {
"language_servers": ["rumdl"]
}
}
}
Sublime Text (LSP package)¶
Add to LSP settings (Preferences > Package Settings > LSP > Settings):
{
"clients": {
"rumdl": {
"enabled": true,
"command": ["rumdl", "server"],
"selector": "text.html.markdown"
}
}
}
Emacs (lsp-mode)¶
Add to your Emacs configuration:
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-language-id-configuration '(markdown-mode . "markdown"))
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("rumdl" "server"))
:major-modes '(markdown-mode)
:server-id 'rumdl)))
Emacs (eglot)¶
Add to your Emacs configuration:
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(markdown-mode . ("rumdl" "server"))))
Configuration¶
The LSP server uses the same configuration as the CLI. It automatically discovers .rumdl.toml or pyproject.toml in your project.
You can override the config path:
Or use built-in defaults only:
Troubleshooting¶
Enable verbose logging¶
This outputs detailed logs to stderr, which most editors capture in their LSP logs.
Check server is working¶
Test the server manually:
You should see a JSON response with server capabilities.
Common issues¶
Diagnostics not appearing:
- Ensure the file is recognized as Markdown (check file extension)
- Check that rumdl is in your PATH
- Look at your editor's LSP logs for errors
Wrong config being used:
- Use
--verboseto see which config file is loaded - Use
--configto specify an explicit path - Use
--no-configto ignore all config files