-
Notifications
You must be signed in to change notification settings - Fork 29.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
Order of edit changes in TextDocumentChangeEvent.contentChanges is reverse the order of the actual edits #11487
Comments
@drew-wallace How do you build your edits? Via Note they will all be applied at the "same time" and the order in which you specify them is of no consequence. |
Here's a simple example: vscode.window.activeTextEditor.edit(function (textEditorEdit) {
textEditorEdit.insert(start, "first");
textEditorEdit.insert(start, "second");
});
vscode.workspace.onDidChangeTextDocument(function(TextDocumentChangeEvent) {
console.log(TextDocumentChangeEvent.contentChanges[0].text); // output: "second"
console.log(TextDocumentChangeEvent.contentChanges[1].text); // output: "first"
}); |
Ok, I might have jumped ahead of myself :). The order in which you specify the edits is of consequence if the edits touch the same location. Perhaps an explanation of how this works would help:
I hope this makes sense, and perhaps you can explain what you're trying to do, maybe there are better ways to do what you want to do that do not introduce knowledge of the model edits implementation details. |
I was trying to work around these issues: #11418 and #10801. The goal was to make an edit and attach an insert of a very long static string so that I could filter the edits that had it and the edits that don't. I needed this because I'm working on a remote pair programming extension and when a remote user makes an edit, the local user receives the edit, but the local user's listener picks up on it and triggers the same edit on the remote user, which causes an infinite loop. This workaround didn't end up working anyway, because I was unable to delete that static string from within the listener. I realize it was probably a bad idea to force edits to have the feature I need since I don't entirely understand what kinds of things can happen when making large edits. |
Cool use-case. This is how I'd do it (pseudocode ignoring multiple documents but the principle should hold): function delta(text1, text2) {
// ... diff/LCS algorithm here
}
function patch(text, edits) {
// apply edits produced by above delta to text here
}
// true when I've posted edits and I don't know if they were applied yet.
var waitingForApplyingMyEdits = false;
// Record last seen text and fetch current text,
// determine diff, send edits off to a server
var lastSentText = doc.getText();
function reconcile() {
if (waitingForApplyingMyEdits) {
return;
}
var currentText = doc.getText();
var edits = delta(lastSentText, currentText);
lastSentText = currentText;
// send edits to server
}
function applyIncomingEdits(edits) {
var currentText = doc.getText();
var desiredText = patch(currentText, edits);
// block any reconciliation until we submit this edit
waitingForApplyingMyEdits = true;
editor.edit((builder) => {
}).then(function(applied) {
waitingForApplyingMyEdits = false;
if (!applied) {
// TODO: try again! user changed the file in the meantime
} else {
// force to compute delta between what I expected and what actually happened
lastSentText = desiredText;
reconcile();
}
});
}
// 500ms after the last edit begin to reconcile
var reconcileTimeout = -1;
workspace.onDidChangeTextDocument((e) => {
clearTimeout(reconcileTimeout);
reconcileTimeout = setTimeout(reconcile, 500);
}); |
@alexandrudima that's a subtle detail that needs to be documented. So as each change in
What about edits received -- can extension authors assume that the changes in |
@alexandrudima This could work, but I think I might wait for the #10801. Having the source of the edit would reduce complexity. |
@siegebell Good point, the doc comment is lacking in this regard (explanation regarding applying edits at the same time). I remember describing this in great detail somewhere in https://github.com/Microsoft/vscode-docs/ but I think it got lost when we went open source. That is exactly what I'm trying to prevent -- that you in any way depend on the order or the shape of the content change events. The contract is that if you begin following independently a certain document and consistently apply the content change events (in the order you received them) you will end up with a document in the same state (same text) as our document. No guarantess about the sort order, about the count, etc. I would like to keep the door open if we need to improve our edit applying code. |
Steps to Reproduce:
TextDocumentChangeEvent.contentChanges
Notice how the order is reverse the order of the actual edit order.The text was updated successfully, but these errors were encountered: