diff --git a/fcore/normal-mode/normal-move.sml b/fcore/normal-mode/normal-move.sml index 458c4d0..e26b6c6 100644 --- a/fcore/normal-mode/normal-move.sml +++ b/fcore/normal-mode/normal-move.sml @@ -275,21 +275,45 @@ struct val buffer = LineGap.goToLine (newCursorLineNumber, buffer) val lineIdx = LineGap.lineNumberToIdx (newCursorLineNumber, buffer) - val buffer = LineGap.goToIdx (lineIdx, buffer) - - val lineIdx = - if Cursor.isPrevChrStartOfLine (buffer, lineIdx) then lineIdx - else lineIdx + 1 - - val lineIdx = - if lineIdx >= #textLength buffer - 1 then - Int.max (0, #textLength buffer - 1) - else - lineIdx in - finishMoveCursorUpDown - (app, newCursorLineNumber, buffer, column, lineIdx) + if lineIdx >= #textLength buffer then + (* we reached last line *) + let + val lineIdx = Int.max (#textLength buffer - 1, 0) + val buffer = LineGap.goToIdx (lineIdx, buffer) + val startOfLine = Cursor.vi0 (buffer, lineIdx) + in + if cursorIdx >= startOfLine then + (* we are already on last line so don't move *) + NormalFinish.buildTextAndClear + (app, buffer, cursorIdx, searchList, [], bufferModifyTime) + else + finishMoveCursorUpDown + (app, newCursorLineNumber, buffer, column, startOfLine) + end + else if lineIdx = #textLength buffer - 1 then + (* last line in buffer ends with \n + * and we just reached it *) + let val () = print "296\n" + in raise Fail "" + end + else + let + val lineIdx = + if lineIdx >= #textLength buffer - 2 then + Int.max (0, #textLength buffer - 2) + else + lineIdx + + val buffer = LineGap.goToIdx (lineIdx, buffer) + val lineIdx = + if Cursor.isOnNewlineAfterChr (buffer, lineIdx) then lineIdx + 1 + else lineIdx + in + finishMoveCursorUpDown + (app, newCursorLineNumber, buffer, column, lineIdx) + end end end diff --git a/temp.txt b/temp.txt index e3652ac..94954ab 100644 --- a/temp.txt +++ b/temp.txt @@ -1,2 +1,2 @@ -hello world -time to go +hello +world diff --git a/test/normal-move.sml b/test/normal-move.sml index 9df0172..9445f1a 100644 --- a/test/normal-move.sml +++ b/test/normal-move.sml @@ -382,7 +382,7 @@ struct val app = AppWith.idx (app, initialCursorIdx) (* act *) - val {cursorIdx, ...} = TestUtils.updateMany (app, "2j") + val {cursorIdx, ...} = TestUtils.update (app, CHAR_EVENT #"j") (* assert *) val expectedIdx = 10 @@ -409,11 +409,11 @@ struct in Expect.isTrue (cursorIdx = expectedIdx) end) - , test "goes to last char in file when last char is not a newline" (fn _ => + , test "goes to last line in file when last char is not a newline" (fn _ => let (* arrange *) val str = "hello\nworld" - val initialCursorIdx = 6 + val initialCursorIdx = 0 val app = TestUtils.init str val app = AppWith.idx (app, initialCursorIdx) @@ -422,7 +422,7 @@ struct val {cursorIdx, ...} = TestUtils.update (app, CHAR_EVENT #"j") (* assert *) - val expectedIdx = String.size str - 1 + val expectedIdx = 6 in Expect.isTrue (cursorIdx = expectedIdx) end) @@ -441,6 +441,27 @@ struct (* act *) val {cursorIdx, ...} = TestUtils.update (app, CHAR_EVENT #"j") + (* assert *) + val expectedIdx = initialCursorIdx + in + Expect.isTrue (cursorIdx = expectedIdx) + end) + , test + "does not go to last chr in file \ + \when last chr is a newline preceded by a non-newline \ + \and a count is provided" + (fn _ => + let + (* arrange *) + val str = "hello\nworld\n" + val initialCursorIdx = 0 + + val app = TestUtils.init str + val app = AppWith.idx (app, initialCursorIdx) + + (* act *) + val {cursorIdx, ...} = TestUtils.updateMany (app, "2j") + (* assert *) val expectedIdx = initialCursorIdx in