Landin editor and IDE support discuss source

Highlighting Landin

One scanner, several renderings. landin_highlight.py holds the lexical surface of the language — the reserved words, the token shapes, and the little state a line cannot decide on its own — and everything that colours Landin is a rendering of that file rather than another scanner that drifts away from it.

artifactfeedsstate
landin_highlight.pythe scanner itself; standard library only, no output formathere
landin_pygments.pyPygments: sourcehut's blob view, Sphinx, MkDocs, pygmentizehere
docs/site/render_html.pythe reading copies at www.701.dev, as HTML spansimports the scanner
textmate/VS Code, VSCodium, Cursor, Windsurf, TextMate, Shiki and bat; importable by JetBrains IDEsgenerated grammar plus extension
tree-sitter/the incremental concrete-syntax grammar and canonical queriesgenerated C parser and corpus
nvim/, helix/, zed/tree-sitter editor packagesready-to-install adapters
vim/, emacs/native Vim and Emacs packages, including Emacs tree-sitter modeready-to-install adapters
sublime/, visual-studio/, jetbrains/TextMate consumers with native packaging or installation instructionsready-to-install adapters
eclipse/Eclipse Generic Editor through its TM4E integrationimportable adapter
notepad-plus-plus/, nano/, kate/widely used and lightweight native syntax definitionsgenerated adapters

The two grammars are the reason this directory exists rather than the scanner living under docs/site/: the reading copies are a consumer of the language's highlighting, not the owner of it.

Installing editor and IDE support

Clone or download the repository, then use the package for the editor in the table. Every package associates the .ldn suffix with Landin; the structural packages also provide editor features such as indentation, folds, text objects or an outline where their host supports them. Helix, Zed, and Emacs fetch the tree-sitter grammar at the fixed commit recorded in their packages, matching the queries and mode rules in this checkout. When changing the grammar or queries, commit those changes first, then update all three revisions to that commit before distributing the packages. highlight/test_adapters.py checks the full commit IDs and equality in every distribution. In a Git checkout with the pinned commit available, it also compares the shipped grammar and queries against that commit. A shallow checkout missing the commit reports that it skipped this comparison; fetch the commit for the full check. The gate's editor-grammar job checks out full history so that it always runs the comparison.

editor or toolpackageinstallation
Zedhighlight/zedOpen Extensions, choose Install Dev Extension, and select this directory.
VS Code, VSCodium, Cursor, Windsurfhighlight/textmateRun npm install, npm run package:check, and npx vsce package; then choose Install from VSIX in the editor.
Neovimhighlight/nvimRun make -C highlight/nvim, then add the directory to runtimepath or use it as a local plugin.
Helixhighlight/helixMerge languages.toml, copy the query directory into the matching runtime directory, then run hx --grammar fetch and hx --grammar build.
Vimhighlight/vimCopy the directory to ~/.vim/pack/landin/start/landin, or point a package manager at it.
Emacshighlight/emacsPut the directory on load-path and require landin-mode; on Emacs 29+, run M-x landin-ts-install-grammar to enable the tree-sitter mode.
Sublime Texthighlight/sublimeCopy the directory to Packages/Landin. For the language server, merge LSP-refine.sublime-settings into the LSP package's settings.
Visual Studiohighlight/visual-studioRun install.ps1 in PowerShell, then reopen the file or restart Visual Studio.
JetBrains IDEshighlight/textmateEnable TextMate Bundles, import this directory as a bundle, and map *.ldn if necessary.
Eclipsehighlight/textmateWith TM4E installed, import syntaxes/landin.tmLanguage.json and open .ldn files in the Generic Editor.
Notepad++highlight/notepad-plus-plusFrom Language, open User Defined Language and import Landin.xml, or copy it to the user-defined-language directory.
Katehighlight/kateInstall landin.xml as a user syntax-highlighting definition, and merge lsp-client.json into the LSP Client plugin's settings for the language server.
Nanohighlight/nano/landin.nanorcInclude the syntax file from the user's nanorc.
Pygments, Sphinx, MkDocshighlightRun pip install ./highlight; the lexer registers the landin and ldn aliases and the .ldn suffix.

The language server

refine lsp is the compiler's language server: diagnostics, go to definition, hover, formatting and quick fixes from the compiler's own stages, as docs/server.md describes. The Neovim, Helix, Emacs, Zed, VS Code, Vim, Sublime Text and Kate packages each start it, with refine on the editor's path; each package's README says how, and test_adapters.py holds every one of them to refine lsp. test.sh starts it through Neovim and Emacs when LANDIN_REFINE names a compiler.

The TextMate grammar can also be loaded directly by TextMate, Shiki and bat. The package-specific README in each directory records any additional host details. These are repository packages rather than editor-marketplace releases, so installation is deliberately local for now.

What the scanner is not

It is not a parser. It is a token scanner with a symbol table collected from the file itself, which is how a name the file declares reads the same everywhere it is used — the whole reason the Pygments lexer takes a file rather than a line.

What it cannot do is tell the set of [0410] from a variable called set. The contextual words — from, of, at, set, range, option, link, align — are coloured by position, and some of them will be coloured wrongly. A regex cannot fix that. The tree-sitter grammar handles the enabled structural surface, including contextual lenof and of, the layout(c), layout(optimal), layout(packed, u32), packed positions, encoded unions and link(symbol: ...) annotations, and extern(c) function types, while c, optimal, layout, link, and symbol remain ordinary identifiers outside those positions. It remains deliberately non-normative and tolerant enough for incomplete editor buffers.

check.py keeps its own list of reserved words on purpose. That one is about legality and this one is about colour, they have drifted apart before, and the comment at the top of check.py explains why they are allowed to.

The Pygments lexer

Installed, it registers itself so Pygments finds it by name, by alias, and by the .ldn suffix:

pip install ./highlight
pygmentize -l landin file.ldn
python3 -m landin_pygments file.ldn     # or straight to the terminal

Pygments is a dependency of the lexer, never of the scanner, so docs/site/render_html.py keeps rendering the documentation with nothing but the standard library.

Nothing installs this automatically, and the package is unreleased: the version in pyproject.toml says only that, and ROADMAP.md decides when it becomes a claim.

Generating and checking packages

The TextMate, Vim, Nano, Kate and copied query files are deterministic renderings. Regenerate or verify them with:

python3 highlight/generate.py
python3 highlight/generate.py --check
./highlight/test.sh                 # isolated: only highlight/ fixtures, see
                                    # highlight/tests/README.md
./highlight/test.sh --integration   # also parse compiler and core fixtures
LANDIN_REFINE=/absolute/path/to/refine ./highlight/test.sh --lsp-emacs
                                    # require Emacs to launch refine lsp

The default test never builds or invokes the compiler. Its mandatory path is standard-library-only: it scans the lexical fixture, exercises the TextMate patterns, parses every manifest and generated format, checks file associations and verifies copied artifacts byte for byte. If Pygments, tree-sitter, Vim, Neovim, Emacs, Lua or PowerShell are installed, it also runs their native smoke checks; absent optional tools are reported and skipped. Neovim's parser is compiled into a temporary directory rather than the product tree. With npm install run in highlight/textmate, the suite also tokenizes the fixture through VS Code's actual TextMate engine and builds a temporary valid VSIX. The --lsp-emacs mode runs only the live editor-to-server smoke and fails if Emacs or the named compiler executable is absent; the compiler gate uses it after building refine.

To exercise Pygments without installing anything into the repository, create a temporary virtual environment, pip install -e ./highlight, and run the suite with that environment's python3 first on PATH.

--integration adds every positive, runtime and ABI Landin source plus core/* to the tree-sitter pass. The *.ldn filter is deliberate: C and header companions in an ABI fixture are never presented to the Landin grammar. It is language-wide evidence, and it is not needed to test or package the highlighters themselves, so it stays a separate request. Unlike every other optional tool here, the pinned tree-sitter CLI is mandatory once it is asked for: --integration without it exits non-zero rather than reporting a corpus pass that did not run. It was made so after the grammar was found to have drifted from the enabled kernel unnoticed, 48 of 846 sources failing, because the pass could be requested and skipped in the same run. The gate's editor-grammar job runs it on each full gate run with the release binary of the CLI version tree-sitter/package.json names, checked against the sha256 in environments/pins.sh, and fails if regenerating the parser changes the committed one. AGENTS.md describes the verified explanatory-only reuse exception. Each editor directory contains the shortest installation path for that editor.