@nmbl-lang/language-server
v0.2.0
Published
Language Server Protocol implementation for NMBL templates
Readme
@nmbl-lang/language-server
A Volar 2.4 language server that provides IDE intelligence for the NMBL template language.
What it does
The server handles two document kinds:
- Standalone
.nmblfiles — the entire file is NMBL source. - Embedded regions in
.svelteand.astrofiles — the server scans for<template lang="nmbl">blocks and activates only on files that contain one (files without that tag are ignored completely, so the Svelte / Astro language servers are not disturbed).
For each recognized document the server:
- Compiles the NMBL source via
@nmbl-lang/core'scompile(), choosing the right framework target (svelte/astro/html). - Produces a Volar
VirtualCodetree: a rootnmblcode plus an embeddedhtmlvirtual code that carries the compiled output. - Exposes source mappings that link every token in the generated HTML back to the original position in the host document (accounting for the leading indentation that was stripped before compilation).
- Feeds the virtual HTML code to
volar-service-htmlto provide HTML completions, hover documentation, and HTML diagnostics for free. - Surfaces NMBL compile errors (syntax errors, unsupported control-flow blocks, etc.) as LSP diagnostics, with spans pointing at the correct position in the original file.
What users get
- Diagnostics — NMBL syntax errors and unsupported block types highlighted in the editor.
- HTML completions and hover — tag names, attribute names, and values are suggested via the embedded HTML language service.
- Go-to-definition / find-references — Volar maps tokens in the compiled HTML back to the NMBL source, so editor navigation works on the original file.
What it deliberately does NOT do
- Framework-type-aware expression checking — NMBL control-flow expressions (
@if(cond),@each(items as item)) are compiled to Svelte or Astro syntax in the virtual code, but the server does not run a full TypeScript/JavaScript type-checker over them. See sveltejs/language-tools#339 for context on why deep expression checking in embedded languages is non-trivial. The Astro Language Server has no plugin hook that would allow injecting a second virtual language service either. - Vue single-file components —
.vuefiles with<template lang="nmbl">are handled by the separate@nmbl-lang/vue-language-pluginVolar plugin, which integrates directly into the Vue language toolchain. This server intentionally ignoreslanguageId: 'vue'to avoid double-reporting diagnostics.
How the VSCode extension wires it
The extension (packages/vscode-extension) contributes:
- TextMate grammars that inject
source.nmblsyntax highlighting into.svelte,.astro, and.vuefiles wherever a<template lang="nmbl">region appears. - A language client (
client/extension.ts) that spawns this server via IPC and activates ononLanguage:nmbl,onLanguage:svelte, andonLanguage:astro.
The client passes { language: 'svelte' } and { language: 'astro' } document selectors to the server. For each open document the server's createVirtualCode inspects the text; if no <template lang="nmbl"> is present the function returns undefined and Volar leaves the file alone.
