LSP Server
lash provides a Language Server Protocol implementation as a separate lash-lsp binary. It imports only lang/ and runtime/ — it does not connect to the backend daemon.
Namespace Model
Section titled “Namespace Model”lash uses a Lisp-2 namespace model, separating Scope into three maps:
vars— variable namespace (let/mutbindings)fns— function namespace (fndeclarations)types— user-defined type namespace (typedeclarations)
declareFn/lookupFn and declareTypeDecl/lookupTypeDecl walk the scope chain for their respective namespaces, parallel to declareVar/lookupVar for variables.
Semantic Analyzer
Section titled “Semantic Analyzer”Pre-execution AST validation, located in lang/semantic/, depends only on runtime/.
| Check | Description |
|---|---|
| Undeclared variable use | Reference not in any enclosing scope. |
| Undeclared function call | Not in function namespace and not a builtin. |
| Immutable assignment | Assignment targets let binding. |
| Redeclaration | let in same scope where name exists. |
| Drop undeclared | drop on name not in scope. |
| Break/continue outside loop | Not inside for/while. |
Integration points:
- Backend may call
analyze()on scripts before execution. - LSP uses
analyze()on partial ASTs for diagnostics. - Interactive mode skips analysis.
Tolerant Parser
Section titled “Tolerant Parser”Located at lang/parser/tolerant.d. Wraps the existing tokenizer with error recovery:
- On parse error: records diagnostic, skips to recovery point, continues.
- Returns: statements, diagnostics, tokens.
- Handles: incomplete expressions, unclosed braces, trailing dots, missing arguments.
Recovery points:
- Statement-level: next
;,}, or start-of-line keyword. - Expression-level: next
),],},,, or;.
LSP Capabilities
Section titled “LSP Capabilities”| Capability | Trigger |
|---|---|
textDocumentSync | Full document sync |
completionProvider | . and $, with resolveProvider:true for lazy per-item docs |
hoverProvider | — |
diagnosticProvider | Push on change |
definitionProvider | — |
semanticTokensProvider | comment token type with a documentation modifier for doc comments |
Completion Sources
Section titled “Completion Sources”- Keywords:
let,mut,fn,type,if,for,while,match,break,continue,exit,true,false,write, … - Builtins:
cd,exit,jobs,fg,bg,z,set,session,audit,profile,echo,cat,ls,pwd,grep,head,tail,sort,uniq,wc— each with a one-line description shown in the popup. - Scope variables and functions: from the current analysis context.
- Native-plugin functions and types: fns and
typedeclarations loaded from~/.lash/plugins/*.lashand the compiled-in bundle show up at command position with full signatures and doc comments. - Subcommands (arg position): after a known CLI (
git,docker,kubectl,helm,cargo,npm,dub,systemctl), the matching subcommands appear with descriptions. Falls back to<cmd> --helpparsing, then bash-completion invocation, for unknown commands. - PATH executables: at command position only, emitted alongside keywords and builtins.
whatisdescriptions attach lazily viacompletionItem/resolve. - Type methods: based on inferred type of the expression before the
. - Environment variables: after
$
Hover Info
Section titled “Hover Info”- Variables: show type and mutability.
- Functions: show typed signature (
fn gco(ref: GitBranch)) and attached doc comments. - Types: show name, cache TTL, method list, and doc comments.
- Parameters inside a fn body: show the param’s type annotation and attached doc lines.
- Methods: show signature and description.
Semantic Tokens
Section titled “Semantic Tokens”Doc-comment spans (///, /** ... */) attached to a following fn, type, or unittest declaration are tagged with the documentation modifier, letting editors style them differently from ordinary // comments. Non-declaration-attached doc-comment syntax falls back to a plain comment token.
Document Lifecycle
Section titled “Document Lifecycle”didOpen— tokenize + tolerant parse + analyze — cache and publish diagnostics.didChange— re-parse + re-analyze — update and publish.didClose— remove from cache.