3.9 KiB
Work in progress.
An attempt to write a Language Server Protocol server for and in XQuery 4.0. It tracks the draft specifications at https://qt4cg.org/ It written for BaseX 12.0 and uses the BaseX websocket feature. See The WebSocket Protocol RFC 6455
Demo
The demo makes use of Docker or Podman for ease of setup. This is not a requirement to use the software.
1 Clone this repo
2. Run docker compose up -d The LSP server shall now running on port 3000 (edit compose.yaml to change port)
3. In a browser navigate to http://localhost:3000/static/clients/codemirror/ to see the CodeMirror 6 demo.
In principle, the LSP can be used in any environment that can make use of a LSP server accessed via a websocket.
LSP Server
webapp/lspThe LSP implementation in XQuery using WebSockets for transport and the JSON-RPC 2.0 API for data format.
Sample html clients
Samples using common browser based code editors are available. The CodeMirror 6 sample is the most functional.
These examples are self contained (no internet access required). Some make use of recent html features, for instance popovertarget
CodeMirror6 https://codemirror.net/
webapp/static/codemirrorA test html page using the CodeMirror6 editor that connects to the BaseX LSP instance
uses
- https://codemirror.net/docs/ref/#lsp-client
- https://github.com/codemirror/legacy-modes/
xquerymode provides browser based syntax highlighting (XQuery 3.1?)
alternative LSP interfaces
Ace Editor
webapp/static/aceA test html page using the Ace editor that connects to the BaseX LSP instance @TODO fix
Uses
Make a websocket server for lsp on port 3000 https://mkslanc.github.io/ace-linters/websocket.html
http://localhost:3000/exampleServer
c1b317e012/packages/demo/websockets-lsp/server/server.ts
I needed set NODE_OPTIONS=--max_old_space_size=8192 for build to complete
Or node --max-old-space-size=8192 node_modules/webpack-dev-serve r/bin/webpack-dev-server.js
Monaco editor
@TODO create https://socket.dev/npm/package/monaco-editor
Server dev notes
State is held in websocket attributes.
| Name | Use |
|---|---|
| id | wsid |
| connectTime | dateTime of connection |
| initialized | set true after client sends initialized message |
| client | the client initialize message |
| files | A map whose keys are open uris, values are maps (doctype-> attribute name where doctype is stored |
| file-{uuid} | name of websocket attribute containing the textDocument |
| parse-{uuid} | name of websocket attribute containing parse tree XML |
sequenceDiagram
WS->>lsp-ws: message
lsp-ws->>rpc: reply
rpc->>+John: John, can you hear me?
XQuery 4.0 parser
The ebnf is taken from Gunther Rademacher's rex-parser-generator XQuery-40.ebnf
The script scripts/rex.xq can generate XQuery or Java parser code from this.
The npm package.json script javac can create a jar file from the Java source.
Related links
java -cp org.eclipse.lemminx-uber.jar org.eclipse.lemminx.XMLServerSocketLauncher`