Skip to content

Conversation

@masmu
Copy link
Contributor

@masmu masmu commented Jan 27, 2026

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 DoTextEvent logic for TextEventRemove handled 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:

VERSION = "1.0.0"

local micro = import("micro")
local buffer = import("micro/buffer")

function postinit()
    local bp = micro.CurPane()
    if bp.Buf:Size() > 0 then
        return
    end
    testCase1(bp)
end

function testCase1(bp)
    bp.Buf:Insert(buffer.Loc(0, 0), "AABBCC")

    -- Place cursor at (3, 0) - Between the two Bs
    -- A A B | B C C
    -- 0 1 2 3 4 5 6
    local c = bp.Buf:GetActiveCursor()
    c.Loc = buffer.Loc(3, 0)

    micro.Log("Start: Cursor at " .. c.Loc.X .. "," .. c.Loc.Y)
    bp.Buf:Remove(buffer.Loc(2, 0), buffer.Loc(4, 0))

    -- Without the fix (missing lines 97-98 in eventhandler.go):
    -- The cursor is "greater than start (2)" BUT NOT "greater than end (4)".
    -- The logic falls through, and the cursor position is NOT updated.
    -- It remains at (3,0).

    -- With the fix:
    -- The cursor is detected as being inside the removed range and clamped to start (2,0).

    if c.Loc.X == 3 then
        micro.InfoBar():Message(
            "BUG DETECTED: Cursor stayed at index 3 (Should be 2)")
    elseif c.Loc.X == 2 then
        micro.InfoBar():Message(
            "NO BUG DETECTED: Cursor correctly moved to index 2")
    else
        micro.InfoBar():Message("Unexpected: Cursor at " .. c.Loc.X)
    end

    micro.Log("End: Cursor at " .. c.Loc.X .. "," .. c.Loc.Y)
end

masmu added 2 commits January 27, 2026 10:19
- Basic insert/remove/replace operations
- Trailing whitespace updates
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.

Also adds regression tests covering:
- Multiple cursors inside removed regions
- Cursors spanning across removal boundaries
- Multiline replacements
@Andriamanitra
Copy link
Contributor

Similar bugs exist for replace/replaceall commands. This PR doesn't fix those because they don't use DoTextEvent (they go through eh.MultipleReplace -> eh.Execute -> ExecuteTextEvent).

@masmu
Copy link
Contributor Author

masmu commented Jan 27, 2026

Thanks for the review. You are correct that Replace / ReplaceAll (via MultipleReplace) bypass DoTextEvent and thus aren't covered by this fix.

However, the primary goal of this PR was to fix the cursor desync issues causing annoying cursor jumps.

Fixing MultipleReplace (which supports multiple deltas and skips DoTextEvent entire logic) seems like a larger, separate task. Would you agree?

@Andriamanitra
Copy link
Contributor

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.

@masmu
Copy link
Contributor Author

masmu commented Jan 27, 2026

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants