mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-29 19:59:19 +01:00
Merge pull request #152759 from microsoft/joh/issue152719
This commit is contained in:
@@ -19,17 +19,19 @@ import { ResourceMap } from 'vs/base/common/map';
|
||||
import { IModelService } from 'vs/editor/common/services/model';
|
||||
import { ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser';
|
||||
import { performSnippetEdits } from 'vs/editor/contrib/snippet/browser/snippetController2';
|
||||
import { SnippetParser } from 'vs/editor/contrib/snippet/browser/snippetParser';
|
||||
|
||||
type ValidationResult = { canApply: true } | { canApply: false; reason: URI };
|
||||
|
||||
type ISingleSnippetEditOperation = ISingleEditOperation & { insertAsSnippet?: boolean };
|
||||
|
||||
class ModelEditTask implements IDisposable {
|
||||
|
||||
readonly model: ITextModel;
|
||||
|
||||
private _expectedModelVersionId: number | undefined;
|
||||
protected _edits: (ISingleEditOperation & { insertAsSnippet?: boolean })[];
|
||||
protected _edits: ISingleSnippetEditOperation[];
|
||||
protected _newEol: EndOfLineSequence | undefined;
|
||||
|
||||
constructor(private readonly _modelReference: IReference<IResolvedTextEditorModel>) {
|
||||
@@ -94,14 +96,28 @@ class ModelEditTask implements IDisposable {
|
||||
apply(): void {
|
||||
if (this._edits.length > 0) {
|
||||
this._edits = this._edits
|
||||
.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range))
|
||||
.map(edit => ({ ...edit, text: edit.text && SnippetParser.escape(edit.text) }));
|
||||
.map(this._transformSnippetStringToInsertText, this) // no editor -> no snippet mode
|
||||
.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
|
||||
this.model.pushEditOperations(null, this._edits, () => null);
|
||||
}
|
||||
if (this._newEol !== undefined) {
|
||||
this.model.pushEOL(this._newEol);
|
||||
}
|
||||
}
|
||||
|
||||
protected _transformSnippetStringToInsertText(edit: ISingleSnippetEditOperation): ISingleSnippetEditOperation {
|
||||
// transform a snippet edit (and only those) into a normal text edit
|
||||
// for that we need to parse the snippet and get its actual text, e.g without placeholder
|
||||
// or variable syntaxes
|
||||
if (!edit.insertAsSnippet) {
|
||||
return edit;
|
||||
}
|
||||
if (!edit.text) {
|
||||
return edit;
|
||||
}
|
||||
const text = new SnippetParser().parse(edit.text, false, false).toString();
|
||||
return { ...edit, insertAsSnippet: false, text };
|
||||
}
|
||||
}
|
||||
|
||||
class EditorEditTask extends ModelEditTask {
|
||||
@@ -134,6 +150,7 @@ class EditorEditTask extends ModelEditTask {
|
||||
|
||||
} else {
|
||||
this._edits = this._edits
|
||||
.map(this._transformSnippetStringToInsertText, this) // mixed edits (snippet and normal) -> no snippet mode
|
||||
.sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
|
||||
this._editor.executeEdits('', this._edits);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user