From d01a1367aeae90e6da26c4026936a0c87ae1a5bf Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Sat, 27 Sep 2025 13:09:18 +0100 Subject: [PATCH] add test for 'dw' case: when we use 'dw' on last word in buffer, and there is no newline after last word, we delete last word fully --- fcore/normal-mode/make-normal-delete.sml | 22 +++++++++++++++++++++- test/normal-delete.sml | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/fcore/normal-mode/make-normal-delete.sml b/fcore/normal-mode/make-normal-delete.sml index a83abcd..6bb611a 100644 --- a/fcore/normal-mode/make-normal-delete.sml +++ b/fcore/normal-mode/make-normal-delete.sml @@ -272,10 +272,30 @@ struct fun finishDeleteByDfa (app, low, high, buffer, time) = let - val length = high - low val buffer = LineGap.goToIdx (high, buffer) + val high = + (* by default, we have a newline at the end of the buffer. + * However, we also support the case where there is no newline + * at the end of the buffer. + * The first case is supported by default, + * but we have to increment the textLength if the buffer + * does not end with a newline, to make sure that + * we delete the last character. *) + if + high = #textLength buffer - 1 + andalso not (Cursor.isCursorAtStartOfLine (buffer, high)) + then #textLength buffer + else high + + val length = high - low val initialMsg = Fn.initMsgs (low, length, buffer) val buffer = LineGap.delete (low, length, buffer) + + (* if we deleted all text in the buffer, + * then make sure that we append a newline at the end + * so that the buffer contains at least one character *) + val buffer = + if #textLength buffer = 0 then LineGap.append ("\n", buffer) else buffer in if low >= #textLength buffer - 1 andalso #textLength buffer > 0 then (* edge case: diff --git a/test/normal-delete.sml b/test/normal-delete.sml index 76594f8..c531d27 100644 --- a/test/normal-delete.sml +++ b/test/normal-delete.sml @@ -1084,6 +1084,29 @@ struct in Expect.isTrue (stringIsExpected andalso cursorIsExpected) end) + , test + "deletes last char when on last word \ + \and there is no newline after current word" + (fn _ => + let + (* arrange *) + val app = TestUtils.init "hello world" + val app = AppWith.idx (app, 6) + + (* act *) + val {buffer, cursorIdx, ...} = TestUtils.updateMany (app, "dw") + + (* assert *) + val expectedString = "hello " + val actualString = LineGap.toString buffer + + val expectedIdx = 5 + + val stringIsExpected = expectedString = actualString + val cursorIsExpected = cursorIdx = expectedIdx + in + Expect.isTrue (stringIsExpected andalso cursorIsExpected) + end) ] val dWDelete = describe "delete motion 'dW'"