fix bugs in vi-l-dfa (we want to stop looping when the counter is ~1, because the starting character will likely be final/a not-newline, and we want to loop at least once; also, we want to special case 'twoNewlineState' as a final case which causes us to go backwards by 1 instead of treating 'oneNewlineState' as a final/special case). We also modify other code to use the new vi-l implementation in the program.
This commit is contained in:
@@ -18,24 +18,41 @@ struct
|
||||
|
||||
val tables = #[startTable, notNewlineTable, oneNewlineTable, twoNewLineTable]
|
||||
|
||||
fun next (currentState, chr) =
|
||||
let val table = Vector.sub (tables, Word8.toInt currentState)
|
||||
in Vector.sub (table, Char.ord chr)
|
||||
end
|
||||
|
||||
structure ViL =
|
||||
MakeNextDfaLoop
|
||||
(struct
|
||||
val startState = startState
|
||||
|
||||
structure Folder =
|
||||
MakeCharFolderNext
|
||||
(struct
|
||||
val startState = startState
|
||||
val tables = tables
|
||||
fun loop (idx, absIdx, str, tl, currentState, counter) =
|
||||
if idx = String.size str then
|
||||
case tl of
|
||||
str :: tl => loop (0, absIdx, str, tl, currentState, counter)
|
||||
| [] => absIdx
|
||||
else
|
||||
let
|
||||
val chr = String.sub (str, idx)
|
||||
val newState = next (currentState, chr)
|
||||
in
|
||||
if newState = twoNewlineState then
|
||||
if counter - 1 = ~1 then
|
||||
absIdx - 1
|
||||
else
|
||||
loop (idx + 1, absIdx + 1, str, tl, startState, counter - 1)
|
||||
else if newState = notNewlineState then
|
||||
if counter - 1 = ~1 then
|
||||
absIdx
|
||||
else
|
||||
loop (idx + 1, absIdx + 1, str, tl, startState, counter - 1)
|
||||
else
|
||||
loop (idx + 1, absIdx + 1, str, tl, newState, counter)
|
||||
end
|
||||
|
||||
fun finish x = x
|
||||
fun isFinal currentState =
|
||||
currentState = notNewlineState
|
||||
orelse currentState = oneNewlineState
|
||||
end)
|
||||
|
||||
val fStart = Folder.foldNext
|
||||
val fStart = loop
|
||||
end)
|
||||
|
||||
val next = ViL.next
|
||||
|
||||
@@ -56,56 +56,7 @@ struct
|
||||
val viDlr = ViDlrDfa.next
|
||||
val viDlrForDelete = ViDlrDfa.nextForDelete
|
||||
|
||||
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 + 1
|
||||
| [] => cursorIdx)
|
||||
|
||||
(* Prerequisite: lineGap is moved to requested idx first
|
||||
* todo: check if we are in a \r\n pair, but this is not a priority *)
|
||||
fun viL (lineGap: LineGap.t, cursorIdx) =
|
||||
let
|
||||
val {rightStrings, idx = bufferIdx, ...} = lineGap
|
||||
in
|
||||
case rightStrings of
|
||||
hd :: tl =>
|
||||
let
|
||||
(* convert absolute cursorIdx to idx relative to hd string *)
|
||||
val strIdx = cursorIdx - bufferIdx
|
||||
in
|
||||
if strIdx < String.size hd then
|
||||
(* strIdx is in hd *)
|
||||
helpViL (strIdx, hd, cursorIdx, tl)
|
||||
else
|
||||
(* strIdx is in tl *)
|
||||
(case tl of
|
||||
tlhd :: tltl =>
|
||||
let val strIdx = strIdx - String.size hd
|
||||
in helpViL (strIdx, tlhd, cursorIdx, tltl)
|
||||
end
|
||||
| [] => cursorIdx)
|
||||
end
|
||||
| [] =>
|
||||
(* return original cursorIdx if there is nothing to the right *)
|
||||
cursorIdx
|
||||
end
|
||||
val viL = ViLDfa.next
|
||||
|
||||
structure ViH =
|
||||
MakeIfCharFolderPrev
|
||||
|
||||
@@ -45,7 +45,6 @@ end
|
||||
structure MoveViH = MakeMove (struct val fMove = Cursor.viH end)
|
||||
structure MoveViJ = MakeMove (struct val fMove = Cursor.viJ end)
|
||||
structure MoveViK = MakeMove (struct val fMove = Cursor.viK end)
|
||||
structure MoveViL = MakeMove (struct val fMove = Cursor.viL end)
|
||||
|
||||
structure MoveToStartOfLine = MakeMove (struct val fMove = Cursor.vi0 end)
|
||||
|
||||
@@ -77,6 +76,8 @@ struct
|
||||
end
|
||||
end
|
||||
|
||||
structure MoveViL = MakeDfaMove (struct val fMove = Cursor.viL end)
|
||||
|
||||
structure MoveToNextWord = MakeDfaMove (struct val fMove = Cursor.nextWord end)
|
||||
structure MoveToNextWORD = MakeDfaMove (struct val fMove = Cursor.nextWORD end)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ struct
|
||||
val buffer = LineGap.goToIdx (lineStart, buffer)
|
||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd, 1)
|
||||
|
||||
val count = if lineEnd = nextLine then 0 else count - 1
|
||||
in
|
||||
@@ -83,7 +83,7 @@ struct
|
||||
val buffer = LineGap.goToIdx (lineStart, buffer)
|
||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd, 1)
|
||||
|
||||
val count = if lineEnd = nextLine then 0 else count - 1
|
||||
in
|
||||
@@ -115,7 +115,7 @@ struct
|
||||
val buffer = LineGap.goToIdx (lineStart, buffer)
|
||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd)
|
||||
val nextLine = Cursor.viL (buffer, lineEnd, 1)
|
||||
val newCursorIdx = Int.min (lineEnd, cursorIdx)
|
||||
|
||||
val buffer =
|
||||
@@ -251,7 +251,7 @@ struct
|
||||
case chrCmd of
|
||||
(* terminal commands: require no input after *)
|
||||
#"h" => NormalDelete.delete (app, count, Cursor.viH, time)
|
||||
| #"l" => NormalDelete.delete (app, count, Cursor.viL, time)
|
||||
| #"l" => NormalDelete.deleteByDfa (app, count, Cursor.viL, time)
|
||||
(* vi's 'j' and 'k' commands move up or down a column
|
||||
* but 'dj' or 'dk' delete whole lines
|
||||
* so their implementation differs from
|
||||
@@ -347,7 +347,7 @@ struct
|
||||
case chrCmd of
|
||||
(* terminal commands: require no input after *)
|
||||
#"h" => NormalYankDelete.delete (app, count, Cursor.viH, time)
|
||||
| #"l" => NormalYankDelete.delete (app, count, Cursor.viL, time)
|
||||
| #"l" => NormalYankDelete.deleteByDfa (app, count, Cursor.viL, time)
|
||||
(* vi's 'j' and 'k' commands move up or down a column
|
||||
* but 'dj' or 'dk' delete whole lines
|
||||
* so their implementation differs from
|
||||
|
||||
@@ -34,6 +34,7 @@ in
|
||||
fcore/cursor-dfa/vi-word-dfa.sml
|
||||
fcore/cursor-dfa/vi-caps-word-dfa.sml
|
||||
fcore/cursor-dfa/vi-dlr-dfa.sml
|
||||
fcore/cursor-dfa/vi-l-dfa.sml
|
||||
fcore/rect.sml
|
||||
fcore/pipe-cursor.sml
|
||||
end
|
||||
@@ -60,6 +61,7 @@ fcore/normal-mode/normal-search-mode.sml
|
||||
|
||||
fcore/app-update.sml
|
||||
|
||||
|
||||
(* TEST FILES *)
|
||||
$(SML_LIB)/basis/mlton.mlb
|
||||
shell/exception-logger.sml
|
||||
|
||||
Reference in New Issue
Block a user