basex-lsp/webapp/lsp/docs.xqm

95 lines
No EOL
2.5 KiB
Text

(: Store for XQuery document data , type, text,uri
on save parse is created and stored
data is stored in webSocket attributes
@author Andy Bunce
:)
module namespace docs="lsp/docs";
import module namespace p="xq4" at "xq4.xqm";
import module namespace pos="lsp/position" at "position.xqm";
(: save $textDocument data as session $socket properties
@return uri
:)
declare function docs:open(
$socket as xs:string,
$params as map(*)
) as xs:string
{
let $text as xs:string:=$params?textDocument?text
let $uri:=$params?textDocument?uri
let $files:=ws:get($socket,"files",{})
let $files:=if(map:contains($files,$uri))
then $files
else
let $uuid:=random:uuid()
return map:put($files,$uri,{
"textDocument": "file-" || $uuid,
"parse": "parse-" || $uuid })
let $keys:=$files($uri)
return (
ws:set($socket,"files",$files),
ws:set($socket,$keys?textDocument,$params?textDocument),
$uri
)
};
(: change $textDocument data as session $socket properties
@return uri
:)
declare function docs:change(
$socket as xs:string,
$params as map(*)
) as xs:string
{
let $uri:=$params?textDocument?uri
let $key:=docs:key($socket,$uri,"textDocument")
let $file:=if(exists($key))
then ws:get($socket,$key)
else error("no file")
let $ver:=$params?textDocument?version
let $text:=if($ver eq 1+ $file?version)
then pos:apply-changes($file?text,$params?contentChanges)
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}`
)
};
(:~ close a file :)
declare function docs:close($socket as xs:string,$uri as xs:string)
as map(*){
let $files:=ws:get($socket,"files",{})
return if(map:contains($files,$uri))
then let $props:=$files($uri)
return (
map:items($props)!ws:delete($socket,.),
ws:set($socket,"files",map:remove($files,$uri))
)
else ()
};
(:~ list of all files :)
declare function docs:list($socket as xs:string)
as xs:string*{
ws:get($socket,"files",{})=>map:keys()
};
(: document info :)
declare type docs:property as enum(
"textDocument",
"parse"
);
(: get $property key for $file from session $socket :)
declare function docs:key(
$socket as xs:string,
$file as xs:string,
$property as docs:property
) as xs:string?
{
ws:get($socket,"files")($file)($property)
};