]> git.mdlowis.com Git - archive/tide-ocaml.git/commitdiff
added and tested nextc and prevc functions. Updated scrollmap to use them
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 4 Nov 2017 03:38:29 +0000 (23:38 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 4 Nov 2017 03:38:29 +0000 (23:38 -0400)
lib/rope.ml
lib/rope.mli
lib/scrollmap.ml
tests/rope_tests.ml

index 9956d514340868cdbfa4894920cbfa088c60abb9..5c078dbd16fe0c6181388f2db3d9dbab29137134 100644 (file)
@@ -12,6 +12,8 @@ let empty = Leaf ("", 0, 0)
 let from_string s =
   Leaf (s, 0, (String.length s))
 
+(******************************************************************************)
+
 let length = function
   | Leaf (_,_,l)   -> l
   | Node (_,_,_,l) -> l
@@ -33,6 +35,8 @@ let check_index rope i =
   if i < 0 || i >= (length rope) then
     raise (Out_of_bounds "Rope.check_index")
 
+(******************************************************************************)
+
 let join left right =
   let llen = (length left) and rlen = (length right) in
   if llen == 0 then right
@@ -40,11 +44,15 @@ let join left right =
   else
     let lh = (height left) and rh = (height right) in
     let nh = 1 + lh + rh in
+    Node (left, right, nh, llen + rlen)
+
+(*
     let n = Node (left, right, nh, llen + rlen) in
     match (lh - rh) with
     | 0  -> n
     | 1  -> n
     | -1 -> n
+*)
 
 let rec split rope i =
   if i < 0 || i > (length rope) then
@@ -66,6 +74,8 @@ let del rope i j =
   let (r_left,r_right) = split l_right (j - i) in
   (join l_left r_right)
 
+(******************************************************************************)
+
 let rec getb rope i =
   check_index rope i;
   match rope with
@@ -98,6 +108,8 @@ let rec getc rope i =
 
 let putc rope i c = rope
 
+(******************************************************************************)
+
 let rec iter_from fn rope pos =
   if pos < (length rope) && (fn (getc rope pos)) then
     iter_from fn rope (pos + 1)
@@ -106,6 +118,8 @@ let rec iteri_from fn rope pos =
   if pos < (length rope) && (fn pos (getc rope pos)) then
     iteri_from fn rope (pos + 1)
 
+(******************************************************************************)
+
 let gets rope i j =
   let buf = Bytes.create (j - i) in
   iteri_from
@@ -120,17 +134,38 @@ let rec puts rope s i =
   let middle = from_string s in
   (join (join left middle) right)
 
+(******************************************************************************)
+
+let nextc rope pos =
+  let next = limit_index rope (pos + 1) in
+  if (getb rope pos) == '\r' && (getb rope next) == '\n' then
+    limit_index rope (pos + 2)
+  else
+    next
+
+let prevc rope pos =
+  let prev1 = limit_index rope (pos - 1) in
+  let prev2 = limit_index rope (pos - 2) in
+  if (getb rope prev2) == '\r' && (getb rope prev1) == '\n' then
+    prev2
+  else
+    prev1
+
+(******************************************************************************)
+
 let is_bol rope pos =
   if pos == 0 then true
-  else ((getc rope (pos-1)) == 0x0A)
+  else let prev = (prevc rope pos) in
+  ((getc rope prev) == 0x0A)
 
 let is_eol rope pos =
   if pos >= (last rope) then true
-  else ((getc rope (pos+1)) == 0x0A)
+  else ((getc rope pos) == 0x0A)
 
 let rec move_till step testfn rope pos =
+  let adjust_pos = if step < 0 then prevc else nextc in
   if (testfn rope pos) then pos
-  else (move_till step testfn rope (pos + step))
+  else (move_till step testfn rope (adjust_pos rope pos))
 
 let to_bol rope pos =
   move_till (-1) is_bol rope pos
index 0f7e63ff10f76bd76127885dfaa252b4bb2430c3..227323b819d799ca59e1d75d7db582c64e9b80dd 100644 (file)
@@ -28,6 +28,9 @@ val putc : rope -> int -> rune -> rope
 val gets : rope -> int -> int -> string
 val puts : rope -> string -> int -> rope
 
+val nextc : rope -> int -> int
+val prevc : rope -> int -> int
+
 val is_bol : rope -> int -> bool
 val is_eol : rope -> int -> bool
 
index a8368fde86423a4a7472be089c3b53372289778e..6852a26153b9809b1658f376f40f977b976ef212 100644 (file)
@@ -28,12 +28,12 @@ let first map =
   map.lines.(map.index)
 
 let bopl buf off =
-  let next = ((Rope.to_bol (Buf.rope buf) off) - 2) in
-  Rope.limit_index (Buf.rope buf) next
+  let rope = (Buf.rope buf) in
+  Rope.prevc rope (Rope.to_bol rope off)
 
 let bonl buf off =
-  let next = ((Rope.to_eol (Buf.rope buf) off) + 2) in
-  Rope.limit_index (Buf.rope buf) next
+  let rope = (Buf.rope buf) in
+  Rope.nextc rope (Rope.to_eol rope off)
 
 let scroll_up map buf =
   let next = map.index - 1 in
index 5ec2bbf8471599e438c5a91d6bfcd5b9a9283264..752456950cef79c35ad7b0068157393db74eee27 100644 (file)
@@ -112,6 +112,34 @@ let  () =
     assert( (getc rope (2)) == Char.code 'c' );
   );
 
+  (* nextc() tests *)
+  test "nextc : should return pos if at end of buffer" (fun () ->
+    let rope = Leaf("abc", 0, 3) in
+    assert( 2 == (nextc rope 2) );
+  );
+  test "nextc : should return pos of next char" (fun () ->
+    let rope = Leaf("a\na", 0, 3) in
+    assert( 2 == (nextc rope 1) );
+  );
+  test "nextc : should return pos of next char" (fun () ->
+    let rope = Leaf("a\r\na", 0, 4) in
+    assert( 3 == (nextc rope 1) );
+  );
+
+  (* prevc() tests *)
+  test "prevc : should return pos if at start of buffer" (fun () ->
+    let rope = Leaf("abc", 0, 3) in
+    assert( 0 == (prevc rope 0) );
+  );
+  test "prevc : should return pos of prev char" (fun () ->
+    let rope = Leaf("a\na", 0, 3) in
+    assert( 1 == (prevc rope 2) );
+  );
+  test "prevc : should return pos of prev char" (fun () ->
+    let rope = Leaf("a\r\na", 0, 4) in
+    assert( 1 == (prevc rope 3) );
+  );
+
   (* is_bol() tests *)
   test "is_bol : should return true if pos is 0" (fun () ->
     let rope = Leaf("abc", 0, 3) in
@@ -137,7 +165,7 @@ let  () =
   );
   test "is_eol : should return true if pos is last char of line with \n ending" (fun () ->
     let rope = Leaf("abc\n", 0, 4) in
-    assert( is_eol rope 2 );
+    assert( is_eol rope 3 );
   );
   test "is_eol : should return true if pos is last char of line with \r\n ending" (fun () ->
     let rope = Leaf("abc\r\n", 0, 5) in