From 49b4b1529aa7222a3b18a54945f7010b73316dfe Mon Sep 17 00:00:00 2001 From: Andy Bunce Date: Thu, 7 Aug 2025 23:06:42 +0100 Subject: [PATCH] [mod] lsprpc->rpc --- test/didchange.xq | 3 ++- webapp/lsp/docs.xqm | 19 ++++++++++++++++--- webapp/lsp/etc/capabilities.json | 2 +- webapp/lsp/jsonrpc.xqm | 31 ++++++++++++++++++++----------- webapp/lsp/lsp-text.xqm | 26 +++++++++----------------- webapp/lsp/lsp-ws.xqm | 6 +++--- 6 files changed, 51 insertions(+), 36 deletions(-) diff --git a/test/didchange.xq b/test/didchange.xq index e0a3c66..112a9fb 100644 --- a/test/didchange.xq +++ b/test/didchange.xq @@ -11,4 +11,5 @@ cccccc`; (: return pos:resolvePosition($text,$p) :) pos:apply-changes($text,$msg?params?contentChanges) -(: $msg?params?contentChanges :) \ No newline at end of file +(: $msg?params?contentChanges :) +,$msg \ No newline at end of file diff --git a/webapp/lsp/docs.xqm b/webapp/lsp/docs.xqm index 4d1aafe..fede9ee 100644 --- a/webapp/lsp/docs.xqm +++ b/webapp/lsp/docs.xqm @@ -6,6 +6,7 @@ module namespace docs="lsp/docs"; import module namespace p="xq4" at "xq4.xqm"; import module namespace pos="lsp/position" at "position.xqm"; +import module namespace rpc = 'rpc' at 'jsonrpc.xqm'; (: save $textDocument data as session $socket properties @return uri @@ -52,9 +53,9 @@ let $text:=if($ver eq 1+ $file?version) else error("bad ver") let $file:=$file=>map:put("version",$ver)=>map:put("text",$text) -return (ws:set($socket,$key,$file), - `{$uri} V{ $ver} text: { $text}` - ) +return ( ws:set($socket,$key,$file) + , $uri) + }; (:~ close a file :) @@ -91,5 +92,17 @@ declare function docs:key( ) as xs:string? { ws:get($socket,"files")($file)($property) +}; +declare function docs:parse( + $socket as xs:string, + $file as xs:string +)as map(*)? +{ + let $text:=docs:key($socket,$file,"textDocument") + let $xml:= p:parse-Module($text)=>prof:time("⏱️ p:parse-Module " || $file) + return ( + ws:set($socket,docs:key($socket,$file,"parse"),$xml), + rpc:log(`done {$xml/name(.)}`) + ) }; \ No newline at end of file diff --git a/webapp/lsp/etc/capabilities.json b/webapp/lsp/etc/capabilities.json index 51c1be2..ddf947b 100644 --- a/webapp/lsp/etc/capabilities.json +++ b/webapp/lsp/etc/capabilities.json @@ -6,7 +6,7 @@ "triggerCharacters": [ "\"", ":" ], "documentSelector": [{ "language": "xquery" }] }, - "hoverProvider": true, + "hoverProvider": false, "documentSymbolProvider": true, "documentRangeFormattingProvider": false, "colorProvider": {}, diff --git a/webapp/lsp/jsonrpc.xqm b/webapp/lsp/jsonrpc.xqm index 997479f..352dca2 100644 --- a/webapp/lsp/jsonrpc.xqm +++ b/webapp/lsp/jsonrpc.xqm @@ -2,22 +2,22 @@ : jsonrpc : @author andy bunce :) -module namespace lsprpc = 'lsprpc'; +module namespace rpc = 'rpc'; import module namespace lsp-text = 'lsp-text' at "lsp-text.xqm"; (: map methods to functions :) -declare variable $lsprpc:methods:=map:merge(( +declare variable $rpc:methods:=map:merge(( map{ - "initialize" : lsprpc:method-initialize#1, - "initialized" : lsprpc:method-initialized#1, - "workspace/didChangeConfiguration" :lsprpc:method-unknown#1 + "initialize" : rpc:method-initialize#1, + "initialized" : rpc:method-initialized#1, + "workspace/didChangeConfiguration" :rpc:method-unknown#1 }, $lsp-text:methods )); (:~ return map if $msg is jsonrpc else empty :) declare -function lsprpc:parse($msg as xs:string) +function rpc:parse($msg as xs:string) as map(*)? { try { @@ -33,17 +33,17 @@ as map(*)? (:~ send replay to $json :) declare -function lsprpc:reply($json as map(*)) +function rpc:reply($json as map(*)) as empty-sequence() { let $method := $json?method - let $f :=$lsprpc:methods?($method) + let $f :=$rpc:methods?($method) let $response := $f!.($json) return if(exists($response)) then ws:send($response=>trace("REPLY: "),ws:id()) }; (:~ canned initialize response :) declare -function lsprpc:method-initialize($json as map(*)) +function rpc:method-initialize($json as map(*)) as map(*) { { @@ -55,7 +55,7 @@ as map(*) (:~ initialized response :) declare -function lsprpc:method-initialized($json as map(*)) +function rpc:method-initialized($json as map(*)) as empty-sequence() { ws:set(ws:id(),"initialized", true()) @@ -63,10 +63,19 @@ as empty-sequence() (:~ unknown method response :) declare -function lsprpc:method-unknown($json as map(*)) +function rpc:method-unknown($json as map(*)) as map(*)? { let $_:=trace($json?method,"unknown") return () }; +(:~ rpc log message :) +declare function rpc:log($msg as xs:string) +as map(*) +{ +{"jsonrpc": "2.0", + "method":"window/logMessage", + "params":{"type":1, "message": $msg} + } +}; \ No newline at end of file diff --git a/webapp/lsp/lsp-text.xqm b/webapp/lsp/lsp-text.xqm index 1cb29fe..19f326a 100644 --- a/webapp/lsp/lsp-text.xqm +++ b/webapp/lsp/lsp-text.xqm @@ -1,8 +1,9 @@ -(:~ handle text messages +(:~ handle textDocument messages : @author andy bunce :) module namespace lsp-text = 'lsp-text'; import module namespace docs="lsp/docs" at "docs.xqm"; +import module namespace rpc = 'rpc' at 'jsonrpc.xqm'; declare variable $lsp-text:methods:=map{ "textDocument/didOpen": lsp-text:didOpen#1, @@ -53,7 +54,7 @@ as map(*)? (:~ didOpen method response :) declare function lsp-text:didOpen($json as map(*)) -as empty-sequence() +as map(*)? { let $uri:=docs:open(ws:id(),$json?params)=>prof:time("⏱️ doc:save ") @@ -65,13 +66,9 @@ as empty-sequence() { 'cache': true() } ) :) - return ws:send( - {"jsonrpc": "2.0", - "method":"window/logMessage", - "params":{"type":1,"message":"saved " || $uri} - }, - ws:id() -) + return rpc:log("saved " || $uri) + + }; (:~ didChange method response :) @@ -79,15 +76,10 @@ declare function lsp-text:didChange($json as map(*)) as map(*)? { - let $msg:=docs:change(ws:id(),$json?params)=>prof:time("⏱️ doc:change ") + let $uri:=docs:change(ws:id(),$json?params)=>prof:time("⏱️ doc:change ") + + return docs:parse(ws:id(),$uri) - return ws:send( - {"jsonrpc": "2.0", - "method":"window/logMessage", - "params":{"type":1,"message":"changed " || $msg} - }, - ws:id() -) }; diff --git a/webapp/lsp/lsp-ws.xqm b/webapp/lsp/lsp-ws.xqm index d1da923..83d522f 100644 --- a/webapp/lsp/lsp-ws.xqm +++ b/webapp/lsp/lsp-ws.xqm @@ -4,7 +4,7 @@ :) module namespace lsp-ws = 'lsp-ws'; -import module namespace lsprpc = 'lsprpc' at 'jsonrpc.xqm'; +import module namespace rpc = 'rpc' at 'jsonrpc.xqm'; declare @@ -36,9 +36,9 @@ function lsp-ws:message( $message as xs:string ) as empty-sequence() { - let $json := lsprpc:parse($message=>trace("MSG ")) + let $json := rpc:parse($message=>trace("MSG ")) return if(exists($json)) - then lsprpc:reply($json) + then rpc:reply($json) else message($message,"bad RPC: ") };