提交 c5cdf50e 编写于 作者: J Johannes Rieken

prep-work for #76847

上级 4259b43f
......@@ -20,6 +20,22 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
import { ILogService } from 'vs/platform/log/common/log';
import { SnippetSession } from './snippetSession';
export interface ISnippetInsertOptions {
overwriteBefore: number;
overwriteAfter: number;
adjustWhitespace: boolean;
undoStopBefore: boolean;
undoStopAfter: boolean;
}
const _defaultOptions: ISnippetInsertOptions = {
overwriteBefore: 0,
overwriteAfter: 0,
undoStopBefore: true,
undoStopAfter: true,
adjustWhitespace: true,
};
export class SnippetController2 implements IEditorContribution {
static get(editor: ICodeEditor): SnippetController2 {
......@@ -63,15 +79,13 @@ export class SnippetController2 implements IEditorContribution {
insert(
template: string,
overwriteBefore: number = 0, overwriteAfter: number = 0,
undoStopBefore: boolean = true, undoStopAfter: boolean = true,
adjustWhitespace: boolean = true,
opts?: Partial<ISnippetInsertOptions>
): void {
// this is here to find out more about the yet-not-understood
// error that sometimes happens when we fail to inserted a nested
// snippet
try {
this._doInsert(template, overwriteBefore, overwriteAfter, undoStopBefore, undoStopAfter, adjustWhitespace);
this._doInsert(template, typeof opts === 'undefined' ? _defaultOptions : { ..._defaultOptions, ...opts });
} catch (e) {
this.cancel();
......@@ -84,9 +98,7 @@ export class SnippetController2 implements IEditorContribution {
private _doInsert(
template: string,
overwriteBefore: number = 0, overwriteAfter: number = 0,
undoStopBefore: boolean = true, undoStopAfter: boolean = true,
adjustWhitespace: boolean = true,
opts: ISnippetInsertOptions
): void {
if (!this._editor.hasModel()) {
return;
......@@ -96,19 +108,19 @@ export class SnippetController2 implements IEditorContribution {
// as that is the inflight state causing cancelation
this._snippetListener.clear();
if (undoStopBefore) {
if (opts.undoStopBefore) {
this._editor.getModel().pushStackElement();
}
if (!this._session) {
this._modelVersionId = this._editor.getModel().getAlternativeVersionId();
this._session = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter, adjustWhitespace);
this._session = new SnippetSession(this._editor, template, opts);
this._session.insert();
} else {
this._session.merge(template, overwriteBefore, overwriteAfter, adjustWhitespace);
this._session.merge(template, opts);
}
if (undoStopAfter) {
if (opts.undoStopAfter) {
this._editor.getModel().pushStackElement();
}
......
......@@ -315,6 +315,18 @@ export class OneSnippet {
}
}
export interface ISnippetSessionInsertOptions {
overwriteBefore: number;
overwriteAfter: number;
adjustWhitespace: boolean;
}
const _defaultOptions: ISnippetSessionInsertOptions = {
overwriteBefore: 0,
overwriteAfter: 0,
adjustWhitespace: true
};
export class SnippetSession {
static adjustWhitespace(model: ITextModel, position: IPosition, snippet: TextmateSnippet): void {
......@@ -450,17 +462,13 @@ export class SnippetSession {
private readonly _editor: IActiveCodeEditor;
private readonly _template: string;
private readonly _templateMerges: [number, number, string][] = [];
private readonly _overwriteBefore: number;
private readonly _overwriteAfter: number;
private readonly _adjustWhitespace: boolean;
private readonly _options: ISnippetSessionInsertOptions;
private _snippets: OneSnippet[] = [];
constructor(editor: IActiveCodeEditor, template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true) {
constructor(editor: IActiveCodeEditor, template: string, options: ISnippetSessionInsertOptions = _defaultOptions) {
this._editor = editor;
this._template = template;
this._overwriteBefore = overwriteBefore;
this._overwriteAfter = overwriteAfter;
this._adjustWhitespace = adjustWhitespace;
this._options = options;
}
dispose(): void {
......@@ -479,7 +487,7 @@ export class SnippetSession {
const model = this._editor.getModel();
// make insert edit and start with first selections
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._overwriteBefore, this._overwriteAfter, false, this._adjustWhitespace);
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._options.overwriteBefore, this._options.overwriteAfter, false, this._options.adjustWhitespace);
this._snippets = snippets;
const selections = model.pushEditOperations(this._editor.getSelections(), edits, undoEdits => {
......@@ -493,12 +501,12 @@ export class SnippetSession {
this._editor.revealRange(selections[0]);
}
merge(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0, adjustWhitespace: boolean = true): void {
merge(template: string, options: ISnippetSessionInsertOptions = _defaultOptions): void {
if (!this._editor.hasModel()) {
return;
}
this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]);
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, overwriteBefore, overwriteAfter, true, adjustWhitespace);
const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, options.overwriteBefore, options.overwriteAfter, true, options.adjustWhitespace);
this._editor.setSelections(this._editor.getModel().pushEditOperations(this._editor.getSelections(), edits, undoEdits => {
......
......@@ -62,7 +62,7 @@ suite('SnippetController', () => {
snippetTest((editor, cursor, template, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(template, 0, 0);
snippetController.insert(template);
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {');
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];');
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
......@@ -98,7 +98,7 @@ suite('SnippetController', () => {
snippetTest((editor, cursor, template, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(template, 0, 0);
snippetController.insert(template);
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {');
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];');
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
......@@ -180,7 +180,7 @@ suite('SnippetController', () => {
test('Stops when calling model.setValue()', () => {
snippetTest((editor, cursor, codeSnippet, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
editor.getModel()!.setValue('goodbye');
......@@ -191,7 +191,7 @@ suite('SnippetController', () => {
test('Stops when undoing', () => {
snippetTest((editor, cursor, codeSnippet, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
editor.getModel()!.undo();
......@@ -202,7 +202,7 @@ suite('SnippetController', () => {
test('Stops when moving cursor outside', () => {
snippetTest((editor, cursor, codeSnippet, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
editor.setPosition({ lineNumber: 1, column: 1 });
......@@ -213,7 +213,7 @@ suite('SnippetController', () => {
test('Stops when disconnecting editor model', () => {
snippetTest((editor, cursor, codeSnippet, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
editor.setModel(null);
......@@ -224,7 +224,7 @@ suite('SnippetController', () => {
test('Stops when disposing editor', () => {
snippetTest((editor, cursor, codeSnippet, snippetController) => {
editor.setPosition({ lineNumber: 4, column: 2 });
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
snippetController.dispose();
......@@ -240,7 +240,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'foo$0';
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -255,7 +255,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'foo$0bar';
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -270,7 +270,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'foo$0bar';
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -285,7 +285,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'foo\n$0\nbar';
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -300,7 +300,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'foo\n$0\nbar';
snippetController.insert(codeSnippet, 0, 0);
snippetController.insert(codeSnippet);
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -314,7 +314,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'xo$0r';
snippetController.insert(codeSnippet, 1, 0);
snippetController.insert(codeSnippet, { overwriteBefore: 1 });
assert.equal(editor.getSelections()!.length, 1);
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 8, endColumn: 8, endLineNumber: 2 }));
......@@ -327,7 +327,7 @@ suite('SnippetController', () => {
editor.setSelection(new Selection(1, 19, 1, 19));
codeSnippet = '{{% url_**$1** %}}';
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getSelections()!.length, 1);
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 27, endLineNumber: 1, endColumn: 27 }));
......@@ -345,7 +345,7 @@ suite('SnippetController', () => {
'});'
].join('\n');
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getSelections()!.length, 1);
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 2, endLineNumber: 2, endColumn: 2 }), editor.getSelection()!.toString());
......@@ -363,7 +363,7 @@ suite('SnippetController', () => {
'});'
].join('\n');
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getSelections()!.length, 1);
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), editor.getSelection()!.toString());
......@@ -379,7 +379,7 @@ suite('SnippetController', () => {
'aft${1}er'
].join('\n');
controller.insert(codeSnippet, 8, 0);
controller.insert(codeSnippet, { overwriteBefore: 8 });
assert.equal(editor.getModel()!.getValue(), 'after');
assert.equal(editor.getSelections()!.length, 1);
......@@ -403,7 +403,7 @@ suite('SnippetController', () => {
'});'
].join('\n');
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getSelections()!.length, 2);
const [first, second] = editor.getSelections()!;
......@@ -428,7 +428,7 @@ suite('SnippetController', () => {
'});'
].join('\n');
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getSelections()!.length, 1);
const [first] = editor.getSelections()!;
......@@ -448,7 +448,7 @@ suite('SnippetController', () => {
codeSnippet = 'afterEach';
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 10, endLineNumber: 1, endColumn: 10 }));
......@@ -465,7 +465,7 @@ suite('SnippetController', () => {
]);
codeSnippet = '_foo';
controller.insert(codeSnippet, 1, 0);
controller.insert(codeSnippet, { overwriteBefore: 1 });
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo');
}, ['this._', 'abc']);
......@@ -478,7 +478,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'XX';
controller.insert(codeSnippet, 1, 0);
controller.insert(codeSnippet, { overwriteBefore: 1 });
assert.equal(editor.getModel()!.getValue(), 'this.XX\nabcXX');
}, ['this._', 'abc']);
......@@ -492,7 +492,7 @@ suite('SnippetController', () => {
]);
codeSnippet = '_foo';
controller.insert(codeSnippet, 1, 0);
controller.insert(codeSnippet, { overwriteBefore: 1 });
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo\ndef_foo');
}, ['this._', 'abc', 'def_']);
......@@ -506,7 +506,7 @@ suite('SnippetController', () => {
]);
codeSnippet = '._foo';
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo');
}, ['this._', 'abc', 'def._']);
......@@ -520,7 +520,7 @@ suite('SnippetController', () => {
]);
codeSnippet = '._foo';
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo');
}, ['this._', 'abc', 'def._']);
......@@ -534,7 +534,7 @@ suite('SnippetController', () => {
]);
codeSnippet = '._foo';
controller.insert(codeSnippet, 2, 0);
controller.insert(codeSnippet, { overwriteBefore: 2 });
assert.equal(editor.getModel()!.getValue(), 'this._._foo\na._foo\ndef._._foo');
}, ['this._', 'abc', 'def._']);
......@@ -550,7 +550,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'document';
controller.insert(codeSnippet, 3, 0);
controller.insert(codeSnippet, { overwriteBefore: 3 });
assert.equal(editor.getModel()!.getValue(), '{document}\n{document && true}');
}, ['{foo}', '{foo && true}']);
......@@ -565,7 +565,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'for (var ${1:i}=0; ${1:i}<len; ${1:i}++) { $0 }';
controller.insert(codeSnippet, 0, 0);
controller.insert(codeSnippet);
assert.equal(editor.getModel()!.getValue(), 'for (var i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
}, ['for (var i=0; i<len; i++) { }']);
......@@ -578,7 +578,7 @@ suite('SnippetController', () => {
]);
codeSnippet = 'for (let ${1:i}=0; ${1:i}<len; ${1:i}++) { $0 }';
controller.insert(codeSnippet, 0, 0);
controller.insert(codeSnippet);
assert.equal(editor.getModel()!.getValue(), 'for (let i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
}, ['for (var i=0; i<len; i++) { }']);
......
......@@ -126,7 +126,7 @@ suite('SnippetSession', function () {
test('snippets, newline NO whitespace adjust', () => {
editor.setSelection(new Selection(2, 5, 2, 5));
const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', 0, 0, false);
const session = new SnippetSession(editor, 'abc\n foo\n bar\n$0', { overwriteBefore: 0, overwriteAfter: 0, adjustWhitespace: false });
session.insert();
assert.equal(editor.getModel()!.getValue(), 'function foo() {\n abc\n foo\n bar\nconsole.log(a);\n}');
});
......@@ -648,7 +648,7 @@ suite('SnippetSession', function () {
assert.ok(actual.equalsSelection(new Selection(1, 9, 1, 12)));
editor.setSelections([new Selection(1, 9, 1, 12)]);
new SnippetSession(editor, 'far', 3, 0).insert();
new SnippetSession(editor, 'far', { overwriteBefore: 3, overwriteAfter: 0, adjustWhitespace: true }).insert();
assert.equal(model.getValue(), 'console.far');
});
});
......@@ -192,13 +192,13 @@ export class SuggestController implements IEditorContribution {
const overwriteBefore = position.column - suggestion.range.startColumn;
const overwriteAfter = suggestion.range.endColumn - position.column;
SnippetController2.get(this._editor).insert(
insertText,
overwriteBefore + columnDelta,
SnippetController2.get(this._editor).insert(insertText, {
overwriteBefore: overwriteBefore + columnDelta,
overwriteAfter,
false, false,
!(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace)
);
undoStopBefore: false,
undoStopAfter: false,
adjustWhitespace: !(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace)
});
if (undoStops) {
this._editor.pushUndoStop();
......
......@@ -484,7 +484,7 @@ export class MainThreadTextEditor {
this._codeEditor.focus();
// make modifications
snippetController.insert(template, 0, 0, opts.undoStopBefore, opts.undoStopAfter);
snippetController.insert(template, { overwriteBefore: 0, overwriteAfter: 0, undoStopBefore: opts.undoStopBefore, undoStopAfter: opts.undoStopAfter });
return true;
}
......
......@@ -157,7 +157,7 @@ export class KeybindingWidgetRenderer extends Disposable {
snippetText = smartInsertInfo.prepend + snippetText + smartInsertInfo.append;
this._editor.setPosition(smartInsertInfo.position);
SnippetController2.get(this._editor).insert(snippetText, 0, 0);
SnippetController2.get(this._editor).insert(snippetText, { overwriteBefore: 0, overwriteAfter: 0 });
}
}
}
......@@ -406,4 +406,4 @@ registerEditorCommand(new DefineKeybindingCommand());
registerThemingParticipant((theme, collector) => {
collector.addRule(`.monaco-editor .inlineKeybindingInfo:before { background: url("data:image/svg+xml,${SeverityIcon.getSVGData(Severity.Info, theme)}") -0.1em -0.2em no-repeat; }`);
collector.addRule(`.monaco-editor .inlineKeybindingError:before { background: url("data:image/svg+xml,${SeverityIcon.getSVGData(Severity.Error, theme)}") -0.1em -0.2em no-repeat; }`);
});
\ No newline at end of file
});
......@@ -167,7 +167,7 @@ class InsertSnippetAction extends EditorAction {
}
}).then(snippet => {
if (snippet) {
SnippetController2.get(editor).insert(snippet.codeSnippet, 0, 0);
SnippetController2.get(editor).insert(snippet.codeSnippet, { overwriteBefore: 0, overwriteAfter: 0 });
}
});
}
......
......@@ -129,7 +129,7 @@ export class TabCompletionController implements editorCommon.IEditorContribution
if (this._activeSnippets.length === 1) {
// one -> just insert
const [snippet] = this._activeSnippets;
SnippetController2.get(this._editor).insert(snippet.codeSnippet, snippet.prefix.length, 0);
SnippetController2.get(this._editor).insert(snippet.codeSnippet, { overwriteBefore: snippet.prefix.length, overwriteAfter: 0 });
} else if (this._activeSnippets.length > 1) {
// two or more -> show IntelliSense box
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册