AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
Language Server for XQuery
翻譯準備中
開發工具TypeScript · XQueryGitHub @DrRataplan自行安裝營運者未確認
試用過了嗎? 點一下就好,不需要登入。
正在載入完整 README。 以下為已儲存的摘錄。
Language Server Protocol implementation for XQuery, providing autocompletion, hover documentation, signature help, go-to-definition, and diagnostics.檢視完整 README ↗Language Server Protocol implementation for XQuery, providing autocompletion, hover documentation, signature help, go-to-definition, and diagnostics.
textDocument/diagnostic), including for files that are not openPlace an lsp-config.xq file in the Fonto root folder (the one that holds the manifest.json) with the following content:
map {
'lib': 'fonto',
'glob': 'packages/**/*.xqm',
'import': map {
'generateLocationHints': false()
}
}
Place an lsp-config.xq file in your project root to enable glob-based import resolution. The server walks up from the current file's directory to find it.
The file contains an XPath 3.1 map expression with a glob key:
map {"glob": "src/**/*.xq"}
Multiple patterns are written as an XPath sequence:
map {"glob": ("src/**/*.xq", "lib/**/*.xq")}
The server expands the globs, analyzes each matched file, and indexes library modules by their declared namespace URI. Imports written without an at clause are then resolved by matching the namespace URI:
(: no "at" path needed — the server finds the file via the glob index :)
import module namespace util="http://example.com/util";
Imports written as import module namespace prefix="uri" at "./other-file.xq" are followed
automatically; symbols from imported files are included in completions.
For files with syntax errors (common while editing), the server falls back to regex-based extraction so completions keep working.
Use the lib key to load built-in definitions for a specific runtime:
| Value | Runtime |
|---|---|
"fonto" | Fonto XML editor — fonto:* functions |
"existdb" | eXist-db — all extension module functions |
map {"glob": "src/**/*.xq", "lib": "existdb"}
Multiple libs use an XPath sequence:
map {"glob": "src/**/*.xq", "lib": ("fonto", "other")}
The "existdb" runtime bundles stub definitions for every eXist-db extension
module (util, xmldb, request, sm, ft, compression, …).
eXist-db automatically pre-declares a large set of namespace prefixes — you can
call util:log(…), xmldb:store(…), process:execute(…), etc. without any
import module namespace statement. When the existdb runtime is active the
server knows about these pre-declared prefixes and:
XQST0081 ("namespace prefix not declared") diagnostics
for all pre-declared namespacesimport module namespace in your sourceIf you do choose to write explicit imports (e.g. for editor portability), the server handles those correctly too:
(: explicit import — also fine :)
import module namespace util = "http://exist-db.org/xquery/util";
util:uuid()
Modules that require explicit import even in eXist-db (e.g. console, kwic) still need a import module namespace declaration; the server offers quick-fix code actions to insert it.
(: lsp-config.xq in your project root :)
map {
"glob": "src/**/*.xq",
"lib": "existdb",
"import": map {
"generateLocationHints": false()
}
}
The generateLocationHints: false() setting prevents the server from appending
at "…" paths to generated imports, which eXist-db does not need (it resolves
modules by namespace URI).
Then import the namespace in your XQuery files as usual — the server resolves completions, hover, and go-to-definition against the bundled definitions:
import module namespace fonto="http://www.fontoxml.com/functions";
Some runtimes do not like location hints (import namespace prefix="uri" at "Location hint";), turn
them off to prevent them from being generated:
map {
'import': map {
'generateLocationHints': false()
}
}
By default the type checker only reports certain static type errors. Some
mistakes are only dynamic errors (XPTY0004) that a static analyzer cannot prove —
for example passing a value of type item()* to a parameter declared as item():
the sequence may have length 0 or 2 at runtime. Opt in to stricter checking with
the strict map to get these reported as warnings:
map {
"glob": "src/**/*.xq",
"strict": map {
"cardinality": true()
}
}
With "cardinality": true(), an argument whose inferred cardinality is not
guaranteed to fit the parameter's occurrence indicator is flagged as a warning
(still with code XPTY0004). For example, passing item()* where item() is
expected, or item()? where item()+ is expected. The check respects narrowing:
inside if (exists($x)) then … a variable of type item()* is treated as
item()+.
function, declare and ancestor-or-self, which saves you
some keystrokesInstall xquery-mode from MELPA:
M-x package-install RET xquery-mode RET
Add to your init.el:
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(xquery-mode . ("npx" "xq-lsp" "--stdio"))))
(add-hook 'xquery-mode-hook #'eglot-ensure)
Open any .xq file and eglot starts the server automatically. Run M-x eglot to start it manually.
Key bindings:
| Action | Key |
|---|---|
| Completion | C-M-i |
| Hover / docs | C-c C-d |
| Signature help | automatic in minibuffer |
| Go to definition | M-. |
| Go back | M-, |
| Document symbols | M-x imenu |
| Diagnostics | M-x flymake-show-buffer-diagnostics |
Inlay hints (inferred types after untyped let/for/declare variable names, and
parameter names before call arguments) are shown by eglot-inlay-hints-mode, which eglot
turns on automatically since Emacs 29.1. If they don't appear, check that :inlayHintProvider
isn't listed in eglot-ignored-server-capabilities, or toggle them with
M-x eglot-inlay-hints-mode.
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-language-id-configuration '(xquery-mode . "xquery"))
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("npx" "xq-lsp" "--stdio"))
:major-modes '(xquery-mode)
:language-id "xquery"
:server-id 'xquery-lsp)))
(add-hook 'xquery-mode-hook #'lsp)
lsp-mode does not show inlay hints unless asked to:
(setq lsp-inlay-hint-enable t)
The reference counts above each function and module variable are code lenses; lsp-mode shows
them by default (lsp-lens-enable). Eglot does not support code lenses.
A minimal VS Code extension lives in editors/vscode/.
Launch VS Code Quick Open (Ctrl+P or Cmd+P), paste the following command, and press enter.
ext install elliat.xquery-lsp-vscode
cd editors/vscode
npm install
Open the editors/vscode folder in VS Code and press F5 to launch a development host with the
extension active. To install it permanently, package it with
vsce:
npx vsce package
code --install-extension xquery-lsp-vscode-*.vsix
The extension registers .xq, .xql, .xqm, .xqy, and .xquery files as XQuery, provides syntax highlighting via a bundled TextMate grammar, and starts xq-lsp automatically when you open one.
A plugin lives in editors/claude-code/ that registers xq-lsp as a native LSP server for Claude Code, giving diagnostics, go-to-definition, find-references, and hover for XQuery files.
Make sure the xq-lsp binary is on PATH:
npm install -g xq-lsp
Then, from within Claude Code:
/plugin marketplace add DrRataplan/xq-lsp
/plugin install xquery-lsp@xq-lsp
See editors/claude-code/README.md for local-development setup and details on what the plugin configures.