diff --git a/webapp/lsp-manager/app.xqm b/webapp/lsp-manager/app.xqm index 3d2d264..f4b9260 100644 --- a/webapp/lsp-manager/app.xqm +++ b/webapp/lsp-manager/app.xqm @@ -67,7 +67,7 @@ function app:socket($wsid) { "connectTime": ws:get($wsid,"connectTime"), "files": map:keys($files), "file1": json:serialize($file, { 'format': 'w3', 'indent': 'no' }), - "doc": json:serialize($doc, { 'format': 'w3', 'indent': 'no' }) + "doc": $doc }) }; diff --git a/webapp/lsp-manager/static/script.js b/webapp/lsp-manager/static/script.js new file mode 100644 index 0000000..8826b52 --- /dev/null +++ b/webapp/lsp-manager/static/script.js @@ -0,0 +1 @@ +// todo \ No newline at end of file diff --git a/webapp/lsp-manager/views/socket.htm b/webapp/lsp-manager/views/socket.htm index 2a1fbbf..27e1235 100644 --- a/webapp/lsp-manager/views/socket.htm +++ b/webapp/lsp-manager/views/socket.htm @@ -16,8 +16,13 @@
-
doc
-
doc
+
doc
+ +
doc
+
doc
+
doc
+
+
doc
diff --git a/webapp/lsp/jsonrpc.xqm b/webapp/lsp/jsonrpc.xqm index 2a647da..b69e822 100644 --- a/webapp/lsp/jsonrpc.xqm +++ b/webapp/lsp/jsonrpc.xqm @@ -5,6 +5,24 @@ module namespace rpc = 'rpc'; import module namespace lsp-text = 'lsp-text' at "lsp-text.xqm"; +(:~ build a notification :) +declare function rpc:build-notification ($method as xs:string, $params as map(*)) +as map(*){ +{"jsonrpc": "2.0", "method": $method, "params": $params } +}; + +(:~ response to $json msg, if result empty just acknowledge :) +declare function rpc:build-response($json as map(*),$result:=()) +as map(*){ +{ "jsonrpc": "2.0", "id": $json?id, "result": $result} +}; + +(:~ response when error :) +declare function rpc:build-error($info as map(*),$json as map(*)) +as map(*){ + { "jsonrpc": "2.0", "id": $json?id, "error": $info } +}; + (: map methods to functions :) declare variable $rpc:Methods:=map:merge(( map{ @@ -22,7 +40,7 @@ as map(*)? { try { let $json:=parse-json($msg) - return if($json?jsonrpc="2.0" and exists($json?method)) + return if($json?jsonrpc eq "2.0" and exists($json?method)) then $json else () } catch *{ @@ -39,8 +57,10 @@ as map(*)? declare function rpc:reply($json as map(*)) as empty-sequence() { - let $f :=(message($json,"➡️"), - $rpc:Methods?($json?method)) + let $f :=( + rpc:admin-log($json,"➡️"), + $rpc:Methods?($json?method) + ) let $response := $f!.($json) return $response!rpc:send(.) }; @@ -50,7 +70,7 @@ declare function rpc:send($msg as map(*)) as empty-sequence() { - ws:send($msg =>trace("⬅️"),ws:id()) + rpc:admin-log($msg,"⬅️"),ws:send($msg ,ws:id()) }; (:~ canned initialize response :) @@ -59,7 +79,7 @@ function rpc:method-initialize($json as map(*)) as map(*) { ws:set(ws:id(),"client", $json?params), - rpc:result($json, + rpc:build-response($json, json:doc("etc/capabilities.json",{"format":"w3"})) }; @@ -85,38 +105,20 @@ as map(*)? declare function rpc:log($msg as xs:string) as map(*) { -{"jsonrpc": "2.0", - "method":"window/logMessage", - "params":{"type":1, "message": $msg} - } + rpc:build-notification( + "window/logMessage", + {"type":1, "message": $msg} +) }; -(:~ rpc response to $json msg, if result empty just acknowledge :) -declare function rpc:result($json as map(*),$result:=()) -as map(*) +(:~ write to admin:log :) +declare function rpc:admin-log($data as item()*,$emoji as xs:string) +as empty-sequence() { -map{ - "jsonrpc": "2.0", - "id": $json?id, - "result": $result -} + let $msg:= json:serialize($data,{ 'format': 'w3', 'indent': 'no' }) + return admin:write-log($emoji || $msg,"LSP") }; -(:~ response when error :) -declare function rpc:error($message as xs:string,$json as map(*)) -{ - { - "jsonrpc": "2.0", - "id": $json?id, - "error": { - "code": -32803, - "message": $message, - "data": { "documentUri": "file:///example.txt", - "reason": "Syntax block" - } - } -} -}; (:~ window/showMessage :) declare function rpc:show-message($msg as xs:string) diff --git a/webapp/lsp/lsp-text.xqm b/webapp/lsp/lsp-text.xqm index 83102be..165f70b 100644 --- a/webapp/lsp/lsp-text.xqm +++ b/webapp/lsp/lsp-text.xqm @@ -32,7 +32,7 @@ as map(*) let $pos:=$json?params?position let $uri:= $json?params?textDocument?uri let $r:=hov:list($uri,$pos) -return rpc:result($json,{"contents":array:build($r)}) +return rpc:build-response($json,{"contents":array:build($r)}) }; (:~ symbols :) @@ -43,7 +43,7 @@ as map(*)? let $uri:=$json?params?textDocument?uri let $xml:=docs:get(ws:id(), $uri, "parse") let $syms:=syms:list($xml,string($xml)) - return rpc:result($json,array:build($syms)) + return rpc:build-response($json,array:build($syms)) }; declare @@ -53,7 +53,7 @@ as map(*)? let $uri:=$json?params?textDocument?uri let $context:=$json?params?context (:{"triggerCharacter":":","triggerKind":2.0e0}:) let $result:=comp:list($context)=>prof:time("⏱️ completions " || $uri) - return rpc:result($json,array:build($result)) + return rpc:build-response($json,array:build($result)) }; declare @@ -64,14 +64,18 @@ as map(*)? let $text:=docs:get(ws:id(), $uri, "textDocument")?text let $xml:=docs:get(ws:id(), $uri, "parse") return if($xml/self::ERROR) - then rpc:error("Syntax errors found.",$json) + then rpc:build-error( + { "code": -32803, "message": "Syntax errors found.", + "data": { "documentUri": $uri, "reason": "Syntax errors found." } + } + ,$json) else let $xml:=$xml update {lsp-text:tidy(.)} let $result:=[{ "range":pos:full-range($text), "newText": string($xml) }] - return rpc:result($json,$result) + return rpc:build-response($json,$result) }; (:~ didOpen method response :) diff --git a/webapp/lsp/lsp-ws.xqm b/webapp/lsp/lsp-ws.xqm index 942b902..378af2d 100644 --- a/webapp/lsp/lsp-ws.xqm +++ b/webapp/lsp/lsp-ws.xqm @@ -17,7 +17,7 @@ function lsp-ws:error($error) { declare %ws:connect('/lsp') function lsp-ws:connect() as empty-sequence() { -let $id:=ws:id()=>trace("CONNECT: ") +let $id:=(ws:id(),rpc:admin-log("CONNECT","🌹")) return ( ws:set($id, "id", $id), ws:set($id, "connectTime", current-dateTime()), @@ -48,5 +48,5 @@ function lsp-ws:message( declare %ws:close('/lsp') function lsp-ws:close() as empty-sequence() { - message("SOCKET CLOSE: " || ws:id()) + rpc:admin-log("CLOSE","🥀") };