reimplement vi0 and helper functions so that they are likely faster (vi0 bring cursor to start of current line; before, this was done by checking each character in the string backwards, but now it is done by looking at the line metadata, which is faster for us by some constant factor)
This commit is contained in:
101
fcore/cursor.sml
101
fcore/cursor.sml
@@ -1,15 +1,41 @@
|
|||||||
structure Cursor =
|
structure Cursor =
|
||||||
struct
|
struct
|
||||||
fun helpVi0 (strPos, str, absIdx, strTl, lineTl) =
|
(* returns absolute index of previous line break in string *)
|
||||||
if strPos < 0 then
|
fun helpVi0 (absIdx, stl, ltl) =
|
||||||
case (strTl, lineTl) of
|
case (stl, ltl) of
|
||||||
(shd :: stl, lhd :: ltl) =>
|
(shd :: stl, lhd :: ltl) =>
|
||||||
helpVi0 (String.size shd - 1, shd, absIdx, stl, ltl)
|
if Vector.length lhd > 0 then
|
||||||
| (_, _) => 0
|
let
|
||||||
|
val startAbsIdx = absIdx - String.size shd
|
||||||
|
val lineIdx = Vector.sub (lhd, Vector.length lhd - 1)
|
||||||
|
in
|
||||||
|
(* found lineIdx.
|
||||||
|
* Need to make sure we follow cursor-on-linebreak rule:
|
||||||
|
* If line break is preceded by non-line break char,
|
||||||
|
* then increment by 1.
|
||||||
|
* *)
|
||||||
|
startAbsIdx + lineIdx + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
helpVi0 (absIdx - String.size shd, stl, ltl)
|
||||||
|
| (_, _) => 0
|
||||||
|
|
||||||
|
fun startVi0 (strPos, shd, lhd, absIdx, stl, ltl) =
|
||||||
|
if String.sub (shd, strPos) = #"\n" then
|
||||||
|
absIdx
|
||||||
else
|
else
|
||||||
case String.sub (str, strPos) of
|
if Vector.length lhd > 0 then
|
||||||
#"\n" => absIdx + 1
|
if Vector.sub (lhd, 0) < strPos then
|
||||||
| _ => helpVi0 (strPos - 1, str, absIdx - 1, strTl, lineTl)
|
let
|
||||||
|
val linePos = BinSearch.equalOrLess (strPos - 1, lhd)
|
||||||
|
val lineIdx = Vector.sub (lhd, linePos)
|
||||||
|
in
|
||||||
|
absIdx - strPos + lineIdx + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
helpVi0 (absIdx - strPos, stl, ltl)
|
||||||
|
else
|
||||||
|
helpVi0 (absIdx - strPos, stl, ltl)
|
||||||
|
|
||||||
fun vi0 (lineGap: LineGap.t, cursorIdx) =
|
fun vi0 (lineGap: LineGap.t, cursorIdx) =
|
||||||
let
|
let
|
||||||
@@ -25,14 +51,8 @@ struct
|
|||||||
in
|
in
|
||||||
if strIdx < String.size strHd then
|
if strIdx < String.size strHd then
|
||||||
(* strIdx is in this string *)
|
(* strIdx is in this string *)
|
||||||
if String.sub (strHd, strIdx) = #"\n" then
|
startVi0
|
||||||
(* don't need to do anything if we are already at newline;
|
(strIdx, strHd, lnHd, cursorIdx, leftStrings, leftLines)
|
||||||
* just return current cursorIdx *)
|
|
||||||
cursorIdx
|
|
||||||
else
|
|
||||||
(* not at newline so start iterating *)
|
|
||||||
helpVi0
|
|
||||||
(strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines)
|
|
||||||
else
|
else
|
||||||
(* strIdx must be in the strTl *)
|
(* strIdx must be in the strTl *)
|
||||||
(case (strTl, lnTl) of
|
(case (strTl, lnTl) of
|
||||||
@@ -40,18 +60,14 @@ struct
|
|||||||
let
|
let
|
||||||
val strIdx = strIdx - String.size strHd
|
val strIdx = strIdx - String.size strHd
|
||||||
in
|
in
|
||||||
if String.sub (nestStrHd, strIdx) = #"\n" then
|
startVi0
|
||||||
(* already at linebreak so return same cursorIdx *)
|
( strIdx
|
||||||
cursorIdx
|
, nestStrHd
|
||||||
else
|
, nestLnHd
|
||||||
(* not in linebreak *)
|
, cursorIdx
|
||||||
helpVi0
|
, strHd :: leftStrings
|
||||||
( strIdx - 1
|
, lnHd :: leftLines
|
||||||
, nestStrHd
|
)
|
||||||
, cursorIdx - 1
|
|
||||||
, strHd :: leftStrings
|
|
||||||
, lnHd :: leftLines
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
| (_, _) => cursorIdx)
|
| (_, _) => cursorIdx)
|
||||||
end
|
end
|
||||||
@@ -541,8 +557,8 @@ struct
|
|||||||
(* graphical-chr -> \n -> \n
|
(* graphical-chr -> \n -> \n
|
||||||
* so go to beginning of line,
|
* so go to beginning of line,
|
||||||
* starting from graphical-chr *)
|
* starting from graphical-chr *)
|
||||||
helpVi0
|
startVi0
|
||||||
(strIdx - 2, shd, cursorIdx - 2, leftStrings, leftLines)
|
(strIdx - 2, shd, lhd, cursorIdx - 2, leftStrings, leftLines)
|
||||||
else
|
else
|
||||||
(* strIdx - 2 is in leftStrings *)
|
(* strIdx - 2 is in leftStrings *)
|
||||||
case (leftStrings, leftLines) of
|
case (leftStrings, leftLines) of
|
||||||
@@ -555,8 +571,8 @@ struct
|
|||||||
(* graphical-chr -> \n -> \n
|
(* graphical-chr -> \n -> \n
|
||||||
* so go to beginning of line,
|
* so go to beginning of line,
|
||||||
* starting from graphical-chr *)
|
* starting from graphical-chr *)
|
||||||
helpVi0
|
startVi0
|
||||||
(String.size lshd - 1, lshd, cursorIdx - 2, lstl, lltl)
|
(String.size lshd - 1, lshd, llhd, cursorIdx - 2, lstl, lltl)
|
||||||
| (_, _) =>
|
| (_, _) =>
|
||||||
(* nothing to the left, so we are at start of buffer *)
|
(* nothing to the left, so we are at start of buffer *)
|
||||||
0
|
0
|
||||||
@@ -564,7 +580,8 @@ struct
|
|||||||
(* ? -> graphical-chr -> \n
|
(* ? -> graphical-chr -> \n
|
||||||
* Don't expect this case to happen
|
* Don't expect this case to happen
|
||||||
* but if it does, go to start of line. *)
|
* but if it does, go to start of line. *)
|
||||||
helpVi0 (strIdx - 1, shd, cursorIdx - 1, leftStrings, leftLines)
|
startVi0
|
||||||
|
(strIdx - 1, shd, lhd, cursorIdx - 1, leftStrings, leftLines)
|
||||||
else
|
else
|
||||||
(* strIdx - 1 is in leftStrings *)
|
(* strIdx - 1 is in leftStrings *)
|
||||||
case (leftStrings, leftLines) of
|
case (leftStrings, leftLines) of
|
||||||
@@ -578,8 +595,8 @@ struct
|
|||||||
cursorIdx - 1
|
cursorIdx - 1
|
||||||
else
|
else
|
||||||
(* graphical-chr -> \n -> \n *)
|
(* graphical-chr -> \n -> \n *)
|
||||||
helpVi0
|
startVi0
|
||||||
(String.size lshd - 2, lshd, cursorIdx - 2, lstl, lltl)
|
(String.size lshd - 2, lshd, llhd, cursorIdx - 2, lstl, lltl)
|
||||||
else
|
else
|
||||||
(* cursorIdx - 2 is in lstl *)
|
(* cursorIdx - 2 is in lstl *)
|
||||||
(case (lstl, lltl) of
|
(case (lstl, lltl) of
|
||||||
@@ -589,12 +606,13 @@ struct
|
|||||||
cursorIdx - 1
|
cursorIdx - 1
|
||||||
else
|
else
|
||||||
(* graphical-chr -> \n -> \n *)
|
(* graphical-chr -> \n -> \n *)
|
||||||
helpVi0
|
startVi0
|
||||||
(String.size stlhd - 1, stlhd, cursorIdx - 2, lstl, lltl)
|
(String.size stlhd - 1, stlhd, ltlhd, cursorIdx - 2, lstl, lltl)
|
||||||
| (_, _) => 0)
|
| (_, _) => 0)
|
||||||
else
|
else
|
||||||
(* ? -> graphical-chr -> \n *)
|
(* ? -> graphical-chr -> \n *)
|
||||||
helpVi0 (String.size lshd - 1, lshd, cursorIdx - 1, leftStrings, leftLines)
|
startVi0
|
||||||
|
(String.size lshd - 1, lshd, llhd, cursorIdx - 1, leftStrings, leftLines)
|
||||||
| (_, _) =>
|
| (_, _) =>
|
||||||
(* leftStrings is empty so go to start of buffer *)
|
(* leftStrings is empty so go to start of buffer *)
|
||||||
0
|
0
|
||||||
@@ -1636,8 +1654,9 @@ struct
|
|||||||
(case (leftStrings, leftLines) of
|
(case (leftStrings, leftLines) of
|
||||||
(lshd :: lstl, llhd :: lltl) =>
|
(lshd :: lstl, llhd :: lltl) =>
|
||||||
let
|
let
|
||||||
val result = helpVi0
|
val result =
|
||||||
(String.size lshd - 1, lshd, bufferIdx - 1, lstl, lltl)
|
startVi0
|
||||||
|
(String.size lshd - 1, lshd, llhd, bufferIdx - 1, lstl, lltl)
|
||||||
in
|
in
|
||||||
if result = bufferIdx then
|
if result = bufferIdx then
|
||||||
bufferIdx - 1
|
bufferIdx - 1
|
||||||
|
|||||||
Reference in New Issue
Block a user