-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Soft undo/redo (de)selection #1596
Comments
I with this 100%. But what would the default key binding be for soft-undo/redo? Maybe |
As @EpocSquadron pointed out, relevant Kakoune PR: mawww/kakoune#4725 |
I'm looking for something similar to vim's |
I didn't know about |
This will also enable more frequent use of the ref: #5784 |
I’d like to have this feature and am interested in implementing it myself. I fairly regularly screw up a selection due to Vim muscle memory. One question I have is what should happen when the buffer has been changed such that it isn’t really possible to undo a selection? A simple example: enter some text in a buffer, then %d. What should a soft undo do at this point given that the previous selection is no longer possible? Perhaps soft undo should only be possible back to the last modification? I’ll take a look at Kakoune and Sublime and see what they do. |
According to the PR description, it looks like they try to map the selection to the new buffer. |
I think in VSCode, soft-undo will do a hard-undo when necessary. |
I've taken a look at what other editors do for their soft undo/redo feature. VSCodeThe feature is called "Cursor undo" and it only works back to the last change. This is simple, pragmatic approach and works for the common "I just accidentally messed up my complicated selection" use case. KakouneKakoune's soft undo and redo is accessed via C-h and C-k. This will attempt to restore selections as best as possible even when text which had been selected no longer exists in the buffer. While this is impressive, it can result in weird selections when soft-undoing where parts of the buffer end up getting selected that are totally unrelated to the original selection. I'm not convinced that this is all that useful and can get a bit confusing. On the flip side, Kakoune's soft undo does allow you to get back to selections for lines that haven't been removed even when other parts of the buffer were removed in between. Note that Kakoune's undo stack and soft undo stack are completely independent. Sublime TextSublime Text's soft undo and redo are accessed via C-u and C-S-U. Soft undo/redo will step through all cursor movements, selections and changes. Normal undo (c-z) will just step back through changes. I find this very natural and easy to understand, but without the limited scope of VSCode's implementation. My only criticism here is that the name "soft undo" isn't all that accurate as it will result in undoing of actual changes to the buffer, not just selections. I would bet that changes and cursor movements/selections are stored in the same list with the normal undo/redo just skipping over the cursor/selection changes. Proposal for HelixI think we should go for the same approach as Sublime Text but call it "granular undo" or "micro undo". Or if storing a full selection history is considered too heavyweight let's go with VSCode's approach as I imagine this will cover 90% of use cases for this feature. Thoughts? |
Thanks for a nice summary of other editors' behaviors! I'd say that Sublime's approach is a mistake precisely because it mixes destructive and non-destructive operations. That's the reason I have to be careful using it since there is always this risk of changing the buffer. To me it's a categorically different kind of operation with no UI benefit of the combo. The Kakoune's attempt to restore selections despite the edits is impressive indeed, also share your concern it might be confusing, but haven't used it enough to know whether this concern outweighs the benefits |
The benefit of being up to step through both selections and changes is that you can get back to any previous selection and editing state. As mentioned, I wouldn't call this "soft undo" because it wouldn't be that but IMHO it's useful and easy to understand.
If the Kakoune approach is too much, would you then advocate for the simple approach taken by VSCode (undo selections back to the last buffer change)? I guess we could always start with that and expand the approach later if it's deemed important. |
But you don't need to only have the combo command to do that, this benefit can be achieved by using
You could even have one "combo"
Agree, I also think that it'd cover most of the use cases for this feature |
I've been thinking about this some more and reading Helix's code, and it occurs to me that there's an extra complication here which I hadn't appreciated until now.
This can be seen when using splits for the same file. Selections in one view aren't visible in the other, but changes to the document are seen in the other. This means that interleaving the selection history in the undo stack doesn't make sense. Any selection history has to be per Document+View. This also makes it more complicated to have a soft undo history which only goes back to the last change to the document (discussed above). With all this in mind, the following approaches seem like sensible ways forward:
Thoughts? Other observations I had while researching tonight:
|
You can have it in ST, open a file in a different project, then move the tab to the first project - you'll have to tabs with views of the same file. But they do have different undo stacks (both soft and hard), you can't undo edits made in tab1 that happened before you opened the same document in tab2 (and soft undos aren't shared at all) re. Doc+View: good idea, but just to clarify: this will be stored per view, so selection changes in View1 have no effect on selection changes in View2 (and their respective soft undo stacks), only the edits have an effect in any view? |
ok, interesting. That’s still consistent with how I imagine it works internally (and that sounds like a slightly odd UX).
Yes, exactly this. Selections are currently stored on Documents in a HashMap indexed by View. I was thinking that selection history would be stored in the same way such that each View has an independent selection history for each Document. In fact, I think ultimately there should be just one HashMap that points to the selection history for each view along where the history type also tracks the current selection. I think the way forward is clear now. I just need to make some time make the change. |
Not sure how far you got with this @mjs, but I have made a simple implementation of the VSCode approach (undo/redo selection until last change) here: Let me know if you think I should open a PR with it. |
@gertqin those code changes seem like a very nice concise implementation of soft undo to me! Please open a PR when you get a chance |
@gertqin I cherry-picked your implementation into a local build, it seems to work great! I just started using Helix recently and often mess up my selections. I found the editor hard to use without this feature. Please open a PR! |
Let's say I carefuly selected a few words between semicolons with a couple of useful
find_next_char
commands, and then accidentally move a cursor.Would be great if there were a pair of
soft_undo
andsoft_redo
(similar to Sublime Text's) that would allow me to easily revert selection changes just like regularundo
/redo
operate on text changeThe text was updated successfully, but these errors were encountered: