I finally bit the bullet, deleted all of our put logic, and re-implemented it from scratch.
This includes `p`, `P`, `gp`, `gP`, `]p`, `[`, and `:put`.
In addition to cleaner, more maintainable code, this resulted in:
- Using replace transformations, which means better performance
- Fixing VisualBlock put and block-wise put (fixes#1796)
- Fixing put when the register contains a macro (fixes#3714)
- Fixing various other corner cases, particularly with regards to cursor placement
- Beefing up our test suite
I'm sure there are still obscure corner cases that we handle wrong, but it'll be easier going forward to fix them.
This ignores the Position its applied to and just sets the line/character to its parameters.
Turns out this absurdly simple addition will help us pay off a lot of technical debt.
- Each register now points to an array - the i'th slot contains the content for the i'th cursor
- If there are more cursors than slots, the first slot is used as a backup
- Each slot contains either a RecordedState (in the case of a macro) or a string
- Newlines in those strings should be interpreted in the context of the associated RegisterMode
- The interface was changed somewhat to be safer and more consistent
I probably broke *something*, but the tests pass and this refactor enables further improvement of the terrible put logic, so I'll fix things as they come up.
This is easily one of the worst areas of the codebase.
It really needs a fundamental refactor (closer to a rewrite, really), but a good first step is to make it a bit more understandable as-is.
This attempts to change no behavior or even fundamental logic, just to make it a bit easier to reason about.
- Rename word methods to be more intuitive
- Use Position methods instead of standalone functions
- Use an object for pseudo-kwargs
- Pass WordType instead of having separate methods for "big" words
- Take `TextDocument` as a parameter
The result is a bit verbose (a more fundamental refactor might be needed
at a later date), but it's consistent, safe, and extensible.
This prepares for some changes to fix corner cases in our word handling.
Refs #5663
This saves ~15-20ms each time the mode changes, which is most impactful when repeating an action or macro that changes mode a few times.
I don't think this should cause any issues...
This fixes some edge cases as well as doing the edits in parallel
Fixes#4915, Refs #5663
Known issue: interactive `:s` does not update the document until the last replace is confirmed
- Much better edit merging, so undoing/redoing should generally only take one replace
- Correct changelist edge cases
- Improve and organize related tests
Known issue: `U` after `O` is broken, but that's a small corner case and `U` is generally much better behaved now.