Language Server Protocol support functions for eXist-db XQuery development
A new Java extension module that exposes eXist-db's XQuery compiler internals as XQuery functions, enabling LSP servers and editors to provide diagnostics, symbol information, completions, hover, go-to-definition, and find-all-references for XQuery code.
This module was originally proposed as part of exist-core (PR #6130). Core developers requested it be extracted into a standalone EXPath package to decouple LSP releases from eXist-db releases. There is no predecessor module — the namespace http://exist-db.org/xquery/lsp is new.
- eXist-db version
7.0.0or greater - Java version
21or greater (for building from source) - Maven version
3.9or greater (for building from source)
From a GitHub release:
xst package install https://github.com/joewiz/exist-lsp/releases/download/v0.9.0-SNAPSHOT/exist-lsp-0.9.0-SNAPSHOT.xarFrom a local build:
mvn package -DskipTests
xst package install target/exist-lsp-0.9.0-SNAPSHOT.xarBuilding requires eXist-db 7.0.0-SNAPSHOT installed in your local Maven repository. The published snapshot on the eXist-db Maven repository is stale (June 2024) and predates API changes on develop that this module depends on.
To install the required artifacts locally, clone and build eXist-db first:
git clone https://github.com/eXist-db/exist
cd exist
mvn -T1.5C clean install -DskipTests -Ddocker=falseThen build the XAR:
git clone https://github.com/joewiz/exist-lsp
cd exist-lsp
mvn clean package -DskipTestsThe XAR package will be at target/exist-lsp-0.9.0-SNAPSHOT.xar.
Note: CI works around the stale Maven snapshot by extracting the
exist.uber.jarfrom theexistdb/existdb:latestDocker image (built nightly fromdevelop) and installing it into the local Maven repository before compilation.
All functions are in the http://exist-db.org/xquery/lsp namespace (default prefix: lsp).
import module namespace lsp = "http://exist-db.org/xquery/lsp";Compiles an XQuery expression and returns an array of diagnostic maps. Returns an empty array if compilation succeeds.
lsp:diagnostics($expression as xs:string) as array(*)
lsp:diagnostics($expression as xs:string, $module-load-path as xs:string?) as array(*)Each map contains:
| Key | Type | Description |
|---|---|---|
line |
xs:integer |
0-based line number |
column |
xs:integer |
0-based column number |
severity |
xs:integer |
LSP DiagnosticSeverity (1=error) |
code |
xs:string |
W3C error code (e.g., XPST0003) |
message |
xs:string |
Human-readable error description |
lsp:diagnostics("let $x := 1 retrun $x")
(: => [ map { "line": 0, "column": 12, "severity": 1,
"code": "XPST0003", "message": "..." } ] :)Extracts document symbols (function and variable declarations) from a compiled XQuery expression.
lsp:symbols($expression as xs:string) as array(*)
lsp:symbols($expression as xs:string, $module-load-path as xs:string?) as array(*)Each map contains:
| Key | Type | Description |
|---|---|---|
name |
xs:string |
Symbol name (e.g., local:greet#1, $local:x) |
kind |
xs:integer |
LSP SymbolKind (12=Function, 13=Variable) |
line |
xs:integer |
0-based start line |
column |
xs:integer |
0-based start column |
detail |
xs:string |
Signature or type information |
Returns completion items available in the context of an XQuery expression, including built-in functions, keywords, and user-declared symbols.
lsp:completions($expression as xs:string) as array(*)
lsp:completions($expression as xs:string, $module-load-path as xs:string?) as array(*)Each map contains:
| Key | Type | Description |
|---|---|---|
label |
xs:string |
Display text (e.g., fn:count#1) |
kind |
xs:integer |
LSP CompletionItemKind (3=Function, 6=Variable, 14=Keyword) |
detail |
xs:string |
Signature or type info |
documentation |
xs:string |
Function description |
insertText |
xs:string |
Text to insert (e.g., fn:count()) |
Returns hover information for the symbol at a given position.
lsp:hover($expression as xs:string, $line as xs:integer, $column as xs:integer) as map(*)?
lsp:hover($expression as xs:string, $line as xs:integer, $column as xs:integer,
$module-load-path as xs:string?) as map(*)?Returns a map with contents (signature and documentation) and kind ("function" or "variable"), or an empty sequence if no symbol is found.
Returns the definition location of the symbol at a given position.
lsp:definition($expression as xs:string, $line as xs:integer, $column as xs:integer) as map(*)?
lsp:definition($expression as xs:string, $line as xs:integer, $column as xs:integer,
$module-load-path as xs:string?) as map(*)?Returns a map with line, column, name, kind, and optionally uri (for cross-module definitions), or an empty sequence.
Finds all references to the symbol at a given position, including the declaration.
lsp:references($expression as xs:string, $line as xs:integer, $column as xs:integer) as array(*)
lsp:references($expression as xs:string, $line as xs:integer, $column as xs:integer,
$module-load-path as xs:string?) as array(*)Each map contains line, column, name, and kind.
All functions accept an optional $module-load-path parameter that controls how import module statements are resolved:
"xmldb:exist:///db"or"/db"— resolve imports from the database- A filesystem path — resolve imports from the filesystem
()or omitted — use the default module load path
GNU-LGPL v2.1 © The eXist-db Authors