refactor Cursor.viH to use DFA
This commit is contained in:
@@ -4,19 +4,30 @@ struct
|
|||||||
val notNewlineState: Word8.word = 0w1
|
val notNewlineState: Word8.word = 0w1
|
||||||
val oneNewlineState: Word8.word = 0w2
|
val oneNewlineState: Word8.word = 0w2
|
||||||
val twoNewlineState: Word8.word = 0w3
|
val twoNewlineState: Word8.word = 0w3
|
||||||
|
val notNewlineAfterNewlineState: Word8.word = 0w4
|
||||||
|
|
||||||
fun makeStart i =
|
fun makeStart i =
|
||||||
if Char.chr i = #"\n" then oneNewlineState else notNewlineState
|
if Char.chr i = #"\n" then oneNewlineState else notNewlineState
|
||||||
|
|
||||||
fun makeOneNewline i =
|
fun makeOneNewline i =
|
||||||
if Char.chr i = #"\n" then twoNewlineState else notNewlineState
|
if Char.chr i = #"\n" then twoNewlineState else notNewlineAfterNewlineState
|
||||||
|
|
||||||
|
fun makeTwoNeline i =
|
||||||
|
if Char.chr i = #"\n" then oneNewlineState else notNewlineAfterNewlineState
|
||||||
|
|
||||||
val startTable = Vector.tabulate (255, makeStart)
|
val startTable = Vector.tabulate (255, makeStart)
|
||||||
val notNewlineTable = startTable
|
val notNewlineTable = startTable
|
||||||
val oneNewlineTable = Vector.tabulate (255, makeOneNewline)
|
val oneNewlineTable = Vector.tabulate (255, makeOneNewline)
|
||||||
val twoNewLineTable = startTable
|
val twoNewLineTable = startTable
|
||||||
|
val notNewlineAfterNewlineTable = notNewlineTable
|
||||||
|
|
||||||
val tables = #[startTable, notNewlineTable, oneNewlineTable, twoNewLineTable]
|
val tables =
|
||||||
|
#[ startTable
|
||||||
|
, notNewlineTable
|
||||||
|
, oneNewlineTable
|
||||||
|
, twoNewLineTable
|
||||||
|
, notNewlineAfterNewlineTable
|
||||||
|
]
|
||||||
|
|
||||||
fun next (currentState, chr) =
|
fun next (currentState, chr) =
|
||||||
let val table = Vector.sub (tables, Word8.toInt currentState)
|
let val table = Vector.sub (tables, Word8.toInt currentState)
|
||||||
@@ -38,12 +49,17 @@ struct
|
|||||||
val chr = String.sub (str, idx)
|
val chr = String.sub (str, idx)
|
||||||
val newState = next (currentState, chr)
|
val newState = next (currentState, chr)
|
||||||
in
|
in
|
||||||
if newState = twoNewlineState then
|
if
|
||||||
|
newState = twoNewlineState
|
||||||
|
then
|
||||||
if counter - 1 = ~1 then
|
if counter - 1 = ~1 then
|
||||||
absIdx - 1
|
absIdx - 1
|
||||||
else
|
else
|
||||||
loop (idx + 1, absIdx + 1, str, tl, startState, counter - 1)
|
loop (idx + 1, absIdx + 1, str, tl, startState, counter - 1)
|
||||||
else if newState = notNewlineState then
|
else if
|
||||||
|
newState = notNewlineState
|
||||||
|
orelse newState = notNewlineAfterNewlineState
|
||||||
|
then
|
||||||
if counter - 1 = ~1 then
|
if counter - 1 = ~1 then
|
||||||
absIdx
|
absIdx
|
||||||
else
|
else
|
||||||
@@ -55,5 +71,43 @@ struct
|
|||||||
val fStart = loop
|
val fStart = loop
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
structure ViH =
|
||||||
|
MakePrevDfaLoop
|
||||||
|
(struct
|
||||||
|
val startState = startState
|
||||||
|
|
||||||
|
fun loop (idx, absIdx, str, tl, currentState, counter) =
|
||||||
|
if idx < 0 then
|
||||||
|
case tl of
|
||||||
|
str :: tl =>
|
||||||
|
loop
|
||||||
|
(String.size str - 1, 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
|
||||||
|
else loop (idx - 1, absIdx - 1, str, tl, newState, 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 if newState = notNewlineAfterNewlineState then
|
||||||
|
if counter - 1 <= 0 then
|
||||||
|
absIdx
|
||||||
|
else
|
||||||
|
loop (idx - 1, absIdx - 1, str, tl, startState, counter - 1)
|
||||||
|
else
|
||||||
|
loop (idx - 1, absIdx - 1, str, tl, newState, counter)
|
||||||
|
end
|
||||||
|
|
||||||
|
val fStart = loop
|
||||||
|
end)
|
||||||
|
|
||||||
val next = ViL.next
|
val next = ViL.next
|
||||||
|
val prev = ViH.prev
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -57,77 +57,7 @@ struct
|
|||||||
val viDlrForDelete = ViDlrDfa.nextForDelete
|
val viDlrForDelete = ViDlrDfa.nextForDelete
|
||||||
|
|
||||||
val viL = ViLDfa.next
|
val viL = ViLDfa.next
|
||||||
|
val viH = ViLDfa.prev
|
||||||
structure ViH =
|
|
||||||
MakeIfCharFolderPrev
|
|
||||||
(struct
|
|
||||||
type env = unit
|
|
||||||
|
|
||||||
fun helpViH (strIdx, hd, cursorIdx, leftStrings) =
|
|
||||||
if strIdx > 0 then
|
|
||||||
(* bounds check: can access prev char in hd *)
|
|
||||||
if String.sub (hd, strIdx - 1) = #"\n" then
|
|
||||||
(* prev char is line break *)
|
|
||||||
if strIdx - 1 > 0 then
|
|
||||||
(* bounds check: can access two chars back in hd *)
|
|
||||||
if String.sub (hd, strIdx - 2) = #"\n" then
|
|
||||||
(* line break followed by line break
|
|
||||||
* so it is fine to decrement by 1 *)
|
|
||||||
cursorIdx - 1
|
|
||||||
else
|
|
||||||
(* non-line break followed by line break
|
|
||||||
* so we have to decrement by two,
|
|
||||||
* skipping over line break *)
|
|
||||||
cursorIdx - 2
|
|
||||||
else
|
|
||||||
(* need to check two chars back in leftStrings *)
|
|
||||||
(case leftStrings of
|
|
||||||
lhd :: ltl =>
|
|
||||||
if String.sub (lhd, String.size lhd - 1) = #"\n" then
|
|
||||||
(* double line break *)
|
|
||||||
cursorIdx - 1
|
|
||||||
else
|
|
||||||
(* non-line break precedes line break *)
|
|
||||||
cursorIdx - 2
|
|
||||||
| [] => cursorIdx - 1)
|
|
||||||
else
|
|
||||||
(* prev char is not line break so we can decrement by 1 *)
|
|
||||||
cursorIdx - 1
|
|
||||||
else
|
|
||||||
(* prev char is in leftStrings *)
|
|
||||||
(case leftStrings of
|
|
||||||
lhd :: ltl =>
|
|
||||||
if String.sub (lhd, String.size lhd - 1) = #"\n" then
|
|
||||||
(* one line break *)
|
|
||||||
if String.size lhd > 1 then
|
|
||||||
(* bounds check: prev-prev chr is in lhd *)
|
|
||||||
if String.sub (lhd, String.size lhd - 2) = #"\n" then
|
|
||||||
(* double line break *)
|
|
||||||
cursorIdx - 1
|
|
||||||
else
|
|
||||||
(* non-line break precedes line break *)
|
|
||||||
cursorIdx - 2
|
|
||||||
else
|
|
||||||
(* prev-prev chr is in ltl *)
|
|
||||||
(case ltl of
|
|
||||||
ltlhd :: _ =>
|
|
||||||
if String.sub (ltlhd, String.size ltlhd - 1) = #"\n" then
|
|
||||||
(* double line break *)
|
|
||||||
cursorIdx - 1
|
|
||||||
else
|
|
||||||
(* non-line break precedes line break *)
|
|
||||||
cursorIdx - 2
|
|
||||||
| [] => cursorIdx - 1)
|
|
||||||
else
|
|
||||||
(* no line break *)
|
|
||||||
cursorIdx - 1
|
|
||||||
| [] => 0)
|
|
||||||
|
|
||||||
fun fStart (strIdx, hd, _, cursorIdx, leftStrings, _, _) =
|
|
||||||
helpViH (strIdx, hd, cursorIdx, leftStrings)
|
|
||||||
end)
|
|
||||||
|
|
||||||
fun viH (lineGap, cursorIdx) = ViH.foldPrev (lineGap, cursorIdx, ())
|
|
||||||
|
|
||||||
fun helpGetCursorColumn (distanceFromLine, strList, lineList) =
|
fun helpGetCursorColumn (distanceFromLine, strList, lineList) =
|
||||||
case (strList, lineList) of
|
case (strList, lineList) of
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ struct
|
|||||||
end
|
end
|
||||||
end
|
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)
|
||||||
|
|
||||||
@@ -76,6 +75,7 @@ struct
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
structure MoveViH = MakeDfaMove (struct val fMove = Cursor.viH end)
|
||||||
structure MoveViL = MakeDfaMove (struct val fMove = Cursor.viL 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)
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ struct
|
|||||||
else
|
else
|
||||||
let
|
let
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
val low = Cursor.viH (buffer, low)
|
val low = Cursor.viH (buffer, low, 1)
|
||||||
val buffer = LineGap.goToIdx (low, buffer)
|
val buffer = LineGap.goToIdx (low, buffer)
|
||||||
val low = Cursor.vi0 (buffer, low)
|
val low = Cursor.vi0 (buffer, low)
|
||||||
val newCount = if low = 0 then 0 else count - 1
|
val newCount = if low = 0 then 0 else count - 1
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ struct
|
|||||||
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
||||||
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.deleteByDfa (app, count, Cursor.viH, time)
|
||||||
| #"l" => NormalDelete.deleteByDfa (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
|
||||||
@@ -346,7 +346,7 @@ struct
|
|||||||
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
fun parseDeleteTerminal (str, count, app, chrCmd, time) =
|
||||||
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.deleteByDfa (app, count, Cursor.viH, time)
|
||||||
| #"l" => NormalYankDelete.deleteByDfa (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
|
||||||
|
|||||||
Reference in New Issue
Block a user