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]
|
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 =
|
structure ViL =
|
||||||
MakeNextDfaLoop
|
MakeNextDfaLoop
|
||||||
(struct
|
(struct
|
||||||
val startState = startState
|
val startState = startState
|
||||||
|
|
||||||
structure Folder =
|
fun loop (idx, absIdx, str, tl, currentState, counter) =
|
||||||
MakeCharFolderNext
|
if idx = String.size str then
|
||||||
(struct
|
case tl of
|
||||||
val startState = startState
|
str :: tl => loop (0, absIdx, str, tl, currentState, counter)
|
||||||
val tables = tables
|
| [] => 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
|
val fStart = loop
|
||||||
fun isFinal currentState =
|
|
||||||
currentState = notNewlineState
|
|
||||||
orelse currentState = oneNewlineState
|
|
||||||
end)
|
|
||||||
|
|
||||||
val fStart = Folder.foldNext
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
val next = ViL.next
|
val next = ViL.next
|
||||||
|
|||||||
@@ -56,56 +56,7 @@ struct
|
|||||||
val viDlr = ViDlrDfa.next
|
val viDlr = ViDlrDfa.next
|
||||||
val viDlrForDelete = ViDlrDfa.nextForDelete
|
val viDlrForDelete = ViDlrDfa.nextForDelete
|
||||||
|
|
||||||
fun helpViL (strIdx, hd, cursorIdx, tl) =
|
val viL = ViLDfa.next
|
||||||
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
|
|
||||||
|
|
||||||
structure ViH =
|
structure ViH =
|
||||||
MakeIfCharFolderPrev
|
MakeIfCharFolderPrev
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ end
|
|||||||
structure MoveViH = MakeMove (struct val fMove = Cursor.viH end)
|
structure MoveViH = MakeMove (struct val fMove = Cursor.viH end)
|
||||||
structure MoveViJ = MakeMove (struct val fMove = Cursor.viJ end)
|
structure MoveViJ = MakeMove (struct val fMove = Cursor.viJ end)
|
||||||
structure MoveViK = MakeMove (struct val fMove = Cursor.viK 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)
|
structure MoveToStartOfLine = MakeMove (struct val fMove = Cursor.vi0 end)
|
||||||
|
|
||||||
@@ -77,6 +76,8 @@ struct
|
|||||||
end
|
end
|
||||||
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)
|
||||||
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 buffer = LineGap.goToIdx (lineStart, buffer)
|
||||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
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
|
val count = if lineEnd = nextLine then 0 else count - 1
|
||||||
in
|
in
|
||||||
@@ -83,7 +83,7 @@ struct
|
|||||||
val buffer = LineGap.goToIdx (lineStart, buffer)
|
val buffer = LineGap.goToIdx (lineStart, buffer)
|
||||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
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
|
val count = if lineEnd = nextLine then 0 else count - 1
|
||||||
in
|
in
|
||||||
@@ -115,7 +115,7 @@ struct
|
|||||||
val buffer = LineGap.goToIdx (lineStart, buffer)
|
val buffer = LineGap.goToIdx (lineStart, buffer)
|
||||||
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
val lineEnd = Cursor.viDlr (buffer, lineStart, 1)
|
||||||
val buffer = LineGap.goToIdx (lineEnd, buffer)
|
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 newCursorIdx = Int.min (lineEnd, cursorIdx)
|
||||||
|
|
||||||
val buffer =
|
val buffer =
|
||||||
@@ -251,7 +251,7 @@ struct
|
|||||||
case chrCmd of
|
case chrCmd of
|
||||||
(* terminal commands: require no input after *)
|
(* terminal commands: require no input after *)
|
||||||
#"h" => NormalDelete.delete (app, count, Cursor.viH, time)
|
#"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
|
(* vi's 'j' and 'k' commands move up or down a column
|
||||||
* but 'dj' or 'dk' delete whole lines
|
* but 'dj' or 'dk' delete whole lines
|
||||||
* so their implementation differs from
|
* so their implementation differs from
|
||||||
@@ -347,7 +347,7 @@ struct
|
|||||||
case chrCmd of
|
case chrCmd of
|
||||||
(* terminal commands: require no input after *)
|
(* terminal commands: require no input after *)
|
||||||
#"h" => NormalYankDelete.delete (app, count, Cursor.viH, time)
|
#"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
|
(* vi's 'j' and 'k' commands move up or down a column
|
||||||
* but 'dj' or 'dk' delete whole lines
|
* but 'dj' or 'dk' delete whole lines
|
||||||
* so their implementation differs from
|
* so their implementation differs from
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ in
|
|||||||
fcore/cursor-dfa/vi-word-dfa.sml
|
fcore/cursor-dfa/vi-word-dfa.sml
|
||||||
fcore/cursor-dfa/vi-caps-word-dfa.sml
|
fcore/cursor-dfa/vi-caps-word-dfa.sml
|
||||||
fcore/cursor-dfa/vi-dlr-dfa.sml
|
fcore/cursor-dfa/vi-dlr-dfa.sml
|
||||||
|
fcore/cursor-dfa/vi-l-dfa.sml
|
||||||
fcore/rect.sml
|
fcore/rect.sml
|
||||||
fcore/pipe-cursor.sml
|
fcore/pipe-cursor.sml
|
||||||
end
|
end
|
||||||
@@ -60,6 +61,7 @@ fcore/normal-mode/normal-search-mode.sml
|
|||||||
|
|
||||||
fcore/app-update.sml
|
fcore/app-update.sml
|
||||||
|
|
||||||
|
|
||||||
(* TEST FILES *)
|
(* TEST FILES *)
|
||||||
$(SML_LIB)/basis/mlton.mlb
|
$(SML_LIB)/basis/mlton.mlb
|
||||||
shell/exception-logger.sml
|
shell/exception-logger.sml
|
||||||
|
|||||||
1
shf.mlb
1
shf.mlb
@@ -34,6 +34,7 @@ in
|
|||||||
fcore/cursor-dfa/vi-word-dfa.sml
|
fcore/cursor-dfa/vi-word-dfa.sml
|
||||||
fcore/cursor-dfa/vi-caps-word-dfa.sml
|
fcore/cursor-dfa/vi-caps-word-dfa.sml
|
||||||
fcore/cursor-dfa/vi-dlr-dfa.sml
|
fcore/cursor-dfa/vi-dlr-dfa.sml
|
||||||
|
fcore/cursor-dfa/vi-l-dfa.sml
|
||||||
fcore/rect.sml
|
fcore/rect.sml
|
||||||
fcore/pipe-cursor.sml
|
fcore/pipe-cursor.sml
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user