diff --git a/README.md b/README.md index 87f1efb..7af9bc6 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Document structure for editor \ No newline at end of file +Manage a document's content as a sequence of lines. \ No newline at end of file diff --git a/src/doci.xqm b/src/doci.xqm index f0c7f12..74cc943 100644 --- a/src/doci.xqm +++ b/src/doci.xqm @@ -66,9 +66,10 @@ declare function doci:text($doci as doci:doci) as xs:string{ string-join($doci?lines,$doci?separator) }; + (: number of lines:) declare function doci:lines($doci as doci:doci) -as xs:string{ +as xs:integer{ $doci?lines=>count() }; @@ -82,30 +83,39 @@ switch () { default return $doci:default-separator } }; + (: apply change:) -declare function doci:change($doci as doci:doci,$change as doci:TextDocumentContentChangeEvent) +declare function doci:update($doci as doci:doci,$change as doci:TextDocumentContentChangeEvent) as doci:doci{ - let $lines:= doci:split-lines($change?text) - return if(empty($change?range)) - then doci:doci($lines,$doci?separator) - else let $range:=$change?range - let $sline:=$range?start?line - let $eline:=$range?end?line - return switch(){ - case $sline eq $eline and count($lines) eq 1 - return let $line:=$doci?lines[$sline+1] - let $new:=substring($line,1,$range?start?character) - || $lines || - substring($line,1+$range?end?character) +let $lines:= doci:split-lines($change?text) +return if(empty($change?range)) + then doci:doci($lines,$doci?separator) + else + let $range:=$change?range + let $sline:= $range?start?line + let $eline:= $range?end?line - let $ulines:=( $doci?lines[position() le $sline], - $new, - $doci?lines[position() gt 1+$sline] - ) - return doci:doci($ulines, $doci?separator) + (: string from start line before insert :) + let $head:= substring( $doci?lines[$sline+1] ,1, $range?start?character ) + (: string from edit end to end of line :) + let $head:= substring( $doci?lines[$sline+1] ,1, $range?start?character ) + let $last := substring( $doci?lines[$eline+1] , $range?end?character +1) - default return error(#doci:change,"oh") - } +let $ulines := ( + subsequence($doci?lines, 1, $sline) (: lines before edit :) + , + if($sline eq $eline) + then ($head || $lines[1] || $last) + + else ( + $head || $lines[1], + subsequence( $lines,2, count( $lines - 2)), + $lines[last()] ||$last + ), + + subsequence($doci?lines, $eline+2) (: lines after edit :) + ) +return doci:doci($ulines,$doci?separator) }; declare function doci:split-lines($text as xs:string) diff --git a/test/doci.xq b/test/doci.xq deleted file mode 100644 index 64eb4fd..0000000 --- a/test/doci.xq +++ /dev/null @@ -1,10 +0,0 @@ -import module namespace doci = 'urn:doci' at "../src/doci.xqm"; - -declare variable $long:= -file:read-text("C:\Users\mrwhe\git\quodatum\basex-lsp\test\sample.docs\pdfbox.xqm"); -declare variable $text:=`ABV -ddddd -`; - - -doci:build($long)?length \ No newline at end of file diff --git a/test/simple.xqm b/test/simple.xqm index 9c4cf1d..7cee11f 100644 --- a/test/simple.xqm +++ b/test/simple.xqm @@ -2,11 +2,12 @@ module namespace test = 'test:doci'; import module namespace doci = 'urn:doci' at "../src/doci.xqm"; + (:~ we can create record from file :) declare %unit:test function test:from-file() { let $doc:=test:read("resources/doc1.txt") let $doci:= doci:build($doc) - return test:expected($doc,$doci,530) + return test:expected($doci,$doc,530) }; @@ -14,7 +15,7 @@ declare %unit:test function test:from-file() { declare %unit:test function test:from-string1() { let $doc:="a one line string" let $doci:= doci:build($doc) - return test:expected($doc,$doci,1) + return test:expected($doci, $doc, 1) }; (:~ we can create record from string :) @@ -22,39 +23,43 @@ declare %unit:test function test:from-string2() { let $doc:="a two line string second line" let $doci:= doci:build($doc) - return test:expected($doc,$doci,2) + return test:expected($doci,$doc,2) }; (:~ we can create update from string :) -declare %unit:test function test:update1() { +declare %unit:test function test:update-start() { let $doc:="123456789" let $doci:= doci:build($doc) - let $change:=test:change("*",0,0,0,0) - let $doci2:=doci:change($doci,$change)=>trace("A") + let $_:= test:expected($doci,$doc,1) + + let $change:=test:def-change("*",0,0,0,0) + let $doci2:=doci:update($doci,$change)=>trace("US1") + let $_:= test:expected($doci2,"*" || $doc,1) - let $change2:=test:change("",0,0,0,1) - let $update:=doci:change($doci2,$change2)=>trace("b") + let $change2:=test:def-change("",0,0,0,1) + let $update:=doci:update($doci2,$change2)=>trace("b") + let $_:= doci:text($update)=>trace("test:update1") return () }; (:~ we can create update from string :) -declare %unit:test function test:update2() { +declare %unit:test function test:update-end() { let $doc:="a 123456789 b" let $doci:= doci:build($doc) - let $_:=test:expected($doc,$doci,3) - let $change:=test:change("*",1,9,1,9) - let $doci2:=doci:change($doci,$change)=>trace("A") + let $_:=test:expected($doci,$doc,3) + let $change:=test:def-change("*",1,9,1,9) + let $doci2:=doci:update($doci,$change) - let $change2:=test:change("",1,9,1,10) - let $update:=doci:change($doci2,$change2)=>trace("b") - return () + let $change2:=test:def-change("",1,9,1,10) + let $update:=doci:update($doci2,$change2) + return unit:assert-equals($doc,doci:text($update)) }; (: test $doci properties as expected :) -declare function test:expected($doc as xs:string, $doci as doci:doci, $lines as xs:integer){ - unit:assert-equals($doci?lines=>count(),$lines), +declare function test:expected($doci as doci:doci, $doc as xs:string, $lines as xs:integer){ + unit:assert-equals(doci:lines($doci),$lines), unit:assert($doci?separator!string-length(.)>0), unit:assert-equals($doc,doci:text($doci)) }; @@ -72,7 +77,7 @@ file:resolve-path($path,file:base-dir())=>file:read-text() }; (: create a change description:) -declare function test:change($text as xs:string, +declare function test:def-change($text as xs:string, $sline as xs:integer,$schar as xs:integer, $eline as xs:integer,$echar as xs:integer ) diff --git a/test/smoke.xq b/test/smoke.xq new file mode 100644 index 0000000..a3a918b --- /dev/null +++ b/test/smoke.xq @@ -0,0 +1,22 @@ +import module namespace doci = 'urn:doci' at "../src/doci.xqm"; + +declare variable $long:= +file:read-text("C:\Users\mrwhe\git\quodatum\basex-lsp\test\sample.docs\pdfbox.xqm"); +declare variable $text:="123456789"; + +(: create a change description:) +declare function local:change($text as xs:string, + $sline as xs:integer,$schar as xs:integer, + $eline as xs:integer,$echar as xs:integer + ) +as doci:TextDocumentContentChangeEvent{ +doci:TextDocumentContentChangeEvent( + $text, + doci:Range(doci:Position($sline,$schar),doci:Position($eline,$echar)) + ) +}; + + + +doci:build($text) +=>doci:change(local:change("*",0,0,0,0)) \ No newline at end of file