-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
VSCodeVim Undo stack should be synced with VSCode undo stack #1490
Comments
The basic explanation is this. We could very easily map ctrl-z to u and ctrl-y to redo. We don't. Why? We have u/Ctrl-r, and (to my untrained eyes) they seem to work basically perfectly. HOWEVER, as you noticed, we are maintaining our own undo history. We have to because it diverges from VSCode. That means there is a naggling possibility there's still a bug somewhere that would lose your history soehow. Indeed, #1503 looks like one example. If there is such a bug, that would be REALLY BAD and you would lose work you finished. So rather than risk that 1% possibility, we just leave in the ctrl-z/y behavior, so that if we do screw up, you can still use them. Feel free to leave feedback on whether this seems like a reasonable approach or not. |
I can see that the search & replace thing would be the cause of some confusion though. Let me know what you think. |
I think I would prefer it if u/ctrl+R just was mapped straight to the same commands as ctrl+Z/ctrl+Y. What functionality is so important that VSCodeVim had to reimplement a history stack? |
@Maistho That would be history itself. 😄 Vim's history does not correspond with VSCode's in important ways. |
@johnfn okay 👌 I mapped u and C-r to undo/redo instead and it seems to work as it should imo. Not sure what I'm missing x) |
@Maistho did my explanation (#1490 (comment)) not explain it? 😉 |
@johnfn What I mean is that I bound u and C-r to vscodes built in commands (undo/redo) instead of the vim extensions undo/redo. Which means that I just don't use the vim extensions undo/redo functionality at all. :) |
Ohh, I misread, my mistake! Trust you me @Maistho, if there is a single absolute truth in this treacherous world, it's that for every single Vim behavior, there is a person who will be very upset if that feature is off even by a single character. 😄 So yeah, we do have to do them the Vim way. I'm glad that the VSCode commands work for you, though. That's awesome. |
@Maistho There's a couple big limitations with Vim's Ctrl-z functionality. One big example is macros. |
Could you explain in more details the differences between Vim's und VSCode's undo stack features? I'm curious to understand what causes the conflict in this case. |
@bs One example is macros. Following VSCode's undo stack, every ctrl+z press would undo one of the actions of the macro. However, in vim, you would want to undo the entire macro. At the time undo functionality was implemented, VSCode didn't have the API features it has now. I believe VSCode added some new API features that allow us to interface with the undo stack, though. |
@Chillee Ah, fantastic. I'm not a huge user of macros, otherwise I would dive in. Looking forward to this being tackled though! |
@johnfn Do you think that if we set VSCode's undo stops to correspond with how they should be in vim, we can get rid of our undo stack completely? It does mean that we'll never implement the vim undo tree though... 😏 |
Yes, definitely. That won't actually solve the problem in this issue however. Fixing this issue would essentially be a search and replace to replace "trigger a vscodevim undo step" with "trigger a vscode undo step". But the real problem here is that there are places where we should be triggering a step that we aren't. |
@johnfn wait what is it that simple? I've seen a bunch of buggy behavior related to undo that would probably be fixed by having vscode manage undo stops. Is there any advantage to having us manage undo behavior? Is there actually a vscode "trigger undo stop" command we can call? I've only seen it around the edit API's. |
There are a fair amount of times where we use our undo history for something that vscode can't give us trivially. The biggest one that comes to mind is definitely stuff like jj to escape, which walks back a certain number of insertions (that may not have been stored in undo history). But my approach is the basic strategy yeah. |
It is funny that I never remembered the shortcut for REDO in VIM, so whenever I try to undo and it undid a huge chunk of my code, I try to REDO, using the VSCode menu entry. And then the editor enters some weird state. Sometimes very confusing, and sometimes I end up losing a big chunk of my code. I have to say, this is very scary to use. |
At least for me, the currently broken behavior of undo right now is far worse than undo not undoing an entire macro execution. The behavior that happens in #2007 happens to me frequently and it is tantamount to corrupting my files. I am often left in a state completely unaware of how much was undone and whether or not I'm able to use vscode vim undo/redo to adequately recover from that. |
@Maistho How did you accomplish the remapping to bypass vscode vim's undo/redo? I tried |
Meanwhile... |
Hey @johnfn, @Zalastax and I are working on implementing undo branches in vscode's native history system. We'd like to make it possible for you to hook into us instead of needing to maintain your own history, what would an API look like that would allow you to do that without compromising on all the wonderful vim-ness that your fans demand? P.S. should I open a new issue for this here? |
Here's a sub-bug that I'm hoping can be fixed or worked-around: |
This can be fixed by using the |
There's a newer VS Code extension called With this you get vim's actual undo/redo tree (not just a stack). I haven't tried it yet, but I suspect that vim's (neovim's) persistent history tree will also work (VS Code will have no idea it exists, neovim will simply be updating the text buffers in VS Code, so the history state effectively lives outside of VS Code and you never touch VS Code's history yourself). In the following video I skip to the closing JSX (HTML-like) tag with
@HamboLagos For me it only works if the file is re-opened in the same VS Code session. When I exit VS Code, the history is gone, and does not come back when I re-launch VS Code. |
For anybody still facing this issue, this setting gives me the desired behaviour: "vim.normalModeKeyBindings": [
{
"before": ["u"],
"after": [],
"commands": [
{
"command": "undo"
}
]
}
] |
@J-Fields I noticed you un-assigned yourself from this issue. Would you be able to do a brain dump of the latest status, to help give a starting point in case someone else wants to pick this up? In particular:
|
Followed suggession given by @ViaxCo and added the following mapping
Works fine. Does anyone see a risk with this workaround? |
@atulpatildbz As has been mentioned several times in the thread you are replying to, this doesn't work with macros. There's a few other commands and things this doesn't work with also, tabdo, many more. |
FWIW, it doesn't appear to run quite well yet, see this issue. |
Maybe I am missing something here, but instead of trying to have Vim use VS Code's undo stack, why not have VS Code use Vim's undo stack and undo/redo commands? i.e. Ctrl-Z is mapped to "vim-undo". It seems to me that Vim's undo implementation can perform a super set of the tasks that VS Code's does, so I don't see why this could go wrong. |
I believe the issue is that the extension can't just tap into |
I can personally say that vims undo has left me screwed twice already.
All this when the only changes I made were very minor. Has anyone else experienced this? |
@wakywayne yes, that's pretty much the whole point of this issue about the VSCode-Vim undo being unreliable. And I'm glad Git exists, I have also been saved from Git due to this. You will want to map your vim undo to use VSCode's undo (and redo) until this issue is fixed. |
@J-Fields would you kindly mind putting vscodevim's undo/redo behind an option, disabled by default, and marked "experimental", with VS Code's undo/redo being the default? |
Could I politely suggest that people can a) discuss ideas, and b) submit pull requests. But asking specific people to complete tasks is not in the spirit of open-source. |
To save people time, the workaround/solution here seems to work for me (very basic testing ONLY). Handily, vscode also no longer shows a file as modified after undoing my changes! |
Maybe it doesn't allow something, maybe it breaks something. Yet @atulpatildbz gave the freedom of choice to every user of your extension. Since last update of VSCode there are some issues with u(ndo) in vim. Remaping to VSCode undo / redo commands helped me get back to work for now. |
Just within the last few days my undo has switched from being perfect to being completely broken. As an example, I will now make a motion like EDIT: I'm nearly certain this sudden change is related to enabling |
@martinemde see #8157 |
Relatedly, is there a way to reduce the granularity of vim's undo? in my experience it's quite high compared to the default one, which I find much better. |
I'm also seeing weirdness with
@martinemde what i'm seeing sounds similar to what you describe, did you ever get to the bottom of this, or was it fixed in #8157? |
I gave up on format on save. I haven't tried again since this disruptive problem. Maybe someone else figured it out? |
@martinemde sad to hear that! ok in the meantime i'm going to try using the below normal mode remapping to remap "vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["u"],
"after": [],
"commands": [
{
"command": "undo",
"args": []
}
]
},
{
"before": ["<C-r>"],
"after": [],
"commands": [
{
"command": "redo",
"args": []
}
]
}
] |
Any progress here? |
Is the workaround of not using format-on-save still valid to this issue? I moved to Neovim from VSCode a couple of years ago because of this very problem, and now I’m considering moving back to VSCode. @ivnsch Have you tried that workaround, and did you find it helpful? |
VSCodeVim undo is not synced with VSCode undo. I've provided a couple different issues/test cases below to illustrate what I mean:
Simple undo
VSCode and VSCodeVim seem to maintain different undo stacks, such that pressing
u
in VIM adds to the VSCode undo stack so that doing a VSCode undo (CMD-Z
) undoes the VIM undo.u
andCMD-Z
should have the same function and share a common undo stack.Search Replace
When doing a vim-based search and replace, one change with all the replacements is pushed to the VSCodeVim undo stack, whereas one change for each replacement is pushed to the VSCode undo stack. It's easy to get confused about the state of the document if you make a replacement, then press
CMD-Z
thinking you've reversed all the changes, make some other changes, then have to backtrack to revert the rest of the replacements.I'm not familiar with the extension architecture for VSCode, so I'm not sure what is technically possible here.
I can break these off into separate issues if you'd prefer.
thumbs-up 👍 this issue if it personally affects you! You can do this by clicking on the emoji-face on the top right of this post. Issues with more thumbs-up will be prioritized.
Simple undo
What did you do?
Press
i
. Type some text:PIZZA
. Press escape. Pressi
. Type some more text:IS GREAT
. Press theu
key to undo. Press CMD-Z.What did you expect to happen?
" IS GREAT" should disappear upon pressing
u
. "PIZZA" should disappear upon pressing CMD-Z so we're left with an empty string.What happened instead?
" IS GREAT" disappeared and then reappeared upon pressing CMD-Z so we're left with "PIZZA IS GREAT".
Search and replace
What did you do?
Given a 50-line document with the string "Pizza" on each line, type
%s/Pizza/Hot Dogs/
from the VSCodeVim command line. PressCMD-Z
.What did you expect to happen?
"Pizza" should appear on every line.
What happened instead?
"Hot Dogs" appears on every line except the last one which shows "Pizza". Similarly, if you first undo with
u
then pressCMD-Z
, "Pizza" appears on every line except the first one which shows "Hot Dogs".Technical details:
The text was updated successfully, but these errors were encountered: