Skip to content

Conversation

@masmu
Copy link
Contributor

@masmu masmu commented Aug 6, 2025

When pasting from the clipboard (or inserting) with multiple cursors, cursors that are directly next to each other are filtered out.
The reason for this is that EventHandler.Replace triggers two separate events to mimic the replacement. These two events are processed sequentially in DoTextEvent, which means that these two consecutive cursors have the same position after TextEventRemove. The second event TextEventInsert, can no longer distinguish between them, and Buffer.MergeCursors filters out one cursor later.

How to reproduce:
Create 2 cursors with selections directly next to each other. Each cursor selects one c.

    cc

    ^^
    ||
    ||
    |cursor 2
    cursor 1

Insert any character, e.g. x or paste your clipboard.

Expectation:

    xx
    ^^
    ||
    ||
    |cursor 2
    cursor 1

Actual behavior:

    xx
     ^
     |
     |
     cursor 1

So, one cursor gets lost.

The last commit (Always stop Undo(), Redo() after TextEventReplace) is totally subjective and up for debate. For me personally it feels much better to have more control for TextEventReplace undos/redos. Let me know what you think.

masmu added 5 commits August 6, 2025 11:07
The code in `DoTextEvent` is quite hard to understand.
Why do we clamp an existing event here? Because we recalculate the end location
which should have been assigned before in `ExecuteTextEvent`.
The end locations for all `TextEventInsert` are incorrectly being stored in the undo stack and are hot-fixed while being processed.

This also fixes potential issues with `TextEventReplace` in regards to multi-line strings.
Getting the remaining characters after line breaks is a common task when dealing with TextEvents.
So make it a utility function and expose it to Lua. This is very useful when processing these events in Lua plugins.
…Remove`, `TextEventInsert`)

When pasting from the clipboard with multiple cursors, cursors that are directly next to each other are filtered out.
The reason for this is that `EventHandler.Replace` triggers two separate events to mimic the replacement. These two events are processed sequentially in `DoTextEvent`, which means that these two consecutive cursors have the same position after `TextEventRemove`. The second event `TextEventInsert`, can no longer distinguish between them, and Buffer.MergeCursors filters out one cursor later.
After replacing text, it is (imho) helpful to undo/redo changes individually. With a single cursor, nothing changes, but with multiple cursors, this gives the user a greater sense of control.
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.

1 participant