diff --git a/fcore/cursor-dfa/vi-l-dfa.sml b/fcore/cursor-dfa/vi-l-dfa.sml index 1fe29f1..4cba737 100644 --- a/fcore/cursor-dfa/vi-l-dfa.sml +++ b/fcore/cursor-dfa/vi-l-dfa.sml @@ -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 diff --git a/fcore/cursor.sml b/fcore/cursor.sml index a0b2a53..7c1e329 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -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 diff --git a/fcore/move.sml b/fcore/move.sml index c70d9a8..140a93d 100644 --- a/fcore/move.sml +++ b/fcore/move.sml @@ -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) diff --git a/fcore/normal-mode/normal-mode.sml b/fcore/normal-mode/normal-mode.sml index bc337bd..145071b 100644 --- a/fcore/normal-mode/normal-mode.sml +++ b/fcore/normal-mode/normal-mode.sml @@ -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 diff --git a/shf-tests.mlb b/shf-tests.mlb index b007167..aa2e5a7 100644 --- a/shf-tests.mlb +++ b/shf-tests.mlb @@ -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 diff --git a/shf.mlb b/shf.mlb index 759c80d..763be7e 100644 --- a/shf.mlb +++ b/shf.mlb @@ -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