[mod] lsp-typedefs

This commit is contained in:
Andy Bunce 2025-09-15 22:38:45 +01:00
parent 03e30fb082
commit 2c85aa10cc
8 changed files with 656 additions and 99 deletions

View file

@ -3,62 +3,5 @@ xquery version '4.0';
module namespace syms="lsp/symbols";
import module namespace pos="lsp/position" at "position.xqm";
declare type syms:SymbolKind as xs:integer;
declare type syms:SymbolTag as xs:string;
declare variable $syms:SymbolKindMap :={
'File': 1 ,
'Module': 2 ,
'Namespace': 3 ,
'Package': 4 ,
'Class': 5 ,
'Method': 6 ,
'Property': 7 ,
'Field': 8 ,
'Constructor': 9 ,
'Enum': 10 ,
'Interface': 11 ,
'Function': 12 ,
'Variable': 13 ,
'Constant': 14 ,
'String': 15 ,
'Number': 16 ,
'Boolean': 17 ,
'Array': 18 ,
'Object': 19 ,
'Key': 20 ,
'Null': 21 ,
'EnumMember': 22 ,
'Struct': 23 ,
'Event': 24 ,
'Operator': 25 ,
'TypeParameter': 26
};
declare record syms:DocumentSymbol(
(: The name of this symbol. Will be displayed in the user interface and
therefore must not be an empty string or a string only consisting of white spaces. :)
name as xs:string,
(: The kind of this symbol. :)
kind as syms:SymbolKind,
(: The range enclosing this symbol not including leading/trailing whitespace
but everything else like comments. This information is typically used to
determine if the clients cursor is inside the symbol to reveal it in the UI. :)
range as pos:Range,
(:The range that should be selected and revealed when this symbol is being
picked, e.g. the name of a function. Must be contained by the `range`. :)
selectionRange as pos:Range,
(: More detail for this symbol, e.g the signature of a function.:)
detail? as xs:string,
(: Tags for this document symbol. @since 3.16.0 :)
tags? as syms:SymbolTag*,
(: Children of this symbol, e.g. properties of a class. :)
children? as syms:DocumentSymbol*
);

View file

@ -2,7 +2,8 @@
@author Andy Bunce
:)
module namespace hnd="lsp/handlers";
import module namespace pos="lsp/position" at "position.xqm";
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
declare record hnd:hand(
result as item()*,
@ -33,15 +34,9 @@ declare function hnd:diags($parse as element(),$diags:=())
})
};
declare record hnd:symbol (
name as xs:string,
type as xs:string,
range-name? as pos:Range,
range-full? as pos:Range,
children? as array(hnd:symbol)
);
declare function hnd:symbols($parse as element(),$syms as hnd:symbol* :=() )
declare function hnd:symbols($parse as element(),$syms as lspt:symbol* :=() )
{
'todo'
};
@ -49,7 +44,7 @@ declare function hnd:symbols($parse as element(),$syms as hnd:symbol* :=() )
declare function hnd:anotated-declaration($parse as element(),$syms)
as hnd:hand
{
let $sym:=hnd:symbol(
let $sym:=lspt:symbol(
$parse/token,
"AA"
)

View file

@ -1,5 +1,6 @@
module namespace lsp-diags = 'lsp-diags';
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
import module namespace pos="lsp/position" at "position.xqm";
declare type lsp-diags:ParseResult as element(Module|ERROR);
@ -14,7 +15,7 @@ renderMessage?: fn(view: EditorView) → Node An optional custom rendering fu
actions?: readonly Action[] An optional array of actions that can be taken on this diagnostic.
:)
declare record lsp-diags:nostic(
range as pos:Range,
range as lspt:Range,
severity as xs:integer, (: enum('error', 'hint', 'info', 'warning') :)
message as xs:string,
code? as xs:string,
@ -59,7 +60,7 @@ as map(*)*{
let $e:= number($xml/@e)-1
return (
(: mark error :)
lsp-diags:nostic(pos:Range(pos:toPosition($text, $b),
lsp-diags:nostic(lspt:Range(pos:toPosition($text, $b),
pos:toPosition($text, $e)),
1,
$dmesg,'XPST0003'),
@ -67,7 +68,7 @@ as map(*)*{
(:mark after error:)
if($e ge string-length($text))
then ()
else lsp-diags:nostic(pos:Range(pos:toPosition($text, $e +1 ),
else lsp-diags:nostic(lspt:Range(pos:toPosition($text, $e +1 ),
pos:toPosition($text, $last)),
2,
"Unparsed due to previous parser error.",

View file

@ -0,0 +1,97 @@
(:~ LSPserver type definitions
@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
@author Andy Bunce
:)
module namespace lspt = 'lsp-typedefs';
(:~ json numbers :)
declare type lspt:num as (xs:integer|xs:double);
(:~
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record lspt:Position(
line as lspt:num,
character as lspt:num
);
(:~
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record lspt:Range(
start as lspt:Position,
end as lspt:Position
);
declare type lspt:SymbolKind as xs:integer;
declare type lspt:SymbolTag as xs:string;
declare record lspt:symbol (
name as xs:string,
type as xs:string,
range-name? as lspt:Range,
range-full? as lspt:Range,
children? as array(lspt:symbol)
);
declare record lspt:DocumentSymbol(
(: The name of this symbol. Will be displayed in the user interface and
therefore must not be an empty string or a string only consisting of white spaces. :)
name as xs:string,
(: The kind of this symbol. :)
kind as lspt:SymbolKind,
(: The range enclosing this symbol not including leading/trailing whitespace
but everything else like comments. This information is typically used to
determine if the clients cursor is inside the symbol to reveal it in the UI. :)
range as lspt:Range,
(:The range that should be selected and revealed when this symbol is being
picked, e.g. the name of a function. Must be contained by the `range`. :)
selectionRange as lspt:Range,
(: More detail for this symbol, e.g the signature of a function.:)
detail? as xs:string,
(: Tags for this document symbol. @since 3.16.0 :)
tags? as lspt:SymbolTag*,
(: Children of this symbol, e.g. properties of a class. :)
children? as lspt:DocumentSymbol*
);
declare variable $lspt:SymbolKindMap :={
'File': 1 ,
'Module': 2 ,
'Namespace': 3 ,
'Package': 4 ,
'Class': 5 ,
'Method': 6 ,
'Property': 7 ,
'Field': 8 ,
'Constructor': 9 ,
'Enum': 10 ,
'Interface': 11 ,
'Function': 12 ,
'Variable': 13 ,
'Constant': 14 ,
'String': 15 ,
'Number': 16 ,
'Boolean': 17 ,
'Array': 18 ,
'Object': 19 ,
'Key': 20 ,
'Null': 21 ,
'EnumMember': 22 ,
'Struct': 23 ,
'Event': 24 ,
'Operator': 25 ,
'TypeParameter': 26
};
declare type lspt:TraceValue as enum( 'off' , 'messages' , 'verbose');

View file

@ -2,32 +2,13 @@
positions in text
:)
module namespace pos="lsp/position";
import module namespace lspt = 'lsp-typedefs' at "lsp-typedefs.xqm";
(:~ json numbers :)
declare type pos:num as (xs:integer|xs:double);
(:~
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record pos:Position(
line as pos:num,
character as pos:num
);
(:~
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record pos:Range(
start as pos:Position,
end as pos:Position
);
(:~ find index from Position :)
declare function pos:resolvePosition($text as xs:string, $pos as pos:Position)
as pos:num
declare function pos:resolvePosition($text as xs:string, $pos as lspt:Position)
as lspt:num
{
let $nl:= index-of(string-to-codepoints($text),10)
let $off:=if($pos?line eq 0)
@ -38,9 +19,9 @@ as pos:num
(:~ convert index into Position :)
declare function pos:toPosition($text as xs:string,
$index as pos:num
$index as lspt:num
)
as pos:Position {
as lspt:Position {
let $nl:= if($index=>trace("IN ") gt string-length($text)=>trace("L "))
then error(xs:QName("pos:range"),`out of range: index={$index},length={string-length($text)}`)
else index-of(string-to-codepoints($text),10)
@ -48,13 +29,13 @@ as pos:Position {
let $off:=if($line eq 0)
then 0
else $nl[$line]
return pos:Position($line, $index - $off)
return lspt:Position($line, $index - $off)
};
(:~ line number for $pos :)
declare function pos:lineAt($nl as xs:integer*,$pos as pos:num)
declare function pos:lineAt($nl as xs:integer*,$pos as lspt:num)
as xs:integer
{
if(empty($nl) or $pos le head($nl))
@ -75,7 +56,7 @@ as xs:integer
};
(:~ format position for text display :)
declare function pos:ln-col($pos as pos:Position,$offset as xs:integer:=1)
declare function pos:ln-col($pos as lspt:Position,$offset as xs:integer:=1)
{
`Ln { $pos?line + $offset}, Col { $pos?character + $offset}`
};
@ -99,6 +80,6 @@ as xs:string{
(:~ full range for $text :)
declare function pos:full-range($text as xs:string)
as pos:Range{
pos:Range(pos:toPosition($text,0), pos:toPosition($text, string-length($text)))
as lspt:Range{
lspt:Range(pos:toPosition($text,0), pos:toPosition($text, string-length($text)))
};