Skip to content
martintrojerPublic

About

A zero-config markdown (and org) language server and Rust library.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

mdroots

CI crates.io

A full-featured markdown and org language server that works the moment you open a note. Navigation, completion, diagnostics with quick fixes, renames and moves that keep links intact, refactorings and notebook-wide queries, with no init step, no config and no root markers. mdroots finds the notebook a file belongs to, indexes it in the background, and keeps the index in your user cache dir, so the next editor that opens the notebook starts warm.

It understands the link styles your notes already use: zk, Obsidian, marksman, Foam, Dendron, Logseq, org-mode and plain relative paths, in one notebook if you mix them.

Why

  • Instant. The note you opened answers in about 10 ms, whatever the notebook size; whole-notebook answers follow once the index is up.
  • Warm across editors. Every editor on a notebook shares one cache; only changed notes are re-read.
  • Zero config, honest about it. Roots and conventions are detected, and the settings you already made in zk or Obsidian are honoured. mdroots roots NOTE shows the root it picked and why.
  • Safe on big trees. It never walks a remote, virtual or oversized tree; it falls back to the folders you actually open.
  • A library first. The server, the CLI and embedders such as ramble (a TUI reader) share the same Rust API.

Compared with zk and marksman

Time from server start, synthetic notebooks, median of 5 runs (method, caveats and how to reproduce):

10,000 notes mdroots (warm cache) mdroots (cold) zk (indexed) marksman
first answer (go to definition) 11 ms 11 ms 207 ms 4.7 s
full note completion 411 ms 2.3 s 290 ms 4.7 s
broken-link diagnostic 368 ms 2.3 s 218 ms 5.2 s
memory (phys_footprint) 60 MB 60 MB 56 MB 317 MB
setup none none zk index: 109 s none

zk answers fastest once zk index has run; mdroots needs no index step, answers the open note first, and at this size uses about as much memory as indexed zk. At 1,000 notes mdroots uses the least memory (14 MB vs 25 MB for zk and 105 MB for marksman). Numbers are from local main after 0.2.10 (memory).

What it is not

  • Not a note manager. It reads notes and answers questions about them; it never writes to your notes or folders, and fills no templates. Renames, moves, quick fixes and refactorings come back as edits for your editor to apply.
  • Not a daemon. Each editor runs it in-process; the first process on a notebook writes the cache, the others read it.
  • Not a tenant in your notes. Nothing is written into your trees; tool configs are read, never required or written.

Install

cargo install mdroots-cli     # the `mdroots` binary (server + CLI)
cargo add mdroots             # the library

Prebuilt binaries for macOS (Apple silicon) and Linux (x86_64, aarch64) are on the releases page. With mise, which picks the right one for the machine:

mise use -g github:martintrojer/mdroots   # latest release
mise up github:martintrojer/mdroots       # update later

mise holds back releases younger than 24 hours by default (minimum_release_age), so within a day of a release name the version: mise use -g github:martintrojer/mdroots@<version>.

Neovim 0.12+: copy editors/nvim/lsp/mdroots.lua and plugin/mdroots.lua into ~/.config/nvim/ and open a markdown file. The plugin file calls vim.lsp.enable('mdroots') and adds optional mappings; to skip it, call vim.lsp.enable('mdroots') in your own config. :MdrootsInfo shows the root and why (details).

Use

mdroots check notes/                # broken links and anchors; exit 1 on problems (CI)
mdroots search 'rust async' notes/  # notes containing every word
mdroots backlinks notes/a.md        # who links here
mdroots roots notes/a.md            # the notebook root mdroots picked, and why
mdroots lsp                         # the language server on stdio

In your editor

  • Navigate: go to definition on every link form, heading and path:line mention; references and backlinks (of notes and tags); hover previews; highlights; document and workspace symbols; folding.
  • Write: completion of notes, headings, paths and tags; inlay hints with resolved titles; backlink code lenses.
  • Fix: diagnostics for broken links, missing anchors, ambiguous links and frontmatter problems, each with quick fixes (change to the closest note or heading, create the note, pick a candidate).
  • Refactor: rename a note and update every link; moves made in your file tree (willRenameFiles) fix links to moved notes and folders; convert links between wiki and Markdown; turn a selection into a link; extract a selection to a new note.
  • Explore the notebook: orphans, missing backlinks, related notes, full-text search, zk list-style queries, tags and a notebook-wide check, as commands that fill your quickfix list.

The full list, with links to the exact behaviour: docs/features.md.

Learn more

Develop

bash scripts/check.sh   # fmt, clippy -D warnings, all tests

MIT licensed.

About

A zero-config markdown (and org) language server and Rust library.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages