From 554c3b035428a716e53f5a46aabbbb5b38efce68 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Sun, 20 Jul 2025 13:28:40 +0100 Subject: [PATCH] done refactoring 'startOfCurrentWORD' function, with tests still passing --- fcore/cursor-dfa/vi-WORD-dfa.sml | 73 +++++++++++++++++++------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/fcore/cursor-dfa/vi-WORD-dfa.sml b/fcore/cursor-dfa/vi-WORD-dfa.sml index 3ea28e9..b19b835 100644 --- a/fcore/cursor-dfa/vi-WORD-dfa.sml +++ b/fcore/cursor-dfa/vi-WORD-dfa.sml @@ -108,39 +108,52 @@ struct end end) - structure StartOfCurrentWORD = - MakePrevDfaLoop - (struct - val startState = startState - - fun fStart (idx, absIdx, str, tl, currentState, counter) = - if idx < 0 then - case tl of - str :: tl => - fStart - (String.size str - 1, absIdx, str, tl, currentState, counter) - | [] => 0 - else - let - val chr = String.sub (str, idx) - val newState = next (currentState, chr) - in - if newState = spaceAfterNonBlankState then - if counter - 1 = 0 then - absIdx + 1 - else - fStart - (idx - 1, absIdx - 1, str, tl, startState, counter - 1) - else - fStart (idx - 1, absIdx - 1, str, tl, newState, counter) - end - end) - val startOfNextWORD = StartOfNextWORD.next val endOfPrevWORD = EndOfPrevWORD.prev + fun loopStartOfCurrentWORD (idx, absIdx, str, tl, currentState, counter) = + if idx < 0 then + case tl of + str :: tl => + loopStartOfCurrentWORD + (String.size str - 1, absIdx, str, tl, currentState, counter) + | [] => 0 + else + let + val chr = String.sub (str, idx) + val newState = next (currentState, chr) + in + if newState = spaceAfterNonBlankState then + if counter - 1 = 0 then + absIdx + 1 + else + loopStartOfCurrentWORD + (idx - 1, absIdx - 1, str, tl, startState, counter - 1) + else + loopStartOfCurrentWORD + (idx - 1, absIdx - 1, str, tl, newState, counter) + end + + (* we do not rely on MakeDfaLoop functor because we want to + * ignore the character the cursor is currently on, + * and start tracking state from the character before the current one. *) fun startOfCurrentWORD (lineGap: LineGap.t, cursorIdx) = - let val lineGap = LineGap.goToIdx (cursorIdx - 1, lineGap) - in StartOfCurrentWORD.prev (lineGap, cursorIdx - 1) + let + val {idx = bufferIdx, leftStrings, ...} = lineGap + val strIdx = cursorIdx - bufferIdx - 1 + val absIdx = cursorIdx - 1 + in + if strIdx < 0 then + case leftStrings of + lhd :: ltl => + loopStartOfCurrentWORD + (String.size lhd - 1, absIdx, lhd, ltl, startState, 1) + | [] => 0 + else + case #rightStrings lineGap of + rhd :: _ => + loopStartOfCurrentWORD + (strIdx, absIdx, rhd, leftStrings, startState, 1) + | [] => Int.max (0, cursorIdx - 2) end end