optionally allow to specify selection at which to insert a snippet, #19116

This commit is contained in:
Johannes Rieken 2017-01-25 15:56:02 +01:00
parent bedb191acc
commit a2a077b088
6 changed files with 38 additions and 9 deletions

View file

@ -49,7 +49,7 @@ suite('editor tests', () => {
});
});
test('insert snippet with replacement', () => {
test('insert snippet with replacement, editor selection', () => {
const snippetString = new SnippetString()
.appendText('has been');
@ -67,6 +67,24 @@ suite('editor tests', () => {
});
});
test('insert snippet with replacement, selection as argument', () => {
const snippetString = new SnippetString()
.appendText('has been');
return withRandomFileEditor('This will be replaced', (editor, doc) => {
const selection = new Selection(
new Position(0, 5),
new Position(0, 12)
);
return editor.insertSnippet(snippetString, selection).then(inserted => {
assert.ok(inserted);
assert.equal(doc.getText(), 'This has been replaced');
assert.ok(doc.isDirty);
});
});
});
test('make edit', () => {
return withRandomFileEditor('', (editor, doc) => {
return editor.edit((builder) => {

3
src/vs/vscode.d.ts vendored
View file

@ -946,11 +946,12 @@ declare module 'vscode' {
* or accept the snippet.
*
* @param snippet The snippet to insert in this edit.
* @param selection One or many selections at which to insert the snippets. Defaults to the current editor selection.
* @param options The undo/redo behaviour around this edit. By default, undo stops will be created before and after this edit.
* @return A promise that resolves with a value indicating if the snippet could be inserted. Note that the promise does not signal
* that the snippet is completely filled-in or accepted.
*/
insertSnippet(snippet: SnippetString, options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
insertSnippet(snippet: SnippetString, selection?: Selection | Selection[], options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
/**
* Adds a set of decorations to the text editor. If a set of decorations already exists with

View file

@ -138,7 +138,7 @@ export abstract class MainThreadEditorsShape {
$tryRevealRange(id: string, range: editorCommon.IRange, revealType: TextEditorRevealType): TPromise<any> { throw ni(); }
$trySetSelections(id: string, selections: editorCommon.ISelection[]): TPromise<any> { throw ni(); }
$tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], opts: IApplyEditsOptions): TPromise<boolean> { throw ni(); }
$tryInsertSnippet(id: string, template: string, opts: IUndoStopOptions): TPromise<any> { throw ni(); }
$tryInsertSnippet(id: string, template: string, selections: editorCommon.ISelection[], opts: IUndoStopOptions): TPromise<any> { throw ni(); }
}
export abstract class MainThreadTreeExplorersShape {

View file

@ -620,8 +620,17 @@ class ExtHostTextEditor implements vscode.TextEditor {
});
}
insertSnippet(snippet: SnippetString, options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Thenable<boolean> {
return this._proxy.$tryInsertSnippet(this._id, snippet.value, options);
insertSnippet(snippet: SnippetString, where?: Selection | Selection[], options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Thenable<boolean> {
if (!where || (Array.isArray(where) && where.length === 0)) {
where = this._selections;
}
const selections = Array.isArray(where)
? where.map(TypeConverters.fromSelection)
: [TypeConverters.fromSelection(where)];
return this._proxy.$tryInsertSnippet(this._id, snippet.value, selections, options);
}
// ---- util

View file

@ -293,11 +293,11 @@ export class MainThreadEditors extends MainThreadEditorsShape {
return TPromise.as(this._textEditorsMap[id].applyEdits(modelVersionId, edits, opts));
}
$tryInsertSnippet(id: string, template: string, opts: IUndoStopOptions): TPromise<boolean> {
$tryInsertSnippet(id: string, template: string, selections: ISelection[], opts: IUndoStopOptions): TPromise<boolean> {
if (!this._textEditorsMap[id]) {
return TPromise.wrapError('TextEditor disposed');
}
return TPromise.as(this._textEditorsMap[id].insertSnippet(template, opts));
return TPromise.as(this._textEditorsMap[id].insertSnippet(template, selections, opts));
}
$registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void {

View file

@ -397,19 +397,20 @@ export class MainThreadTextEditor {
return false;
}
insertSnippet(template: string, opts: IUndoStopOptions) {
const snippetController = SnippetController.get(this._codeEditor);
insertSnippet(template: string, selections: EditorCommon.ISelection[], opts: IUndoStopOptions) {
if (!this._codeEditor) {
return false;
}
this._codeEditor.focus();
this._codeEditor.setSelections(selections);
if (opts.undoStopBefore) {
this._codeEditor.pushUndoStop();
}
const snippetController = SnippetController.get(this._codeEditor);
snippetController.insertSnippet(template, 0, 0);
if (opts.undoStopAfter) {