From e55a7e2bca8a041b62ed89eeb0c51c82cf883bfc Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Sun, 3 Aug 2025 17:35:33 +0100 Subject: [PATCH] add separate folder when deleting end of current word, so that we can fix 'de' and 'dE' motions (the result of the folders for the cursor motion is meant to be decremented by 1, but the result for deleting is not meant to be decremented or incremented at all) --- fcore/app-update.sml | 4 ++-- fcore/cursor-dfa/vi-WORD-dfa.sml | 20 +++++++++++++++++ fcore/cursor-dfa/vi-word-dfa.sml | 37 +++++++++++++++++++++----------- fcore/cursor.sml | 2 ++ 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/fcore/app-update.sml b/fcore/app-update.sml index 359d5af..cb74e36 100644 --- a/fcore/app-update.sml +++ b/fcore/app-update.sml @@ -805,8 +805,8 @@ struct | #"W" => deleteByDfa (app, count, Cursor.nextWORD) | #"b" => deleteByDfa (app, count, Cursor.prevWord) | #"B" => deleteByDfa (app, count, Cursor.prevWORD) - | #"e" => deleteByDfa (app, count, Cursor.endOfWord) - | #"E" => deleteByDfa (app, count, Cursor.endOfWORD) + | #"e" => deleteByDfa (app, count, Cursor.endOfWordForDelete) + | #"E" => deleteByDfa (app, count, Cursor.endOfWORDForDelete) | #"0" => delete (app, 1, Cursor.vi0) | #"$" => deleteToEndOfLine app | #"^" => deleteToFirstNonSpaceChr app diff --git a/fcore/cursor-dfa/vi-WORD-dfa.sml b/fcore/cursor-dfa/vi-WORD-dfa.sml index 32f9940..aa57c8c 100644 --- a/fcore/cursor-dfa/vi-WORD-dfa.sml +++ b/fcore/cursor-dfa/vi-WORD-dfa.sml @@ -123,6 +123,25 @@ struct val fStart = EndOfCurrentWORDFolder.foldNext end) + structure EndOfCurrentWORDForDelete = + MakeNextDfaLoopPlus1 + (struct + val startState = startState + + structure Folder = + MakeCharFolderNext + (struct + val startState = startState + val tables = tables + + fun isFinal currentState = + currentState = spaceAfterNonBlankState + fun finish idx = idx + end) + + val fStart = Folder.foldNext + end) + structure EndOfCurrentWORDStrict = MakeNextDfaLoop (struct @@ -138,6 +157,7 @@ struct val startOfCurrentWORD = StartOfCurrentWORD.prev (* E *) val endOfCurrentWORD = EndOfCurrentWORD.next + val endOfCurrentWORDForDelete = EndOfCurrentWORDForDelete.next (* functions to strictly get the start and end of the current word. * Problem: We want to support Vi motions like viW (selects a single word), diff --git a/fcore/cursor-dfa/vi-word-dfa.sml b/fcore/cursor-dfa/vi-word-dfa.sml index 770e338..d2c9eb7 100644 --- a/fcore/cursor-dfa/vi-word-dfa.sml +++ b/fcore/cursor-dfa/vi-word-dfa.sml @@ -77,15 +77,6 @@ struct , spaceToPunctTable ] - fun next (currentState, chr) = - let - val currentState = Word8.toInt currentState - val currentTable = Vector.sub (tables, currentState) - val charIdx = Char.ord chr - in - Vector.sub (currentTable, charIdx) - end - structure StartOfNextWord = MakeNextDfaLoop (struct @@ -157,16 +148,17 @@ struct val fStart = StartOfCurrentWordFolder.foldPrev end) + fun isFinalForEndOfCurrentWord currentState = + currentState = alphaToSpace orelse currentState = punctToSpace + orelse currentState = alphaToPunct orelse currentState = punctToAlpha + structure EndOfCurrentWordFolder = MakeCharFolderNext (struct val startState = startState val tables = tables - fun isFinal currentState = - currentState = alphaToSpace orelse currentState = punctToSpace - orelse currentState = alphaToPunct orelse currentState = punctToAlpha - + val isFinal = isFinalForEndOfCurrentWord fun finish x = x - 1 end) @@ -184,6 +176,24 @@ struct val fStart = EndOfCurrentWordFolder.foldNext end) + structure EndOfCurrentWordForDelete = + MakeNextDfaLoopPlus1 + (struct + val startState = startState + + structure Folder = + MakeCharFolderNext + (struct + val startState = startState + val tables = tables + + val isFinal = isFinalForEndOfCurrentWord + fun finish x = x + end) + + val fStart = Folder.foldNext + end) + (* w *) val startOfNextWord = StartOfNextWord.next (* ge *) @@ -192,6 +202,7 @@ struct val startOfCurrentWord = StartOfCurrentWord.prev (* e *) val endOfCurrentWord = EndOfCurrentWord.next + val endOfCurrentWordForDelete = EndOfCurrentWordForDelete.next (* the meaning of "Strict" and the utility of these two functions * is described in vi-WORD-dfa.sml *) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 8373d49..82fd42b 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -729,9 +729,11 @@ struct (* equivalent of vi's `e` command *) val endOfWord = ViWordDfa.endOfCurrentWord + val endOfWordForDelete = ViWordDfa.endOfCurrentWordForDelete (* equivalent of vi's `E` command *) val endOfWORD = ViWORDDfa.endOfCurrentWORD + val endOfWORDForDelete = ViWORDDfa.endOfCurrentWORDForDelete fun helpFirstNonSpaceChr (strPos, str, absIdx, stl, ltl) = if strPos = String.size str then