未验证 提交 52e9e02e 编写于 作者: A Alex Dima

Fixes #110141: Do not push undo stack elements for a no-op EOL change

上级 549da12a
......@@ -1014,4 +1014,38 @@ suite('vscode API - workspace', () => {
}
});
test('issue #110141 - TextEdit.setEndOfLine applies an edit and invalidates redo stack even when no change is made', async () => {
const file = await createRandomFile('hello\nworld');
const document = await vscode.workspace.openTextDocument(file);
await vscode.window.showTextDocument(document);
// apply edit
{
const we = new vscode.WorkspaceEdit();
we.insert(file, new vscode.Position(0, 5), '2');
await vscode.workspace.applyEdit(we);
}
// check the document
{
assert.equal(document.getText(), 'hello2\nworld');
assert.equal(document.isDirty, true);
}
// apply no-op edit
{
const we = new vscode.WorkspaceEdit();
we.set(file, [vscode.TextEdit.setEndOfLine(vscode.EndOfLine.LF)]);
await vscode.workspace.applyEdit(we);
}
// undo
{
await vscode.commands.executeCommand('undo');
assert.equal(document.getText(), 'hello\nworld');
assert.equal(document.isDirty, false);
}
});
});
......@@ -695,6 +695,11 @@ export interface ITextModel {
*/
getEOL(): string;
/**
* Get the end of line sequence predominantly used in the text buffer.
*/
getEndOfLineSequence(): EndOfLineSequence;
/**
* Get the minimum legal column for line at `lineNumber`
*/
......
......@@ -830,6 +830,15 @@ export class TextModel extends Disposable implements model.ITextModel {
return this._buffer.getEOL();
}
public getEndOfLineSequence(): model.EndOfLineSequence {
this._assertNotDisposed();
return (
this._buffer.getEOL() === '\n'
? model.EndOfLineSequence.LF
: model.EndOfLineSequence.CRLF
);
}
public getLineMinColumn(lineNumber: number): number {
this._assertNotDisposed();
return 1;
......
......@@ -1685,6 +1685,10 @@ declare namespace monaco.editor {
* @return EOL char sequence (e.g.: '\n' or '\r\n').
*/
getEOL(): string;
/**
* Get the end of line sequence predominantly used in the text buffer.
*/
getEndOfLineSequence(): EndOfLineSequence;
/**
* Get the minimum legal column for line at `lineNumber`
*/
......
......@@ -39,6 +39,18 @@ class ModelEditTask implements IDisposable {
this._modelReference.dispose();
}
isNoOp() {
if (this._edits.length > 0) {
// contains textual edits
return false;
}
if (this._newEol !== undefined && this._newEol !== this.model.getEndOfLineSequence()) {
// contains an eol change that is a real change
return false;
}
return true;
}
addEdit(resourceEdit: ResourceTextEdit): void {
this._expectedModelVersionId = resourceEdit.versionId;
const { textEdit } = resourceEdit;
......@@ -219,10 +231,12 @@ export class BulkTextEdits {
if (tasks.length === 1) {
// This edit touches a single model => keep things simple
const task = tasks[0];
const singleModelEditStackElement = new SingleModelEditStackElement(task.model, task.getBeforeCursorState());
this._undoRedoService.pushElement(singleModelEditStackElement, this._undoRedoGroup);
task.apply();
singleModelEditStackElement.close();
if (!task.isNoOp()) {
const singleModelEditStackElement = new SingleModelEditStackElement(task.model, task.getBeforeCursorState());
this._undoRedoService.pushElement(singleModelEditStackElement, this._undoRedoGroup);
task.apply();
singleModelEditStackElement.close();
}
this._progress.report(undefined);
} else {
// prepare multi model undo element
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册