This commit is contained in:
Andy Bunce 2025-08-24 22:54:14 +01:00
parent 9331800656
commit 9f34c28efc
6 changed files with 264 additions and 146 deletions

View file

@ -8,16 +8,20 @@ An attempt to write a [Language Server Protocol](https://en.wikipedia.org/wiki/L
3. Run `docker compose up -d` The LSP server shall now running on port 3000 (edit `compose.yaml` to change port)
4. 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 websocket accessed LSP.
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/lsp` The LSP implementation in XQuery using WebSockets for transport and the [JSON-RPC](https://www.jsonrpc.org/specification) 2.0 API for data format.
## Sample html clients
A couple of samples using common browser based code editor components are available. The `CodeMirror 6` sample is the most functional.
A couple of 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](https://caniuse.com/?search=popovertarget)
### Using `CodeMirror6` https://codemirror.net/
* `webapp/static/codemirror` A test html page using the [CodeMirror6 editor](https://codemirror.net/) that connects to the BaseX LSP instance
#### uses
* https://codemirror.net/docs/ref/#lsp-client
#### alternatives
* https://github.com/FurqanSoftware/codemirror-languageserver
* https://hjr265.me/blog/codemirror-lsp/
@ -42,12 +46,12 @@ r/bin/webpack-dev-server.js`
@TODO create
https://socket.dev/npm/package/monaco-editor
### Dev notes
### Server dev notes
State is held in [websocket attributes](https://docs.basex.org/main/WebSocket_Functions#websocket_attributes).
|Name|Use|
|----|---|
|initialized|set true after client sends initialized messag|
|initialized|set true after client sends initialized 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 with textDocument|
|parse-{uuid}|name of websocket attribute with parse tree XML|

View file

@ -1 +1 @@
{"cells":[{"kind":2,"language":"xquery","value":"(:<:)\r\n\r\nimport module namespace docs=\"lsp/docs\" at \"/srv/basex/webapp/lsp/docs.xqm\";"},{"kind":2,"language":"xquery","value":"2+2"},{"kind":2,"language":"xquery","value":"ws:ids()"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn $t"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"parse\")\r\nreturn $t/self::ERROR"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn $t"}]}
{"cells":[{"kind":2,"language":"xquery","value":"(:<:)\r\n\r\nimport module namespace docs=\"lsp/docs\" at \"/srv/basex/webapp/lsp/docs.xqm\";"},{"kind":2,"language":"xquery","value":"2+2"},{"kind":2,"language":"xquery","value":"ws:ids()"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn $t?text"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"parse\")\r\nreturn $t/self::ERROR"},{"kind":2,"language":"xquery","value":"let $sock:=foot(ws:ids())\r\nlet $f:=docs:list($sock)\r\nlet $t:=docs:get($sock,$f,\"textDocument\")\r\nreturn $t"}]}

172
package-lock.json generated
View file

@ -149,9 +149,9 @@
}
},
"node_modules/@codemirror/lsp-client": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@codemirror/lsp-client/-/lsp-client-6.0.1.tgz",
"integrity": "sha512-HxvGP1i+LkTQIKa9NWYJ/6djNEEo70IV+FU16FbORD0E3p9FNkcrAujDWyOJHtLxMFDFXdQsaHIiqxtCzZ5v2A==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@codemirror/lsp-client/-/lsp-client-6.1.0.tgz",
"integrity": "sha512-DRZ97ZvTywU6IvGvmImNFIOWo2IkI1V6EccXrgId7/nJ7IhUQNFkGRMafDGX8plr65ngCBH+u9Sy0fTuGu39BA==",
"license": "MIT",
"dependencies": {
"@codemirror/autocomplete": "^6.18.6",
@ -417,9 +417,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.47.1.tgz",
"integrity": "sha512-lTahKRJip0knffA/GTNFJMrToD+CM+JJ+Qt5kjzBK/sFQ0EWqfKW3AYQSlZXN98tX0lx66083U9JYIMioMMK7g==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.48.0.tgz",
"integrity": "sha512-aVzKH922ogVAWkKiyKXorjYymz2084zrhrZRXtLrA5eEx5SO8Dj0c/4FpCHZyn7MKzhW2pW4tK28vVr+5oQ2xw==",
"cpu": [
"arm"
],
@ -431,9 +431,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.47.1.tgz",
"integrity": "sha512-uqxkb3RJLzlBbh/bbNQ4r7YpSZnjgMgyoEOY7Fy6GCbelkDSAzeiogxMG9TfLsBbqmGsdDObo3mzGqa8hps4MA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.48.0.tgz",
"integrity": "sha512-diOdQuw43xTa1RddAFbhIA8toirSzFMcnIg8kvlzRbK26xqEnKJ/vqQnghTAajy2Dcy42v+GMPMo6jq67od+Dw==",
"cpu": [
"arm64"
],
@ -445,9 +445,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.47.1.tgz",
"integrity": "sha512-tV6reObmxBDS4DDyLzTDIpymthNlxrLBGAoQx6m2a7eifSNEZdkXQl1PE4ZjCkEDPVgNXSzND/k9AQ3mC4IOEQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.48.0.tgz",
"integrity": "sha512-QhR2KA18fPlJWFefySJPDYZELaVqIUVnYgAOdtJ+B/uH96CFg2l1TQpX19XpUMWUqMyIiyY45wje8K6F4w4/CA==",
"cpu": [
"arm64"
],
@ -459,9 +459,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.47.1.tgz",
"integrity": "sha512-XuJRPTnMk1lwsSnS3vYyVMu4x/+WIw1MMSiqj5C4j3QOWsMzbJEK90zG+SWV1h0B1ABGCQ0UZUjti+TQK35uHQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.48.0.tgz",
"integrity": "sha512-Q9RMXnQVJ5S1SYpNSTwXDpoQLgJ/fbInWOyjbCnnqTElEyeNvLAB3QvG5xmMQMhFN74bB5ZZJYkKaFPcOG8sGg==",
"cpu": [
"x64"
],
@ -473,9 +473,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.47.1.tgz",
"integrity": "sha512-79BAm8Ag/tmJ5asCqgOXsb3WY28Rdd5Lxj8ONiQzWzy9LvWORd5qVuOnjlqiWWZJw+dWewEktZb5yiM1DLLaHw==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.48.0.tgz",
"integrity": "sha512-3jzOhHWM8O8PSfyft+ghXZfBkZawQA0PUGtadKYxFqpcYlOYjTi06WsnYBsbMHLawr+4uWirLlbhcYLHDXR16w==",
"cpu": [
"arm64"
],
@ -487,9 +487,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.47.1.tgz",
"integrity": "sha512-OQ2/ZDGzdOOlyfqBiip0ZX/jVFekzYrGtUsqAfLDbWy0jh1PUU18+jYp8UMpqhly5ltEqotc2miLngf9FPSWIA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.48.0.tgz",
"integrity": "sha512-NcD5uVUmE73C/TPJqf78hInZmiSBsDpz3iD5MF/BuB+qzm4ooF2S1HfeTChj5K4AV3y19FFPgxonsxiEpy8v/A==",
"cpu": [
"x64"
],
@ -501,9 +501,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.47.1.tgz",
"integrity": "sha512-HZZBXJL1udxlCVvoVadstgiU26seKkHbbAMLg7680gAcMnRNP9SAwTMVet02ANA94kXEI2VhBnXs4e5nf7KG2A==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.48.0.tgz",
"integrity": "sha512-JWnrj8qZgLWRNHr7NbpdnrQ8kcg09EBBq8jVOjmtlB3c8C6IrynAJSMhMVGME4YfTJzIkJqvSUSVJRqkDnu/aA==",
"cpu": [
"arm"
],
@ -515,9 +515,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.47.1.tgz",
"integrity": "sha512-sZ5p2I9UA7T950JmuZ3pgdKA6+RTBr+0FpK427ExW0t7n+QwYOcmDTK/aRlzoBrWyTpJNlS3kacgSlSTUg6P/Q==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.48.0.tgz",
"integrity": "sha512-9xu92F0TxuMH0tD6tG3+GtngwdgSf8Bnz+YcsPG91/r5Vgh5LNofO48jV55priA95p3c92FLmPM7CvsVlnSbGQ==",
"cpu": [
"arm"
],
@ -529,9 +529,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.47.1.tgz",
"integrity": "sha512-3hBFoqPyU89Dyf1mQRXCdpc6qC6At3LV6jbbIOZd72jcx7xNk3aAp+EjzAtN6sDlmHFzsDJN5yeUySvorWeRXA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.48.0.tgz",
"integrity": "sha512-NLtvJB5YpWn7jlp1rJiY0s+G1Z1IVmkDuiywiqUhh96MIraC0n7XQc2SZ1CZz14shqkM+XN2UrfIo7JB6UufOA==",
"cpu": [
"arm64"
],
@ -543,9 +543,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.47.1.tgz",
"integrity": "sha512-49J4FnMHfGodJWPw73Ve+/hsPjZgcXQGkmqBGZFvltzBKRS+cvMiWNLadOMXKGnYRhs1ToTGM0sItKISoSGUNA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.48.0.tgz",
"integrity": "sha512-QJ4hCOnz2SXgCh+HmpvZkM+0NSGcZACyYS8DGbWn2PbmA0e5xUk4bIP8eqJyNXLtyB4gZ3/XyvKtQ1IFH671vQ==",
"cpu": [
"arm64"
],
@ -557,9 +557,9 @@
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.47.1.tgz",
"integrity": "sha512-4yYU8p7AneEpQkRX03pbpLmE21z5JNys16F1BZBZg5fP9rIlb0TkeQjn5du5w4agConCCEoYIG57sNxjryHEGg==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.48.0.tgz",
"integrity": "sha512-Pk0qlGJnhILdIC5zSKQnprFjrGmjfDM7TPZ0FKJxRkoo+kgMRAg4ps1VlTZf8u2vohSicLg7NP+cA5qE96PaFg==",
"cpu": [
"loong64"
],
@ -571,9 +571,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.47.1.tgz",
"integrity": "sha512-fAiq+J28l2YMWgC39jz/zPi2jqc0y3GSRo1yyxlBHt6UN0yYgnegHSRPa3pnHS5amT/efXQrm0ug5+aNEu9UuQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.48.0.tgz",
"integrity": "sha512-/dNFc6rTpoOzgp5GKoYjT6uLo8okR/Chi2ECOmCZiS4oqh3mc95pThWma7Bgyk6/WTEvjDINpiBCuecPLOgBLQ==",
"cpu": [
"ppc64"
],
@ -585,9 +585,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.47.1.tgz",
"integrity": "sha512-daoT0PMENNdjVYYU9xec30Y2prb1AbEIbb64sqkcQcSaR0zYuKkoPuhIztfxuqN82KYCKKrj+tQe4Gi7OSm1ow==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.48.0.tgz",
"integrity": "sha512-YBwXsvsFI8CVA4ej+bJF2d9uAeIiSkqKSPQNn0Wyh4eMDY4wxuSp71BauPjQNCKK2tD2/ksJ7uhJ8X/PVY9bHQ==",
"cpu": [
"riscv64"
],
@ -599,9 +599,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.47.1.tgz",
"integrity": "sha512-JNyXaAhWtdzfXu5pUcHAuNwGQKevR+6z/poYQKVW+pLaYOj9G1meYc57/1Xv2u4uTxfu9qEWmNTjv/H/EpAisw==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.48.0.tgz",
"integrity": "sha512-FI3Rr2aGAtl1aHzbkBIamsQyuauYtTF9SDUJ8n2wMXuuxwchC3QkumZa1TEXYIv/1AUp1a25Kwy6ONArvnyeVQ==",
"cpu": [
"riscv64"
],
@ -613,9 +613,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.47.1.tgz",
"integrity": "sha512-U/CHbqKSwEQyZXjCpY43/GLYcTVKEXeRHw0rMBJP7fP3x6WpYG4LTJWR3ic6TeYKX6ZK7mrhltP4ppolyVhLVQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.48.0.tgz",
"integrity": "sha512-Dx7qH0/rvNNFmCcIRe1pyQ9/H0XO4v/f0SDoafwRYwc2J7bJZ5N4CHL/cdjamISZ5Cgnon6iazAVRFlxSoHQnQ==",
"cpu": [
"s390x"
],
@ -627,9 +627,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.47.1.tgz",
"integrity": "sha512-uTLEakjxOTElfeZIGWkC34u2auLHB1AYS6wBjPGI00bWdxdLcCzK5awjs25YXpqB9lS8S0vbO0t9ZcBeNibA7g==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.48.0.tgz",
"integrity": "sha512-GUdZKTeKBq9WmEBzvFYuC88yk26vT66lQV8D5+9TgkfbewhLaTHRNATyzpQwwbHIfJvDJ3N9WJ90wK/uR3cy3Q==",
"cpu": [
"x64"
],
@ -641,9 +641,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.47.1.tgz",
"integrity": "sha512-Ft+d/9DXs30BK7CHCTX11FtQGHUdpNDLJW0HHLign4lgMgBcPFN3NkdIXhC5r9iwsMwYreBBc4Rho5ieOmKNVQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.48.0.tgz",
"integrity": "sha512-ao58Adz/v14MWpQgYAb4a4h3fdw73DrDGtaiF7Opds5wNyEQwtO6M9dBh89nke0yoZzzaegq6J/EXs7eBebG8A==",
"cpu": [
"x64"
],
@ -655,9 +655,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.47.1.tgz",
"integrity": "sha512-N9X5WqGYzZnjGAFsKSfYFtAShYjwOmFJoWbLg3dYixZOZqU7hdMq+/xyS14zKLhFhZDhP9VfkzQnsdk0ZDS9IA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.48.0.tgz",
"integrity": "sha512-kpFno46bHtjZVdRIOxqaGeiABiToo2J+st7Yce+aiAoo1H0xPi2keyQIP04n2JjDVuxBN6bSz9R6RdTK5hIppw==",
"cpu": [
"arm64"
],
@ -669,9 +669,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.47.1.tgz",
"integrity": "sha512-O+KcfeCORZADEY8oQJk4HK8wtEOCRE4MdOkb8qGZQNun3jzmj2nmhV/B/ZaaZOkPmJyvm/gW9n0gsB4eRa1eiQ==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.48.0.tgz",
"integrity": "sha512-rFYrk4lLk9YUTIeihnQMiwMr6gDhGGSbWThPEDfBoU/HdAtOzPXeexKi7yU8jO+LWRKnmqPN9NviHQf6GDwBcQ==",
"cpu": [
"ia32"
],
@ -683,9 +683,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz",
"integrity": "sha512-CpKnYa8eHthJa3c+C38v/E+/KZyF1Jdh2Cz3DyKZqEWYgrM1IHFArXNWvBLPQCKUEsAqqKX27tTqVEFbDNUcOA==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.48.0.tgz",
"integrity": "sha512-sq0hHLTgdtwOPDB5SJOuaoHyiP1qSwg+71TQWk8iDS04bW1wIE0oQ6otPiRj2ZvLYNASLMaTp8QRGUVZ+5OL5A==",
"cpu": [
"x64"
],
@ -1199,9 +1199,9 @@
}
},
"node_modules/rollup": {
"version": "4.47.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.47.1.tgz",
"integrity": "sha512-iasGAQoZ5dWDzULEUX3jiW0oB1qyFOepSyDyoU6S/OhVlDIwj5knI5QBa5RRQ0sK7OE0v+8VIi2JuV+G+3tfNg==",
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.0.tgz",
"integrity": "sha512-BXHRqK1vyt9XVSEHZ9y7xdYtuYbwVod2mLwOMFP7t/Eqoc1pHRlG/WdV2qNeNvZHRQdLedaFycljaYYM96RqJQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1215,26 +1215,26 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.47.1",
"@rollup/rollup-android-arm64": "4.47.1",
"@rollup/rollup-darwin-arm64": "4.47.1",
"@rollup/rollup-darwin-x64": "4.47.1",
"@rollup/rollup-freebsd-arm64": "4.47.1",
"@rollup/rollup-freebsd-x64": "4.47.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.47.1",
"@rollup/rollup-linux-arm-musleabihf": "4.47.1",
"@rollup/rollup-linux-arm64-gnu": "4.47.1",
"@rollup/rollup-linux-arm64-musl": "4.47.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.47.1",
"@rollup/rollup-linux-ppc64-gnu": "4.47.1",
"@rollup/rollup-linux-riscv64-gnu": "4.47.1",
"@rollup/rollup-linux-riscv64-musl": "4.47.1",
"@rollup/rollup-linux-s390x-gnu": "4.47.1",
"@rollup/rollup-linux-x64-gnu": "4.47.1",
"@rollup/rollup-linux-x64-musl": "4.47.1",
"@rollup/rollup-win32-arm64-msvc": "4.47.1",
"@rollup/rollup-win32-ia32-msvc": "4.47.1",
"@rollup/rollup-win32-x64-msvc": "4.47.1",
"@rollup/rollup-android-arm-eabi": "4.48.0",
"@rollup/rollup-android-arm64": "4.48.0",
"@rollup/rollup-darwin-arm64": "4.48.0",
"@rollup/rollup-darwin-x64": "4.48.0",
"@rollup/rollup-freebsd-arm64": "4.48.0",
"@rollup/rollup-freebsd-x64": "4.48.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.48.0",
"@rollup/rollup-linux-arm-musleabihf": "4.48.0",
"@rollup/rollup-linux-arm64-gnu": "4.48.0",
"@rollup/rollup-linux-arm64-musl": "4.48.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.48.0",
"@rollup/rollup-linux-ppc64-gnu": "4.48.0",
"@rollup/rollup-linux-riscv64-gnu": "4.48.0",
"@rollup/rollup-linux-riscv64-musl": "4.48.0",
"@rollup/rollup-linux-s390x-gnu": "4.48.0",
"@rollup/rollup-linux-x64-gnu": "4.48.0",
"@rollup/rollup-linux-x64-musl": "4.48.0",
"@rollup/rollup-win32-arm64-msvc": "4.48.0",
"@rollup/rollup-win32-ia32-msvc": "4.48.0",
"@rollup/rollup-win32-x64-msvc": "4.48.0",
"fsevents": "~2.3.2"
}
},

View file

@ -7,64 +7,41 @@
<title>Codemirror6 example using BaseX LSP</title>
<link rel="icon" type="image/png" href="../favicon.png" />
<link href="../bootstrap@5.3.7.css" rel="stylesheet"
integrity="sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr" crossorigin="anonymous">
<link href="../bootstrap@5.3.7.css" rel="stylesheet" />
<link rel="stylesheet" href="styles.css" />
<script src="popover.js" defer></script>
</head>
<body>
<nav class="navbar bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand">XQuery 4.0 LSP client</a>
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<a class="navbar-brand">BaseX LSP client</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Editor</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Msgs</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/dba/logs" target="dba">Dba</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<button id="popcon" popovertarget="popConnect" class="btn btn-danger">
<i class="bi bi-router"></i>
</button>
</div>
<a href="/dba/logs" target="dba">#</a>
</nav>
<div class="row">
<div>
<select id="language">
<option selected>Language</option>
<option value="plaintext">plaintext</option>
<option value="xquery">xquery</option>
<option value="xml">xml</option>
</select>
<label for="file">File:</label>
<input id="iFile" type="url" value="file:///some/file.xqm" />
<!-- <div class="btn-group mr-2" role="group" aria-label="First group">
<button type="button" class="btn btn-secondary">1</button>
<button type="button" class="btn btn-secondary">2</button>
<button type="button" class="btn btn-secondary">3</button>
<button type="button" class="btn btn-secondary">4</button>
</div> -->
<div class="btn-group btn-group-sm " role="group" aria-label="Second group">
<button id="search" type="button" class="btn btn-light"><i
class="bi bi-search"></i></button>
<button id="lint" type="button" class="btn btn-light"><i
class="bi bi-info-square"></i></button>
<button id="sync" type="button" class="btn btn-light">
<i class="bi bi-arrow-repeat"></i>
</button>
</div>
<div class="btn-group" role="group" aria-label="Third group">
<button type="button" class="btn btn-light" title="Format"><i class="bi bi-justify-left"></i></button>
<button type="button" class="btn btn-light"
popovertarget="popSettings" title="Settings">
<i class="bi bi-gear"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="container-fluid">
@ -101,23 +78,70 @@
</div>
<div class="col flex-grow-1" style="overflow: auto;">
<div>
<select id="language">
<option selected>Language</option>
<option value="plaintext">plaintext</option>
<option value="xquery">xquery</option>
<option value="xml">xml</option>
</select>
<label for="file">File:</label>
<input id="iFile" type="url" value="file:///some/file.xqm" />
<!-- <div class="btn-group mr-2" role="group" aria-label="First group">
<button type="button" class="btn btn-secondary">1</button>
<button type="button" class="btn btn-secondary">2</button>
<button type="button" class="btn btn-secondary">3</button>
<button type="button" class="btn btn-secondary">4</button>
</div> -->
<div class="btn-group btn-group-sm " role="group" aria-label="Second group">
<button id="search" type="button" class="btn btn-light"><i class="bi bi-search"></i></button>
<button id="lint" type="button" class="btn btn-light"><i class="bi bi-info-square"></i></button>
<button id="sync" type="button" class="btn btn-light">
<i class="bi bi-arrow-repeat"></i>
</button>
</div>
<div class="btn-group" role="group" aria-label="Third group">
<button type="button" class="btn btn-light" title="Format"><i
class="bi bi-justify-left"></i></button>
<button type="button" class="btn btn-light" popovertarget="popSettings" title="Settings">
<i class="bi bi-gear"></i></button>
</div>
</div>
<!-- Editor goes in here -->
<div id="editor"></div>
</div>
</div>
</div>
<!-- Popovers -->
<div id="popConnect" popover>
<h2>Connect to LSP</h2>
<div id="state">🔴</div>
<input id="iServer" type="text" value="ws://localhost:3000/ws/lsp" style="width:25em" />
<button id="connect">connect</button>
</div>
<dialog id="popConnect" popover>
<div class="modal-header">
<h5 class="modal-title">Connect to LSP</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="state">🔴</div>
<input id="iServer" type="text" value="ws://localhost:3000/ws/lsp" style="width:25em" />
</div>
<div class="modal-footer">
<button id="connect">connect</button>
</div>
</dialog>
<div id="popSettings" popover>
<h2>Settings</h2>
<div>TODO</div>
</div>
<dialog id="popSettings" popover >
<div class="modal-header">
<h5 class="modal-title">Editor configuration</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
@TODO
</div>
<div class="modal-footer">
<button id="connect">ok</button>
</div>
</dialog>
<!-- CodeMirror 6 -->
<script src="./lsp.bundle.js"></script>
<script src="./script.js"></script>

View file

@ -0,0 +1,84 @@
// Create a class for the element
class PopupInfo extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
}
connectedCallback() {
// Create a shadow root
const shadow = this.attachShadow({ mode: "open" });
// Create spans
const wrapper = document.createElement("span");
wrapper.setAttribute("class", "wrapper");
const icon = document.createElement("span");
icon.setAttribute("class", "icon");
icon.setAttribute("tabindex", 0);
const info = document.createElement("span");
info.setAttribute("class", "info");
// Take attribute content and put it inside the info span
const text = this.getAttribute("data-text");
info.textContent = text;
// Insert icon
let imgUrl;
if (this.hasAttribute("img")) {
imgUrl = this.getAttribute("img");
} else {
imgUrl = "img/default.png";
}
const img = document.createElement("img");
img.src = imgUrl;
icon.appendChild(img);
// Create some CSS to apply to the shadow dom
const style = document.createElement("style");
console.log(style.isConnected);
style.textContent = `
.wrapper {
position: relative;
}
.info {
font-size: 0.8rem;
width: 200px;
display: inline-block;
border: 1px solid black;
padding: 10px;
background: white;
border-radius: 10px;
opacity: 0;
transition: 0.6s all;
position: absolute;
bottom: 20px;
left: 10px;
z-index: 3;
}
img {
width: 1.2rem;
}
.icon:hover + .info, .icon:focus + .info {
opacity: 1;
}
`;
// Attach the created elements to the shadow dom
shadow.appendChild(style);
console.log(style.isConnected);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
}
}
// Define the new element
customElements.define("popup-info", PopupInfo);

View file

@ -18,3 +18,9 @@
nav {
background-color: burlywood!;
}
.nav-pills > li > a
{
/* adjust padding for height*/
padding-top: 4px;
padding-bottom: 4px;
}