Repository navigation
Conversation
|
Similar bugs exist for |
|
Thanks for the review. You are correct that However, the primary goal of this PR was to fix the cursor desync issues causing annoying cursor jumps. Fixing |
|
That's fair. I pointed it out because that's the issue I first assumed this PR was fixing, and I was surprised to see no change in behavior when I went to test it. |
|
No worries, that makes sense. Would you be able to review this PR? I was hoping to get this merged soon, as this fix is a prerequisite for some more bug fixes I have already prepared. |
|
I had no time to do the review yet, but absolutely great to see an official test for this! 👍 |
| } else if loc.Y == end.Y && loc.GreaterEqual(end) { | ||
| loc = loc.MoveLA(-DiffLA(start, end, eh.buf.LineArray), eh.buf.LineArray) | ||
| } else if loc.GreaterThan(start) { | ||
| loc = start |
There was a problem hiding this comment.
The entire fix is this 2-line change, the rest of this commit is just adding tests?
So move those tests to a separate commit (so that it is immediately seen what exactly the fix is)?
...Also nit: could you wrap lines in the commit message, e.g. with 72 characters limit?
There was a problem hiding this comment.
Yes, just those 2 lines.
...Also nit: could you wrap lines in the commit message, e.g. with 72 characters limit?
Sure.
There was a problem hiding this comment.
Thank you.
Shall we switch the two commits to introduce the fix first before we add the regression test?
There was a problem hiding this comment.
You are welcome.
That has been holding up a refactoring for almost a year now. No offense to you guys. I know you are doing your best.
Shall we switch the two commits to introduce the fix first before we add the regression test?
Whatever works best for you.
There was a problem hiding this comment.
Whatever works best for you.
This is how I would do it: First the fix, then the test.
We're just about to cross the finish line. Let's cross it. 😅
There was a problem hiding this comment.
Yep, if the test is introduced first, it causes a temporary regression of make test in the 1st commit (fixed only by the 2nd commit). That is not a huge problem, but still potentially might cause unnecessary troubles when bisecting.
|
Apologies for long delayed review. The fix looks good to me, thanks. Please just split the 2nd commit to separate the actual fix from the tests, as I asked above. I haven't reviewed the tests yet. |
|
BTW a simple lua function for testing the fix (can be bound to a key via function removeAround(bp)
bp.Buf:Remove(bp.Cursor.Loc:Move(-2, bp.Buf), bp.Cursor.Loc:Move(2, bp.Buf))
end |
8dcf9a8 to
a5baf1c
Compare
| } | ||
| } | ||
|
|
||
| func TestReplaceMultiLineCursorMovement(t *testing.T) { |
There was a problem hiding this comment.
Why MultiLine if it only deals with a single line?
There was a problem hiding this comment.
True. It should be probably named something like TestReplaceSingleLineCursorAndSelectionShift.
Is that okay?
There was a problem hiding this comment.
AFAICS what this test does is: replace text which overlaps with the selection (but doesn't contain the cursor position). The name TestReplaceSingleLineCursorAndSelectionShift doesn't quite reflect that? The selection is not just shifted, it is modified?
Also why need to emphasize SingleLine? E.g. the above and below test names TestReplaceWithSelection and TestReplaceSelectedTextCursorPosition don't emphasize it?
There was a problem hiding this comment.
Yep, good point. What do think of TestReplaceOverlappingSelection?
| } else if loc.Y == end.Y && loc.GreaterEqual(end) { | ||
| loc = loc.MoveLA(-DiffLA(start, end, eh.buf.LineArray), eh.buf.LineArray) | ||
| } else if loc.GreaterThan(start) { | ||
| loc = start |
There was a problem hiding this comment.
Yep, if the test is introduced first, it causes a temporary regression of make test in the 1st commit (fixed only by the 2nd commit). That is not a huge problem, but still potentially might cause unnecessary troubles when bisecting.
Previously, if a cursor was positioned strictly inside a range of text being removed (start < cursor < end), the event handler failed to update its position. This resulted in the cursor retaining its old X/Y coordinates, effectively "jumping" forward into subsequent text. The fix ensures that any cursor inside the removed region is clamped to the start of the deletion.
a5baf1c to
5348393
Compare
| expectedLoc1 := Loc{5, 0} | ||
| if cursor1.Loc != expectedLoc1 { | ||
| t.Errorf("Expected cursor1 at %v, got %v", expectedLoc1, cursor1.Loc) | ||
| } |
There was a problem hiding this comment.
Any reason why not check cursor1.Selection here?
There was a problem hiding this comment.
Probably just missing, I am gonna add the selection assertion for cursor1. 👍
| cursor.Num = 0 | ||
| buf.SetCursors([]*Cursor{cursor}) | ||
|
|
||
| buf.Remove(Loc{11, 0}, Loc{13, 0}) |
There was a problem hiding this comment.
12..13 would be a more interesting test?
There was a problem hiding this comment.
Yes. I would vote to add a new test for this and update the name of the current test to mirror the names of RemoveAtEOLNoTrailingWs / RemoveAtEOLLeavingTrailingWs.
So:
TestUpdateTrailingWsRemoveWsOnlyAtEOLLeavingNoTrailingWsTestUpdateTrailingWsRemoveWsOnlyAtEOLLeavingTrailingWs
The names get long though.
|
|
||
| func TestUpdateTrailingWsLineShiftInsert(t *testing.T) { | ||
| buf := NewBufferFromString("line1\nline2 \nline3", "", BTDefault) | ||
| cursor := NewCursor(buf, Loc{8, 1}) |
There was a problem hiding this comment.
We don't have as many as 8 characters at line 1?
There was a problem hiding this comment.
That's right, good catch! It was actually supposed to be {7, 1}. I'll fix that.
|
|
||
| func TestUpdateTrailingWsLineShiftRemove(t *testing.T) { | ||
| buf := NewBufferFromString("line1\nline2\nline3 \nline4", "", BTDefault) | ||
| cursor := NewCursor(buf, Loc{8, 2}) |
There was a problem hiding this comment.
We don't have as many as 8 characters at line 2?
There was a problem hiding this comment.
Here was well! It was actually supposed to be {7, 2}. I'll fix that.
| buf.Replace(Loc{6, 0}, Loc{11, 0}, "test") | ||
|
|
||
| if cursor.NewTrailingWsY != -1 { | ||
| t.Errorf("Expected NewTrailingWsY to be -1 (cursor not at EOL after replace), got %d", cursor.NewTrailingWsY) |
There was a problem hiding this comment.
Cursor is actually still at EOL after replace in this test?
There was a problem hiding this comment.
Ehm ... yes? 🤔
Before the replacement: Test string's width = 13, we place the cursor to EOL {13, 0}.
We replace world with test, which is one character shorter than before.
So the new EOL is {12, 0}. The cursor remains there.
Have I completely misunderstood something here?
There was a problem hiding this comment.
Ahh, that's not clear from the message. Should we maybe change the text to (cursor not at insert end)?
- Basic insert/remove/replace operations - Trailing whitespace updates - Multiple cursors inside, before and after removed regions - Cursors spanning across removal boundaries - Multiline replacements
5348393 to
7d5e0df
Compare
This PR fixes a bug in the buffer event handler where cursors positioned strictly inside a removed text range (start < cursor < end) were not correctly updated.
Previously, the
DoTextEventlogic forTextEventRemovehandled cursors after the removed range and cursors at the end of the range, but fell through for cursors residing inside the range. This caused such cursors to retain their original (x, y) coordinates. Since the text before them was deleted, retaining the old coordinates meant the cursor effectively "jumped" forward relative to the content.Reproduction:
Without the Lua plugin system, it is difficult to trigger the bug, but it can be easily reproduced with the following code: