[mod] lineAt
This commit is contained in:
parent
8f2368ce7b
commit
5c759eb3f4
8 changed files with 618 additions and 37 deletions
|
|
@ -40,7 +40,7 @@ as map(*){
|
|||
declare function lsp-diags:parse-error($text as xs:string, $xml as element(ERROR))
|
||||
as map(*)?{
|
||||
|
||||
lsp-diags:nostic(pos:Range(pos:toPosition($xml, $xml/@b),
|
||||
pos:toPosition($xml, $xml/@e)),
|
||||
1,$xml/string())
|
||||
lsp-diags:nostic(pos:Range(pos:toPosition($text=>trace("EXML "), $xml/@b),
|
||||
pos:toPosition($text, $xml/@e)),
|
||||
1,$xml/string())=>trace("EEEE ")
|
||||
};
|
||||
|
|
@ -37,43 +37,48 @@ as xs:string{
|
|||
};
|
||||
|
||||
(:~ find index from Position :)
|
||||
declare function pos:resolvePosition($text as xs:string, $pos as map(*))
|
||||
declare function pos:resolvePosition($text as xs:string, $pos as pos:Position)
|
||||
as xs:integer
|
||||
{
|
||||
let $nl:= index-of(string-to-codepoints($text),10)
|
||||
let $_:=trace(count($nl),"lines ")
|
||||
let $s:= while-do(
|
||||
map{"off":0,"line":0},
|
||||
fn($r, $i){$r?line < $pos?line},
|
||||
fn($r,$i){ let $next:=$nl[$i]
|
||||
return if(empty($next))
|
||||
then error(xs:QName("docs:range"),"bad line")
|
||||
else {"off": $next+1,"line":$r?line+1} }
|
||||
)
|
||||
let $off:= $s?off+$pos?character
|
||||
return if($off>string-length($text))
|
||||
then error(xs:QName("docs:range"),"bad offset")
|
||||
else xs:integer($off)
|
||||
|
||||
let $off:=if($pos?line eq 0)
|
||||
then 0
|
||||
else $nl[$pos?line]
|
||||
return $off+$pos?character
|
||||
};
|
||||
|
||||
(:~ convert index into Position :)
|
||||
declare function pos:toPosition($text as xs:string, $index as xs:integer)
|
||||
declare function pos:toPosition($text as xs:string,
|
||||
$index as xs:integer
|
||||
)
|
||||
as pos:Position {
|
||||
let $nl:= index-of(string-to-codepoints($text),10)
|
||||
let $_:=trace(count($nl),"lines ")
|
||||
|
||||
let $predicate:=fn($r, $i){
|
||||
let $next:=$nl[$i]
|
||||
return exists($next) and $next < $index
|
||||
}
|
||||
|
||||
let $s:= while-do(
|
||||
map{"off":0,"line":0},
|
||||
$predicate,
|
||||
fn($r,$i){ let $next:=$nl[$i] return {"off": $next+1,"line":$r?line+1}=>trace("AA ") }
|
||||
)
|
||||
return pos:Position($s?line, $index - $s?off)
|
||||
let $nl:= index-of(string-to-codepoints($text),10)
|
||||
let $line:=pos:lineAt($nl,$index)
|
||||
let $off:=if($line eq 0)
|
||||
then 0
|
||||
else $nl[$line]
|
||||
return pos:Position($line, $index - $off)
|
||||
};
|
||||
|
||||
|
||||
|
||||
(:~ line number for $pos :)
|
||||
declare function pos:lineAt($nl as xs:integer*,$pos as xs:integer)
|
||||
as xs:integer
|
||||
{
|
||||
if($pos le head($nl))
|
||||
then 0
|
||||
else if($pos gt foot($nl))
|
||||
then count($nl)
|
||||
else let $s:=do-until(
|
||||
{"min":1,"max":count($nl)},
|
||||
fn($r){
|
||||
let $mid:=round(($r?min+$r?max) div 2,0,"away-from-zero")
|
||||
return if ($nl[$mid] lt $pos)
|
||||
then map:put($r,"min",$mid)
|
||||
else map:put($r,"max",$mid -1)
|
||||
},
|
||||
fn($r){$r?max eq $r?min}
|
||||
)
|
||||
return $s?max
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue