new task: rewrite basic cursor.sml functions (h, j, k, l) to look for 'is line break preceded by non-line break?' rather than 'is there a double line break?' because the second question which is already implemented has buggy behaviour on triple line breaks, where cursor does not go to the place user expects. Currently, on Cursor.viL has been rewritten to match the first question.
This commit is contained in:
@@ -126,6 +126,30 @@ struct
|
|||||||
cursorIdx
|
cursorIdx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fun helpViL (strIdx, hd, cursorIdx, tl) =
|
||||||
|
if String.sub (hd, strIdx) = #"\n" then
|
||||||
|
(* if line break, go to next idx, no matter what chr is there *)
|
||||||
|
cursorIdx + 1
|
||||||
|
else
|
||||||
|
if strIdx + 1 < String.size hd then
|
||||||
|
(* next chr is in hd *)
|
||||||
|
if String.sub (hd, strIdx + 1) = #"\n" then
|
||||||
|
(* if non-line break followed by line break, go to chr + 2 *)
|
||||||
|
cursorIdx + 2
|
||||||
|
else
|
||||||
|
cursorIdx + 1
|
||||||
|
else
|
||||||
|
(case tl of
|
||||||
|
tlhd :: _ =>
|
||||||
|
if String.sub (tlhd, 0) = #"\n" then
|
||||||
|
(* non-line break followed by line break *)
|
||||||
|
cursorIdx + 2
|
||||||
|
else
|
||||||
|
(* non-line break followed by non-line break *)
|
||||||
|
cursorIdx
|
||||||
|
| [] =>
|
||||||
|
cursorIdx)
|
||||||
|
|
||||||
(* Prerequisite: lineGap is moved to requested idx first
|
(* Prerequisite: lineGap is moved to requested idx first
|
||||||
* todo: check if we are in a \r\n pair, but this is not a priority *)
|
* todo: check if we are in a \r\n pair, but this is not a priority *)
|
||||||
fun viL (lineGap: LineGap.t, cursorIdx) =
|
fun viL (lineGap: LineGap.t, cursorIdx) =
|
||||||
@@ -138,57 +162,19 @@ struct
|
|||||||
(* convert absolute cursorIdx to idx relative to hd string *)
|
(* convert absolute cursorIdx to idx relative to hd string *)
|
||||||
val strIdx = cursorIdx - bufferIdx
|
val strIdx = cursorIdx - bufferIdx
|
||||||
in
|
in
|
||||||
if strIdx + 1 < String.size hd then
|
if strIdx < String.size hd then
|
||||||
(* if there is at least one character after this idx *)
|
(* strIdx is in hd *)
|
||||||
let
|
helpViL (strIdx, hd, cursorIdx, tl)
|
||||||
val nextChr = String.sub (hd, strIdx + 1)
|
|
||||||
in
|
|
||||||
(case nextChr of
|
|
||||||
#"\n" =>
|
|
||||||
if strIdx + 2 < String.size hd then
|
|
||||||
(* if there are at least two chars after strIdx *)
|
|
||||||
cursorIdx + 2
|
|
||||||
else
|
else
|
||||||
(* only one char after strIdx which is \n
|
(* strIdx is in tl *)
|
||||||
* if there is a string at the tl, can increment by 2 *)
|
|
||||||
(case tl of
|
|
||||||
_ :: _ => cursorIdx + 2
|
|
||||||
| [] => cursorIdx + 1)
|
|
||||||
| _ => cursorIdx + 1)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
(* no chars after this idx; have to check tl *)
|
|
||||||
(case tl of
|
(case tl of
|
||||||
tlhd :: tltl =>
|
tlhd :: tltl =>
|
||||||
(* if there is another string after current head, we can increment cursorIdx
|
|
||||||
* however, first we need to check if next char is \n. *)
|
|
||||||
let
|
let
|
||||||
val nextChr = String.sub (tlhd, 0)
|
val strIdx = strIdx - String.size hd
|
||||||
in
|
in
|
||||||
(case nextChr of
|
helpViL (strIdx, tlhd, cursorIdx, tltl)
|
||||||
#"\n" =>
|
|
||||||
if String.size tlhd > 2 then
|
|
||||||
(* if there is at least one character after \n
|
|
||||||
* then increment cursorIdx by 2 *)
|
|
||||||
cursorIdx + 2
|
|
||||||
else
|
|
||||||
(* this string only contains \n
|
|
||||||
* but there is a small possibility tltl
|
|
||||||
* contains another string.
|
|
||||||
* If it does, we can increment cursorIdx by 2,
|
|
||||||
* moving past newline.
|
|
||||||
* If not, increment cursorIdx by 1,
|
|
||||||
* landing on newline. *)
|
|
||||||
(case tltl of
|
|
||||||
_ :: _ => cursorIdx + 2
|
|
||||||
| [] => cursorIdx + 1)
|
|
||||||
| _ =>
|
|
||||||
(* next char is not newline,
|
|
||||||
* so we can just increment by 1 *)
|
|
||||||
cursorIdx + 1)
|
|
||||||
end
|
end
|
||||||
| [] =>
|
| [] =>
|
||||||
(* if there is no string after current head, return original cursorIdx *)
|
|
||||||
cursorIdx)
|
cursorIdx)
|
||||||
end
|
end
|
||||||
| [] =>
|
| [] =>
|
||||||
|
|||||||
Reference in New Issue
Block a user