From e078ca89d27ece557b191dd7a65cacb5df24d737 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Sun, 3 Aug 2025 14:17:25 +0100 Subject: [PATCH] refactor some code to use looping in DFA (which is faster than looping outside of the data structure) --- fcore/app-update.sml | 41 +++++++++++++++++++----- fcore/cursor-dfa/make-dfa-loop.sml | 24 +++++++------- fcore/cursor.sml | 6 ++-- fcore/move.sml | 51 ++++++++++++++++++++++-------- 4 files changed, 86 insertions(+), 36 deletions(-) diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 833cce9..359c787 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -472,6 +472,27 @@ struct fun delete (app: app_type, count, fMove) = helpDelete (app, #buffer app, #cursorIdx app, #cursorIdx app, count, fMove) + fun deleteByDfa (app: app_type, count, fMove) = + let + val {buffer, cursorIdx, searchList, searchString, ...} = app + + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val otherIdx = fMove (buffer, cursorIdx, count) + + val low = Int.min (cursorIdx, otherIdx) + val high = Int.max (cursorIdx, otherIdx) + val length = high - low + + val buffer = LineGap.delete (low, length, buffer) + + val (buffer, searchList) = deleteSearchList + (low, length, searchString, searchList, buffer) + + val buffer = LineGap.goToIdx (low, buffer) + in + Finish.buildTextAndClear (app, buffer, low, searchList) + end + fun deleteToEndOfLine (app: app_type) = let val {buffer, cursorIdx, ...} = app @@ -780,12 +801,16 @@ struct * other cursor motions *) | #"j" => deleteLine (app, count + 1) | #"k" => deleteLineBack (app, count) - | #"w" => delete (app, count, Cursor.nextWord) - | #"W" => delete (app, count, Cursor.nextWORD) - | #"b" => delete (app, count, Cursor.prevWord) - | #"B" => delete (app, count, Cursor.prevWORD) - | #"e" => delete (app, count, Cursor.endOfWordPlusOne) - | #"E" => delete (app, count, Cursor.endOfWORDPlusOne) + | #"w" => deleteByDfa (app, count, Cursor.nextWord) + | #"W" => deleteByDfa (app, count, Cursor.nextWORD) + | #"b" => deleteByDfa (app, count, Cursor.prevWord) + | #"B" => deleteByDfa (app, count, Cursor.prevWORD) + + (* todo: fix as 'plusOne' needs reimplementing + | #"e" => deleteByDfa (app, count, Cursor.endOfWordPlusOne) + | #"E" => deleteByDfa (app, count, Cursor.endOfWORDPlusOne) + *) + | #"0" => delete (app, 1, Cursor.vi0) | #"$" => deleteToEndOfLine app | #"^" => deleteToFirstNonSpaceChr app @@ -835,8 +860,8 @@ struct (case newCmd of CHAR_EVENT chr => (case chr of - #"e" => delete (app, count, Cursor.endOfPrevWord) - | #"E" => delete (app, count, Cursor.endOfPrevWORD) + #"e" => deleteByDfa (app, count, Cursor.endOfPrevWord) + | #"E" => deleteByDfa (app, count, Cursor.endOfPrevWORD) | #"g" => deleteToStart app | _ => clearMode app) | KEY_ESC => clearMode app diff --git a/fcore/cursor-dfa/make-dfa-loop.sml b/fcore/cursor-dfa/make-dfa-loop.sml index 8913537..d950ac2 100644 --- a/fcore/cursor-dfa/make-dfa-loop.sml +++ b/fcore/cursor-dfa/make-dfa-loop.sml @@ -6,7 +6,7 @@ end functor MakeNextDfaLoop(M: MAKE_DFA_LOOP) = struct - fun next (lineGap: LineGap.t, cursorIdx) = + fun next (lineGap: LineGap.t, cursorIdx, count) = let val {rightStrings, idx = bufferIdx, ...} = lineGap (* convert absolute cursorIdx to idx relative to hd string *) @@ -16,13 +16,13 @@ struct shd :: stl => if strIdx < String.size shd then (* strIdx is in this string *) - M.fStart (strIdx, cursorIdx, shd, stl, M.startState, 1) + M.fStart (strIdx, cursorIdx, shd, stl, M.startState, count) else (* strIdx is in tl *) (case stl of stlhd :: stltl => let val strIdx = strIdx - String.size shd - in M.fStart (strIdx, cursorIdx, stlhd, stltl, M.startState, 1) + in M.fStart (strIdx, cursorIdx, stlhd, stltl, M.startState, count) end | _ => cursorIdx) | [] => cursorIdx @@ -31,7 +31,7 @@ end functor MakeNextDfaLoopPlus1(M: MAKE_DFA_LOOP) = struct - fun next (lineGap: LineGap.t, cursorIdx) = + fun next (lineGap: LineGap.t, cursorIdx, count) = let val {rightStrings, idx = bufferIdx, ...} = lineGap (* convert absolute cursorIdx to idx relative to hd string *) @@ -42,13 +42,13 @@ struct shd :: stl => if strIdx < String.size shd then (* strIdx is in this string *) - M.fStart (strIdx, absIdx, shd, stl, M.startState, 1) + M.fStart (strIdx, absIdx, shd, stl, M.startState, count) else (* strIdx is in tl *) (case stl of stlhd :: stltl => let val strIdx = strIdx - String.size shd - in M.fStart (strIdx, absIdx, stlhd, stltl, M.startState, 1) + in M.fStart (strIdx, absIdx, stlhd, stltl, M.startState, count) end | _ => cursorIdx) | [] => cursorIdx @@ -57,7 +57,7 @@ end functor MakePrevDfaLoop(M: MAKE_DFA_LOOP) = struct - fun prev (lineGap: LineGap.t, cursorIdx) = + fun prev (lineGap: LineGap.t, cursorIdx, count) = let val {rightStrings, leftStrings, idx = bufferIdx, ...} = lineGap (* convert absolute cursorIdx to idx relative to hd string *) @@ -67,7 +67,7 @@ struct shd :: stl => if strIdx < String.size shd then (* strIdx is in this string *) - M.fStart (strIdx, cursorIdx, shd, leftStrings, M.startState, 1) + M.fStart (strIdx, cursorIdx, shd, leftStrings, M.startState, count) else (* strIdx is in tl *) (case stl of @@ -77,7 +77,7 @@ struct val leftStrings = shd :: leftStrings in M.fStart - (strIdx, cursorIdx, stlhd, leftStrings, M.startState, 1) + (strIdx, cursorIdx, stlhd, leftStrings, M.startState, count) end | [] => cursorIdx) | [] => cursorIdx @@ -86,7 +86,7 @@ end functor MakePrevDfaLoopMinus1(M: MAKE_DFA_LOOP) = struct - fun prev (lineGap: LineGap.t, cursorIdx) = + fun prev (lineGap: LineGap.t, cursorIdx, count) = let val {idx = bufferIdx, leftStrings, ...} = lineGap val strIdx = cursorIdx - bufferIdx - 1 @@ -95,12 +95,12 @@ struct if strIdx < 0 then case leftStrings of lhd :: ltl => - M.fStart (String.size lhd - 1, absIdx, lhd, ltl, M.startState, 1) + M.fStart (String.size lhd - 1, absIdx, lhd, ltl, M.startState, count) | [] => 0 else case #rightStrings lineGap of rhd :: _ => - M.fStart (strIdx, absIdx, rhd, leftStrings, M.startState, 1) + M.fStart (strIdx, absIdx, rhd, leftStrings, M.startState, count) | [] => Int.max (0, cursorIdx - 2) end end diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 97650a6..76d8648 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -737,10 +737,12 @@ struct * but 'de' deletes up to and including last char of word * So we need to increment by one for deletion. *) fun endOfWordPlusOne (lineGap, cursorIdx) = - endOfWord (lineGap, cursorIdx) + 1 + (* todo: fix *) + endOfWord (lineGap, cursorIdx, 1) + 1 fun endOfWORDPlusOne (lineGap, cursorIdx) = - endOfWORD (lineGap, cursorIdx) + 1 + (* todo: fix *) + endOfWORD (lineGap, cursorIdx, 1) + 1 fun helpFirstNonSpaceChr (strPos, str, absIdx, stl, ltl) = if strPos = String.size str then diff --git a/fcore/move.sml b/fcore/move.sml index a415944..8225058 100644 --- a/fcore/move.sml +++ b/fcore/move.sml @@ -42,19 +42,42 @@ 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 MoveToNextWord = MakeMove (struct val fMove = Cursor.nextWord end) -structure MoveToNextWORD = MakeMove (struct val fMove = Cursor.nextWORD end) - -structure MoveToEndOfWord = MakeMove (struct val fMove = Cursor.endOfWord end) -structure MoveToEndOfWORD = MakeMove (struct val fMove = Cursor.endOfWORD end) - -structure MoveToPrevWord = MakeMove (struct val fMove = Cursor.prevWord end) -structure MoveToPrevWORD = MakeMove (struct val fMove = Cursor.prevWORD end) - -structure MoveToEndOfPrevWord = - MakeMove (struct val fMove = Cursor.endOfPrevWord end) -structure MoveToEndOfPrevWORD = - MakeMove (struct val fMove = Cursor.endOfPrevWORD end) - structure MoveToStartOfLine = MakeMove (struct val fMove = Cursor.vi0 end) structure MoveToEndOfLine = MakeMove (struct val fMove = Cursor.viDlr end) + +signature DFA_MOVE = +sig + val fMove: LineGap.t * int * int -> int +end + +signature MAKE_DFA_MOVE = +sig + val move: AppType.app_type * int -> AppType.app_type +end + +functor MakeDfaMove(Fn: DFA_MOVE): MAKE_DFA_MOVE = +struct + fun move (app: AppType.app_type, count) = + let + val {buffer, cursorIdx, ...} = app + val buffer = LineGap.goToIdx (cursorIdx, buffer) + val cursorIdx = Fn.fMove (buffer, cursorIdx, count) + in + Finish.buildTextAndClear (app, buffer, cursorIdx, #searchList app) + end +end + +structure MoveToNextWord = MakeDfaMove (struct val fMove = Cursor.nextWord end) +structure MoveToNextWORD = MakeDfaMove (struct val fMove = Cursor.nextWORD end) + +structure MoveToEndOfWord = MakeDfaMove (struct val fMove = Cursor.endOfWord end) +structure MoveToEndOfWORD = MakeDfaMove (struct val fMove = Cursor.endOfWORD end) + +structure MoveToPrevWord = MakeDfaMove (struct val fMove = Cursor.prevWord end) +structure MoveToPrevWORD = MakeDfaMove (struct val fMove = Cursor.prevWORD end) + +structure MoveToEndOfPrevWord = + MakeDfaMove (struct val fMove = Cursor.endOfPrevWord end) +structure MoveToEndOfPrevWORD = + MakeDfaMove (struct val fMove = Cursor.endOfPrevWORD end) +