From 1255238d6c02d885357b175ca93be07aa887014f Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Wed, 24 Sep 2025 19:32:31 +0100 Subject: [PATCH] pass failing tests for 'dj' motion --- fcore/normal-mode/make-normal-delete.sml | 63 ++++++++++++++++++++++-- test/normal-delete.sml | 6 +-- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/fcore/normal-mode/make-normal-delete.sml b/fcore/normal-mode/make-normal-delete.sml index 7f824bf..7fd438a 100644 --- a/fcore/normal-mode/make-normal-delete.sml +++ b/fcore/normal-mode/make-normal-delete.sml @@ -374,12 +374,65 @@ struct NormalModeWith.bufferMsgsAndMode (app, buffer, [], NORMAL_MODE "") else let - val () = print "not on last line so have to delete\n" - val () = print - ("startLine = " ^ Int.toString startLine ^ "; endLine = " - ^ Int.toString endLine ^ "\n") + val buffer = LineGap.goToIdx (endLineIdx, buffer) + + (* right now, endLineIdx may be on a newline. + * If it is, we want to delete that newline too, + * and in that case, we increment by 1 to do so. + * However, we don't want to delete the last newline in the file + * so we don't increment in that case. + * Edge case: if the startIdx also begins after a newline + * then it is okay for us to delete the newline at the end of the file + * because there will already be a newline at the end of the file + * after the deletion. *) + val endsOnNewline = Cursor.isCursorAtStartOfLine (buffer, endLineIdx) + + val buffer = LineGap.goToIdx (startIdx, buffer) + val startsAfterNewline = + startIdx > 0 andalso Cursor.isPrevChrStartOfLine (buffer, startIdx) + + val endLineIdx = + if endsOnNewline then + if endLineIdx = #textLength buffer - 1 then + if startsAfterNewline then endLineIdx + 1 else endLineIdx + else + endLineIdx + 1 + else + endLineIdx + + val length = endLineIdx - startIdx + + (* perform the actual deletion *) + val buffer = LineGap.goToIdx (endLineIdx, buffer) + val initialMsg = Fn.initMsgs (startIdx, length, buffer) + val buffer = LineGap.delete (startIdx, length, buffer) + + (* if we deleted end of file, then we have to move the cursorIdx + * to the first column of the now-last line *) + val newEndIdx = #textLength buffer - 1 in - raise Fail "" + if startIdx >= newEndIdx then + let + val buffer = LineGap.goToIdx (newEndIdx, buffer) + in + if Cursor.isOnNewlineAfterChr (buffer, newEndIdx) then + let + val buffer = LineGap.goToIdx (newEndIdx - 1, buffer) + val newCursorIdx = Cursor.vi0 (buffer, newEndIdx - 1) + in + finishAfterDeletingBuffer + (app, newCursorIdx, buffer, time, initialMsg) + end + else + let + val newCursorIdx = Cursor.vi0 (buffer, newEndIdx) + in + finishAfterDeletingBuffer + (app, newCursorIdx, buffer, time, initialMsg) + end + end + else + finishAfterDeletingBuffer (app, startIdx, buffer, time, initialMsg) end end diff --git a/test/normal-delete.sml b/test/normal-delete.sml index d27080c..61ba542 100644 --- a/test/normal-delete.sml +++ b/test/normal-delete.sml @@ -349,7 +349,7 @@ struct val app = AppWith.idx (app, originalIdx) (* act *) - val {cursorIdx, buffer, ...} = TestUtils.updateMany (app, "dl") + val {cursorIdx, buffer, ...} = TestUtils.updateMany (app, "dj") (* assert *) val actualString = LineGap.toString buffer @@ -374,11 +374,11 @@ struct val app = AppWith.idx (app, originalIdx) (* act *) - val {cursorIdx, buffer, ...} = TestUtils.updateMany (app, "dl") + val {cursorIdx, buffer, ...} = TestUtils.updateMany (app, "dj") (* assert *) val actualString = LineGap.toString buffer - val expectedString = "bye world\n" + val expectedString = "hello\n" val stringIsExpected = actualString = expectedString val expectedCursorIdx = 0