basex-lsp/webapp/lsp/lsp-text.xqm
2025-10-11 15:50:06 +01:00

119 lines
No EOL
3.4 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(:~ 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 lspt = 'lsp-typedefs' at 'lsp-typedefs.xqm';
import module namespace pos="lsp/position" at "position.xqm";
import module namespace syms="lsp/symbols" at "providers/documentSymbols.xqm";
import module namespace comp = 'lsp-completions' at "providers/completions.xqm";
import module namespace hov = 'lsp-hover' at "providers/hover.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,
"textDocument/documentSymbol" : lsp-text:symbols#1
};
declare variable $lsp-text:word-reg:="[A-Z]|_|[a-z]|[À-Ö]|[Ø-ö]|[ø-˿]|[Ͱ-ͽ]|[Ϳ-῿]|[-]|[⁰-↏]|[Ⰰ-⿯]|[、-퟿]|[豈-﷏]|[ﷰ-<2D>]";
(:~ hover :)
declare
function lsp-text:hover($json as map(*))
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)})
};
(:~ symbols :)
declare
function lsp-text:symbols($json as map(*))
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))
};
declare
function lsp-text:completion($json as map(*))
as map(*)?
{
let $doc:=$json?params?textDocument?uri
let $context:=$json?params?context (:{"triggerCharacter":":","triggerKind":2.0e0}:)
let $result:=comp:list($context)
return rpc:result($json,array:build($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 $result:=[{
"range":pos:full-range($text),
"newText": string($xml)
}]
return rpc:result($json,$result)
};
(:~ 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 ()
)
};