This commit is contained in:
Andy Bunce 2025-08-17 22:59:08 +01:00
parent 2d99af9389
commit e9a2d46272
7 changed files with 43 additions and 22 deletions

View file

@ -18,7 +18,7 @@ services:
# - ./jars:/srv/basex/lib/custom # - ./jars:/srv/basex/lib/custom
# - ./repo:/srv/basex/repo # - ./repo:/srv/basex/repo
environment: environment:
- "SERVER_OPTS= -d" - "SERVER_OPTS= "
volumes: volumes:
basex-lsp: basex-lsp:

View file

@ -24,6 +24,7 @@
"build-cm": "rollup bundles/src/lsp.js -m true -f iife -o webapp/static/clients/codemirror/lsp.bundle.js -p node-resolve,tla --output.name lsp", "build-cm": "rollup bundles/src/lsp.js -m true -f iife -o webapp/static/clients/codemirror/lsp.bundle.js -p node-resolve,tla --output.name lsp",
"min-cm": "cd webapp/static/clients/codemirror && npx minify lsp.bundle.js > lsp.bundle.min.js ", "min-cm": "cd webapp/static/clients/codemirror && npx minify lsp.bundle.js > lsp.bundle.min.js ",
"min": "cd dist && npx minify cm6.bundle.js > cm6.bundle.min.js && npx minify lsp.bundle.js > lsp.bundle.min.js", "min": "cd dist && npx minify cm6.bundle.js > cm6.bundle.min.js && npx minify lsp.bundle.js > lsp.bundle.min.js",
"javac":"cd bundles/grammar && javac -cp %BASEX12%\\BaseX.jar -d build xq4.java && cd build && jar cf ../xq4.jar . " "javac":"cd bundles/grammar && javac -cp %BASEX12%\\BaseX.jar -d build xq4.java && cd build && jar cf ../xq4.jar . "
} }
} }

View file

@ -81,4 +81,15 @@ as map(*)
"method":"window/logMessage", "method":"window/logMessage",
"params":{"type":1, "message": $msg} "params":{"type":1, "message": $msg}
} }
};
(:~ rpc response to $json msg :)
declare function rpc:response($result,$json as map(*))
as map(*)
{
map{
"jsonrpc": "2.0",
"id": $json?id,
"result": $result
}
}; };

View file

@ -33,7 +33,7 @@ declare function lsp-diags:publish(
as map(*){ as map(*){
let $diagnostics:=if($xml/self::ERROR) let $diagnostics:=if($xml/self::ERROR)
then array{lsp-diags:parse-error($text, $xml)} then array{lsp-diags:parse-error($text, $xml)}
else array{lsp-diags:parse-xquery($text,$xml)} else array{ lsp-diags:parse-xquery($text,$xml)}
return {"jsonrpc": "2.0", return {"jsonrpc": "2.0",
"method":"textDocument/publishDiagnostics", "method":"textDocument/publishDiagnostics",
@ -55,21 +55,22 @@ lsp-diags:nostic(pos:Range(pos:toPosition($text, $xml/@b),
lsp-diags:nostic(pos:Range(pos:toPosition($text, $xml/@e +1 ), lsp-diags:nostic(pos:Range(pos:toPosition($text, $xml/@e +1 ),
pos:toPosition($text, string-length($text)-1)), pos:toPosition($text, string-length($text)-1)),
$lsp-diags:severities('warning'), $lsp-diags:severities('warning'),
"Previous parse error") "Unparsed due to previous parser error.")
}; };
(: test data :) (: test data :)
declare function lsp-diags:parse-xquery($text as xs:string, $xml as element(Module)) declare function lsp-diags:parse-xquery($text as xs:string, $xml as element(Module))
as map(*)*{ as map(*)*{
lsp-diags:nostic(pos:Range(pos:Position(0,0), pos:Position(0, 5)), (: lsp-diags:nostic(pos:Range(pos:Position(0,0), pos:Position(0, 5)),
$lsp-diags:severities('error'),"111"), $lsp-diags:severities('error'),"error"),
lsp-diags:nostic(pos:Range(pos:Position(1,0), pos:Position(1,5)), lsp-diags:nostic(pos:Range(pos:Position(1,0), pos:Position(1,5)),
$lsp-diags:severities('warning'),"2222"), $lsp-diags:severities('warning'),"warning"),
lsp-diags:nostic(pos:Range(pos:Position(2,0), pos:Position(2, 5)), lsp-diags:nostic(pos:Range(pos:Position(2,0), pos:Position(2, 5)),
$lsp-diags:severities('info'),"333"), $lsp-diags:severities('info'),"info"),
lsp-diags:nostic(pos:Range(pos:Position(3,0), pos:Position(3, 6)),
$lsp-diags:severities('hint'), "hint") :)
lsp-diags:nostic(pos:Range(pos:Position(3,0), pos:Position(3, 12)),
$lsp-diags:severities('hint'), "44")
}; };

View file

@ -2,8 +2,10 @@
: @author andy bunce : @author andy bunce
:) :)
module namespace lsp-text = 'lsp-text'; module namespace lsp-text = 'lsp-text';
import module namespace docs="lsp/docs" at "docs.xqm"; import module namespace docs="lsp/docs" at "docs.xqm";
import module namespace rpc = 'rpc' at 'jsonrpc.xqm'; import module namespace rpc = 'rpc' at 'jsonrpc.xqm';
import module namespace pos="lsp/position" at "position.xqm";
declare variable $lsp-text:methods:=map{ declare variable $lsp-text:methods:=map{
"textDocument/didOpen": lsp-text:didOpen#1, "textDocument/didOpen": lsp-text:didOpen#1,
@ -21,24 +23,21 @@ declare
function lsp-text:hover($json as map(*)) function lsp-text:hover($json as map(*))
as map(*) as map(*)
{ {
map{
"jsonrpc": "2.0", let $r:= [
"id": $json?id,
"result":{
"contents": [
`markdown here, this is **bold**. `markdown here, this is **bold**.
A [link](http://google.com) A [link](http://google.com)
The last line.` The last line.`
, ,
`A hover at \\n\\n{ json:serialize($json?params?position) } `A hover at { pos:ln-col($json?params?position) }
uri: {$json?params?textDocument?uri} ` uri: {$json?params?textDocument?uri} `
] ]
} return rpc:response($r,$json)
}
}; };
declare declare
function lsp-text:completion($json as map(*)) function lsp-text:completion($json as map(*))
as map(*)? as map(*)?

View file

@ -23,12 +23,14 @@ declare record pos:Range(
end as pos:Position end as pos:Position
); );
(:~ update $text with changes $chs from didChange
:)
declare function pos:apply-changes($text as xs:string, $chs as array(*)) declare function pos:apply-changes($text as xs:string, $chs as array(*))
as xs:string{ as xs:string{
array:fold-left($chs,$text,pos:apply-change#2) array:fold-left($chs,$text,pos:apply-change#2)
}; };
(:~ text updated with $ch changes from didChange :) (:~ text updated single change :)
declare function pos:apply-change($text as xs:string, $ch as map(*)) declare function pos:apply-change($text as xs:string, $ch as map(*))
as xs:string{ as xs:string{
if(exists($ch?range)) if(exists($ch?range))
@ -83,4 +85,8 @@ as xs:integer
fn($r){$r?max eq $r?min} fn($r){$r?max eq $r?min}
) )
return $s?max return $s?max
}; };
declare function pos:ln-col($pos as pos:Position){
`Ln { $pos?line}, Col { $pos?character}`
};

View file

@ -77,7 +77,7 @@ function connect() {
function incoming(msg) { function incoming(msg) {
const rpc=JSON.parse(msg); const rpc=JSON.parse(msg);
log(rpc.method); log(rpc);
switch (rpc.method) { switch (rpc.method) {
case "textDocument/publishDiagnostics": case "textDocument/publishDiagnostics":
diags(rpc.params); diags(rpc.params);
@ -88,10 +88,13 @@ function incoming(msg) {
} }
}; };
function log(msg){
function log(rpc){
if(rpc.id) return
const text=rpc.method;
const li = document.createElement("li"); const li = document.createElement("li");
li.appendChild(document.createTextNode(msg)); li.appendChild(document.createTextNode(text));
const ol=document.getElementById("msg"); const ol=document.getElementById("msg");
ol.insertBefore(li,ol.firstChild) ol.insertBefore(li,ol.firstChild)
}; };