diff --git a/README.md b/README.md index 91e1cee..da7886e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ An attempt to write a language protocol server using BaseX features... * https://github.com/mkslanc/ace-linters https://mkslanc.github.io/ace-linters/ * 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` ## notes Using https://github.com/mkslanc/ace-linters https://mkslanc.github.io/ace-linters/ diff --git a/webapp/lsp/jsonrpc.xqm b/webapp/lsp/jsonrpc.xqm new file mode 100644 index 0000000..729574e --- /dev/null +++ b/webapp/lsp/jsonrpc.xqm @@ -0,0 +1,59 @@ +(:~ + : jsonrpc + : @author andy bunce + :) +module namespace lsprpc = 'lsprpc'; + +declare variable $lsprpc:methods:=map{ + "initialize" : lsprpc:method-initialize#1, + "initialized" : lsprpc:method-unknown#1, + "workspace/didChangeConfiguration" :lsprpc:method-unknown#1, + "textDocument/didOpen": lsprpc:method-unknown#1, + "textDocument/didClose" : lsprpc:method-unknown#1 +}; + +(:~ return map if $msg is jsonrpc else empty :) +declare +function lsprpc:parse($msg as xs:string) +as map(*)? +{ + try { + let $json:=parse-json($msg) + return if($json?jsonrpc="2.0" and exists($json?method)) + then $json + else () + } catch *{ + () + } + +}; + +(:~ send replay to $json :) +declare +function lsprpc:reply($json as map(*)) +as empty-sequence() { + let $method := $json?method + let $f :=$lsprpc: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(*)) +as map(*)? +{ + ``[{"jsonrpc":"2.0","id":0, +"result":{"capabilities":{"textDocumentSync":2,"completionProvider":{"resolveProvider":false,"triggerCharacters":["\"",":"]},"hoverProvider":true,"documentSymbolProvider":true,"documentRangeFormattingProvider":false,"colorProvider":{},"foldingRangeProvider":true,"selectionRangeProvider":true,"documentLinkProvider":{}}}}]`` + =>parse-json() +}; + +(:~ unknown method response :) +declare +function lsprpc:method-unknown($json as map(*)) +as map(*)? +{ + let $_:=trace($json?method,"unknown") + return () +}; + diff --git a/webapp/lsp/lsp-ws.xqm b/webapp/lsp/lsp-ws.xqm index fced4e4..6c7812b 100644 --- a/webapp/lsp/lsp-ws.xqm +++ b/webapp/lsp/lsp-ws.xqm @@ -1,9 +1,10 @@ (:~ - : Simple WebSocket chat. WebSocket functions. - : @author BaseX Team, BSD License + : WebSocket LSP + : @author Andy Bunce :) module namespace lsp-ws = 'lsp-ws'; +import module namespace lsprpc = 'lsprpc' at 'jsonrpc.xqm'; import module namespace chat-util = 'chat/util' at 'lsp-util.xqm'; declare @@ -18,9 +19,8 @@ function lsp-ws:error($error) { declare %ws:connect('/lsp') function lsp-ws:connect() as empty-sequence() { - let $_:=ws:id()=>trace("CONNECT2: ") - let $_:=session:get($chat-util:id)=>trace("CONNECTx: ") - return ws:set(ws:id()=>trace("CONNECT: "), $chat-util:id, "session:get($chat-util:id)") + + ws:set(ws:id()=>trace("CONNECT: "), $chat-util:id, "session:get($chat-util:id)") (: ,chat-util:users() :) }; @@ -33,15 +33,14 @@ declare function lsp-ws:message( $message as xs:string ) as empty-sequence() { - let $json := parse-json($message=>trace("MSG ")) - let $type := $json?type - return if($type = 'message') then ( - chat-util:message($json?text, $json?to) - ) else if($type = 'ping') then( - (: do nothing :) - ) else error() + + let $json := lsprpc:parse($message=>trace("MSG ")) + return if(exists($json)) + then lsprpc:reply($json) + else message($message,"bad RPC: ") }; + (:~ : Closes a WebSocket connection. Unregisters the user and notifies all clients. :) diff --git a/webapp/static/ace/esm.html b/webapp/static/ace/esm.html new file mode 100644 index 0000000..1f7ea6d --- /dev/null +++ b/webapp/static/ace/esm.html @@ -0,0 +1,41 @@ + + + +
+ + +