From 11cb00860bf22fd85182f421f888260027fe4a8b Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 12 Dec 2025 11:32:03 +0000 Subject: [PATCH] reimplemen 'diw' motion to fix failing test --- fcore/cursor.sml | 165 ++++++++++++++++++++++- fcore/normal-mode/make-normal-delete.sml | 41 +++--- temp.txt | 2 +- todo.md | 4 +- 4 files changed, 190 insertions(+), 22 deletions(-) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 7f6bc96..2376225 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -46,7 +46,6 @@ struct MakeIfCharFolderPrev (struct type env = unit - val fStart = startVi0 fun fStart (strPos, shd, lhd, absIdx, stl, ltl, _) = startVi0 (strPos, shd, lhd, absIdx, stl, ltl) end) @@ -406,6 +405,170 @@ struct | [] => cursorIdx end + structure FirstContiguousAlpha = + MakeIfCharFolderPrev + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos < 0 then + case stl of + shd :: stl => loop (String.size shd - 1, shd, absIdx, stl) + | [] => 0 + else + let + val chr = String.sub (shd, strPos) + in + if Char.isAlphaNum chr orelse chr = #"_" then + loop (strPos - 1, shd, absIdx - 1, stl) + else + absIdx + 1 + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun firstContiguousAlpha (lineGap, cursorIdx) = + FirstContiguousAlpha.foldPrev (lineGap, cursorIdx, ()) + + structure LastContiguousAlpha = + MakeIfCharFolderNext + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos = String.size shd then + case stl of + shd :: stl => loop (0, shd, absIdx, stl) + | [] => Int.max (0, absIdx - 1) + else + let + val chr = String.sub (shd, strPos) + in + if Char.isAlphaNum chr orelse chr = #"_" then + loop (strPos + 1, shd, absIdx + 1, stl) + else + absIdx - 1 + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun lastContiguousAlpha (lineGap, cursorIdx) = + LastContiguousAlpha.foldNext (lineGap, cursorIdx, ()) + + structure FirstContiguousSpace = + MakeIfCharFolderPrev + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos < 0 then + case stl of + shd :: stl => loop (String.size shd - 1, shd, absIdx, stl) + | [] => 0 + else + let + val chr = String.sub (shd, strPos) + in + if Char.isSpace chr then + if chr = #"\n" then absIdx + 1 + else loop (strPos - 1, shd, absIdx - 1, stl) + else + absIdx + 1 + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun firstContiguousSpace (lineGap, cursorIdx) = + FirstContiguousSpace.foldPrev (lineGap, cursorIdx, ()) + + structure LastContiguousSpace = + MakeIfCharFolderNext + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos = String.size shd then + case stl of + shd :: stl => loop (0, shd, absIdx, stl) + | [] => Int.max (0, absIdx - 1) + else + let + val chr = String.sub (shd, strPos) + in + if Char.isSpace chr then + if chr = #"\n" then absIdx - 1 + else loop (strPos + 1, shd, absIdx + 1, stl) + else + absIdx - 1 + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun lastContiguousSpace (lineGap, cursorIdx) = + LastContiguousSpace.foldNext (lineGap, cursorIdx, ()) + + structure FirstContiguousPunct = + MakeIfCharFolderPrev + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos < 0 then + case stl of + shd :: stl => loop (String.size shd - 1, shd, absIdx, stl) + | [] => 0 + else + let + val chr = String.sub (shd, strPos) + in + if Char.isAlphaNum chr orelse chr = #"_" orelse Char.isSpace chr then + absIdx + 1 + else + loop (strPos - 1, shd, absIdx - 1, stl) + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun firstContiguousPunct (lineGap, cursorIdx) = + FirstContiguousPunct.foldPrev (lineGap, cursorIdx, ()) + + structure LastContiguousPunct = + MakeIfCharFolderNext + (struct + type env = unit + + fun loop (strPos, shd, absIdx, stl) = + if strPos = String.size shd then + case stl of + shd :: stl => loop (0, shd, absIdx, stl) + | [] => Int.max (0, absIdx - 1) + else + let + val chr = String.sub (shd, strPos) + in + if Char.isAlphaNum chr orelse chr = #"_" orelse Char.isSpace chr then + absIdx - 1 + else + loop (strPos + 1, shd, absIdx + 1, stl) + end + + fun fStart (strPos, shd, _, absIdx, stl, _, _) = + loop (strPos, shd, absIdx, stl) + end) + + fun lastContiguousPunct (lineGap, cursorIdx) = + LastContiguousPunct.foldNext (lineGap, cursorIdx, ()) + (* Prerequisite: lineGap is moved to cursorIdx *) fun isCursorAtStartOfLine (lineGap: LineGap.t, cursorIdx) = let diff --git a/fcore/normal-mode/make-normal-delete.sml b/fcore/normal-mode/make-normal-delete.sml index bdd663a..1581094 100644 --- a/fcore/normal-mode/make-normal-delete.sml +++ b/fcore/normal-mode/make-normal-delete.sml @@ -917,30 +917,35 @@ struct let val {buffer, cursorIdx, dfa, ...} = app val buffer = LineGap.goToIdx (cursorIdx, buffer) - - val low = Cursor.prevWordStrict (buffer, cursorIdx, 1) - val high = Cursor.endOfWordStrict (buffer, cursorIdx, 1) + 1 - - val buffer = LineGap.goToIdx (high, buffer) - val length = high - low + val chr = LineGap.sub (cursorIdx, buffer) in - if canDeleteInsideOrAround (buffer, low, length) then + if chr = #"\n" then + NormalFinish.clearMode app + else if Char.isAlphaNum chr orelse chr = #"_" then let - val buffer = LineGap.goToIdx (high, buffer) + val low = Cursor.firstContiguousAlpha (buffer, cursorIdx) + val high = Cursor.lastContiguousAlpha (buffer, cursorIdx) + 1 val length = high - low - val initialMsg = Fn.initMsgs (low, length, buffer) - - val buffer = LineGap.delete (low, length, buffer) - - val (buffer, searchList) = SearchList.build (buffer, dfa) - - val buffer = LineGap.goToIdx (low, buffer) in - NormalFinish.buildTextAndClear - (app, buffer, low, searchList, initialMsg, time) + deleteAndFinish (app, low, length, buffer, time) + end + else if Char.isSpace chr then + let + val low = Cursor.firstContiguousSpace (buffer, cursorIdx) + val high = Cursor.lastContiguousSpace (buffer, cursorIdx) + 1 + val length = high - low + in + deleteAndFinish (app, low, length, buffer, time) end else - app + (* char is punct *) + let + val low = Cursor.firstContiguousPunct (buffer, cursorIdx) + val high = Cursor.lastContiguousPunct (buffer, cursorIdx) + 1 + val length = high - low + in + deleteAndFinish (app, low, length, buffer, time) + end end fun deleteInsideWORD (app: app_type, time) = diff --git a/temp.txt b/temp.txt index e942542..9b48555 100644 --- a/temp.txt +++ b/temp.txt @@ -1 +1 @@ -99999999999999999999999999999999 +hello abc_123 world diff --git a/todo.md b/todo.md index 8a17f13..09e9212 100644 --- a/todo.md +++ b/todo.md @@ -1,8 +1,8 @@ # To-do list - Add tests for: - - delete inside word -- Implement delete-around-word and test it + - delete inside WORD +- Implement delete-around-word/WORD and test it - Reimplement `%` motion and `d%` motion. - They should both search for the next character in any pair, the same way in Vim - Add tests for reimplemented movements and motions