When a file is being modified in Code, then an external process modifies something in the file, for example a code formatter, the modification is loaded instantly in Code, but all the history is lost.
Expected behavior would be to have the external modification, as one entry in the history.
1 - Start a new file in VS Code and start typing in the file, then save the file. Keep the file and VS Code open.
2 - Open the same file in another editor. Modify some thing and save.
3 - Go back to VS Code , there is not 'Undo' available.
Indeed, the current handling of a file change on disk is to drop the old buffer and allocate everything fresh. I'm wondering what other editors do...
fyi @bpasero
Sublime considers the external modification as an entry in the history. So if you do one undo all the external modifications would be reverted, and if you keep undoing, you would get back to history of modifications you did in the same window.
The problem with dropping the buffer is when you have an external process to monitor the files and for example format it. (i.e. go fmt or js-beautify). So this would result in to lose all the history in the editor.
Would indeed be very nice to preserve the undo history even for changes outside Code.
This has saved me in Sublime before; I'd really like to see it in code.
Scenario: Working with multiple repos in multiple terminals, VS Code used to edit files in one (still using the terminal for git operations). In a terminal for another repo I want to blow away any unstaged changes so I throw a git checkout -- . at it. Surprise! That was the terminal for files open Code, not the other one I really wanted. How do I get those changes back? Ideally I'd just go into each open buffer and undo to get those edits back.
This is the only thing that keeps me going back to atom or sublime. Would love to see this feature implemented. Is it in the pipeline or planned..?
Agree, that feature in Sublime has been a life saver many times.
Just blew away two hours of work by typing git checkout -- * in the wrong console. Sad to find this as an open feature request instead of a lifeline! (And frankly kind of surprised that by now, git doesn't just cache things it overwrites in some non-persistent space so you have a quick undo recourse, seems like it would be a pretty simple idiot saver)
Damn it, accidentally ran git checkout . and couldn't restore file opened in vscode too =[
Would be very useful
Webstorm allows this as well, and is incredibly helpful at times.
Almost a year now , undo history should be preserved.
For the time being those in need can use "history" extension at marketplace. Although a workaround, works for time being in case files get replaced, for e.g. git checkouts or losing the stash.
@aga5tya Do you mean xyz.local-history?
@emyller, yes, that's the one.
+1
+1
Any update on this? Are there any plans to implement it?
+1
Just happened to me because I'm used to this behavior. Now to rewrite a few hours of code... 馃槥
I started looking into implementing this and have a few questions @waderyan @alexandrudima:
Here is the place where we clear the history: https://github.com/Microsoft/vscode/blob/f07f89928b9ea8b54c3fcb4c105c2d28f55b12dc/src/vs/editor/common/model/editableTextModel.ts#L82
What is the appropriate way to push an edit operation rather than clear the history?
I tried an initial naive approach of just putting the entire buffer onto the undo stack:
protected _resetValue(newValue: ITextSource): void {
// super._resetValue(newValue); <-- If I call this, the model is changed without an edit operation, and an edit operation no longer makes sense.
this._commandManager.pushEditOperation(
[new Selection(1, 1, 1, 1)],
[EditOperation.replace(this.getFullModelRange(), newValue.lines.join(newValue.EOL))],
(inverseEditOperations: editorCommon.IIdentifiedSingleEditOperation[]) => [new Selection(1, 1, 1, 1)]
);
// Destroy my edit history and settings
// this._commandManager = new EditStack(this);
this._hasEditableRange = false;
this._editableRangeId = null;
this._trimAutoWhitespaceLines = null;
}
But there are a few issues with pushing a new edit operation here.
1) There is an error in the MirrorModel when the file gets shorter:
Cannot read property 'substring' of undefined
at MirrorModel._acceptDeleteRange (file:///home/ryan/clones/vscode/out/vs/editor/common/model/mirrorModel.js:79:55)
at MirrorModel.onEvents (file:///home/ryan/clones/vscode/out/vs/editor/common/model/mirrorModel.js:37:22)
2) the file is marked as unsaved
3) We don't have access to cursor position information, so I'm just passing in a cursor at the beginning and a cursor calculator that always puts it at the beginning.
Perhaps we need to override setValueFromTextSource in the EditableTextModel rather than modifying _resetText?
How do I push an edit operation, tell the model that it's unchanged, and what should the cursor state and cursorStateComputer be?
@stringham thanks for looking into this :+1:.
The place to make the change is not in the model, within the setValue/setValueFromTextSource call (which is used in other cases than a file reload from disk), but one layer above, in the workbench, where the file is read from disk in the file change case.
A setValue/setValueFromTextSource call should be replaced with pushEditOperations, but these should be as small as possible as to not become a memory problem (i.e. if a file is changed on disk by appending one line, preferably, the edit would be to append that one line to the buffer, otherwise the entire old file will remain in memory).
Perhaps the updateModel in the model service (modelServiceImpl.ts) could do this, but all callers of updateModel should be inspected to see if it is expected that decorations, the undo stack, the editable range, etc. are expected to survive in all the calls cases. The current callers include a couple more places than the file changed on disk case (textEditorModel.ts)
I just lost code from this as well. My previous editor (PHPStorm) handled this beautifully. Very disappointing that VS Code has no way to undo external changes.
This is definitely a must have. I felt safe changing files outside as I used a use Sublime and ran into this today...
Great that you look into it @stringham :+1: !
+1
Any news?
I'm also affected by this. Means I still need to use sublime for certain projects.
yeah, this will be good. the undo function of sublime it's really a life saver
+1
Thanks to @stringham , if all goes well with testing, this will make it into our August release.
When we can expect this to be live as today I faced the same issue while trying tasks in vscode. I created a wrong task and boom, my file was changes and now I can not undo it at all.
@akanshgulati AFAIK this has been live since September. I'm on version 1.18.0 and it works
@rhymes I tried using cmd + z to undo it but could not revert to that previous state. Are you saying that above problem which I mentioned is solved through this issue or I am referring different problem altogether?
@akanshgulati I don't know if it's the same problem.
Try: open a text file with vscode, write something in it, open the same file with another editor, change the content, go back to vscode and you'll see the new content, do cmd - z and you should see the original content.
It also works with "git checkout -- file.txt" in case you're working inside a git repository.
Most helpful comment
Thanks to @stringham , if all goes well with testing, this will make it into our August release.