diff --git a/fcore/cursor-dfa/vi-WORD-dfa.sml b/fcore/cursor-dfa/vi-WORD-dfa.sml index 5e3c21b..3ea28e9 100644 --- a/fcore/cursor-dfa/vi-WORD-dfa.sml +++ b/fcore/cursor-dfa/vi-WORD-dfa.sml @@ -3,7 +3,8 @@ struct val startState: Word8.word = 0w0 val startNonBlankState: Word8.word = 0w1 val startSpaceState: Word8.word = 0w2 - val nonBlankAfterSpaceState: Word8.word = 0w4 + val nonBlankAfterSpaceState: Word8.word = 0w3 + val spaceAfterNonBlankState = 0w4 fun makeStart i = let val chr = Char.chr i @@ -12,7 +13,7 @@ struct fun makeStartNonBlankState i = let val chr = Char.chr i - in if Char.isSpace chr then startSpaceState else startNonBlankState + in if Char.isSpace chr then spaceAfterNonBlankState else startNonBlankState end fun makeStartSpace i = @@ -20,11 +21,27 @@ struct in if Char.isSpace chr then startSpaceState else nonBlankAfterSpaceState end + fun makeNonBlankAfterSpace i = + let + val chr = Char.chr i + in + if Char.isSpace chr then spaceAfterNonBlankState + else nonBlankAfterSpaceState + end + val startTable = Vector.tabulate (255, makeStart) val startNonBlankTable = Vector.tabulate (255, makeStartNonBlankState) val startSpaceTable = Vector.tabulate (255, makeStartSpace) + val nonBlankAfterSpaceTable = Vector.tabulate (255, makeNonBlankAfterSpace) + val spaceAfterNonBlankTable = nonBlankAfterSpaceTable - val tables = #[startTable, startNonBlankTable, startSpaceTable] + val tables = + #[ startTable + , startNonBlankTable + , startSpaceTable + , nonBlankAfterSpaceTable + , spaceAfterNonBlankTable + ] fun next (currentState, currentChar) = let @@ -91,6 +108,39 @@ 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 startOfCurrentWORD (lineGap: LineGap.t, cursorIdx) = + let val lineGap = LineGap.goToIdx (cursorIdx - 1, lineGap) + in StartOfCurrentWORD.prev (lineGap, cursorIdx - 1) + end end diff --git a/fcore/cursor.sml b/fcore/cursor.sml index db5b282..7f32166 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -1038,8 +1038,7 @@ struct toPrevWord (lineGap, cursorIdx, helpPrevWord) (* equivalent of vi's 'B' command *) - fun prevWORD (lineGap, cursorIdx) = - toPrevWord (lineGap, cursorIdx, helpPrevWORD) + val prevWORD = ViWORDDfa.startOfCurrentWORD fun toEndOfPrevWord (lineGap: LineGap.t, cursorIdx, fPrev) = let