Expand description
Languages registered at runtime rather than compiled in.
Design:
plugin-languages.md §2.3.
Slice plan: LG.2.
Lang is a closed enum, and every language lattice supports is a
workspace dependency. This module is the other half: a registry a
plugin contributes to at load and is withdrawn from at unload, so
“which languages exist” stops being a compile-time property of the
editor (paramount goal #2).
§Why the name is the id
LanguageName is a Copy newtype over a &'static str, not an
index into a table. Two things fall out of that, and both were the
reason for choosing it:
Lang::name()stays a field read. It is the key every query lookup already uses —registry.highlights_query(lang.name()), six times per highlight invocation, plus folds and indents. An index would have put a process-global table read inside it (paramount goal #1).LangRegistryis already keyed by&'static str. A plugin language joins the map native languages live in, under its own name, rather than needing a parallel index space.
The name is leaked, once per distinct name — LanguageName::intern
dedupes, so a plugin reloaded fifty times in a dev session leaks one
string, not fifty. A leaked name also means a buffer still holding
Lang::Plugin(name) after its plugin unloads keeps naming itself
correctly; it simply finds no grammar and renders as plain text.
Nothing dangles, and there is no kind-branch anywhere to express it.
§Why reads are process-global
Writes go through an RCU handle with teardown by provenance, exactly
as contributable-registries.md prescribes. Reads do not take a
handle, because Lang::detect_from_path is a free function with
nineteen call sites across lattice-host, lattice-magit and
lattice-multibuffer. Threading a handle through them would make
plugin languages visible on some paths and invisible on others —
a two-tier language concept, and the same failure the “no
kind-specific logic” rule forbids for buffers. Lang::Plugin must be
interpretable wherever Lang::Rust is, by the same code.
LangRegistry::standard is already a process-wide memo in this crate
for a related reason.
Structs§
- Language
Name - The name of a language, interned so it outlives every buffer that
refers to it. Doubles as the language’s identity:
Lang::Plugincarries one, and it is the key intocrate::LangRegistry. - Language
Registration - One plugin-contributed language.
- Plugin
Languages - The set of runtime-registered languages.
Enums§
- Language
Registration Error - Why a registration was refused. Every variant names the offending language, because a plugin author reading a log line needs to know which of their contributions failed — and per LG.3’s error rule a failed language must not take the plugin’s other contributions with it.
Functions§
- handle
- The process-wide handle. See the module docs for why reads do not take one explicitly.
- register
- Register a language.
- register_
with_ grammar - Register a language with its grammar and queries (LG.3a).
- register_
with_ grammar_ themed register_with_grammar, with the theme registry in hand (TK.1).- resolve_
extension - Resolve a file extension to a plugin language.
- snapshot
- Snapshot the live set. Wait-free; callers hold the
Arcfor as long as they need a coherent view. - unregister_
plugin - Withdraw every language contributed by
provenance, returning how many were removed.
Type Aliases§
- Plugin
Languages Handle - Copy-on-write RCU, the idiom
contributable-registries.md§2 establishes and the tree already carries five times over.