basex-lsp/webapp/lsp/lsp-text.xqm

111 lines
No EOL
2.5 KiB
Text

(:~ 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';
import module namespace pos="lsp/position" at "position.xqm";
declare variable $lsp-text:methods:=map{
"textDocument/didOpen": lsp-text:didOpen#1,
"textDocument/didChange": lsp-text:didChange#1,
"textDocument/didClose" : lsp-text:method-unknown#1,
"textDocument/hover": lsp-text:hover#1,
"textDocument/completion": lsp-text:completion#1,
"textDocument/formatting" : lsp-text:format#1
};
(:~ hover :)
declare
function lsp-text:hover($json as map(*))
as map(*)
{
let $r:= [
`markdown here, this is **bold**.
A [link](http://google.com)
The last line.`
,
`A hover at { pos:ln-col($json?params?position) } uri: {$json?params?textDocument?uri} `
]
return rpc:result({"contents":$r},$json)
};
declare
function lsp-text:completion($json as map(*))
as map(*)?
{
let $doc:=$json?params?textDocument?uri
return map{
"jsonrpc": "2.0",
"id": $json?id,
"result":()
}
};
declare
function lsp-text:format($json as map(*))
as map(*)?
{
let $uri:=$json?params?textDocument?uri
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)
else
let $xml:=$xml update {lsp-text:tidy(.)}
let $fmt:=`(: formatting to do :)
`
return rpc:result([{
"range":pos:full-range($text),
"newText": $fmt || string($xml)
}],$json)
};
(:~ didOpen method response :)
declare
function lsp-text:didOpen($json as map(*))
as map(*)?
{
let $uri:=docs:open(ws:id(),$json?params)=>prof:time("⏱️ doc:save ")
return docs:parse(ws:id(),$uri)
};
(:~ didChange method response :)
declare
function lsp-text:didChange($json as map(*))
as map(*)?
{
let $uri:=docs:change(ws:id(),$json?params)=>prof:time("⏱️ doc:change ")
return docs:parse(ws:id(),$uri)
};
(:~ unknown method response :)
declare
function lsp-text:method-unknown($json as map(*))
as map(*)?
{
let $_:=trace($json?method,"unknown")
return ()
};
(:~ ensure spaces around := :)
declare %updating function lsp-text:tidy($doc){
for $a in $doc//TOKEN[.=":="]
let $before:= $a/preceding-sibling::node()[1]
let $after:= $a/following-sibling::node()[1]
return (
if($before instance of element(*))
then insert node " " before $a else (),
if($after instance of element(*))
then insert node " " after $a else ()
)
};