wire up snippets, #4956

This commit is contained in:
Johannes Rieken 2016-11-21 16:18:06 +01:00
parent 646533e008
commit c68054a9b1
7 changed files with 29 additions and 30 deletions

View file

@ -15,7 +15,8 @@ import { Selection } from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { CommonEditorRegistry, commonEditorContribution, EditorCommand } from 'vs/editor/common/editorCommonExtensions';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ICodeSnippet, CodeSnippet } from './snippet';
import { ISnippetVariableResolver, ICodeSnippet, CodeSnippet } from './snippet';
import { SnippetVariablesResolver } from './snippetVariables';
import EditorContextKeys = editorCommon.EditorContextKeys;
@ -380,11 +381,13 @@ export class SnippetController {
}
private _editor: editorCommon.ICommonCodeEditor;
private _variableResolver: ISnippetVariableResolver;
protected _currentController: InsertSnippetController;
private _inSnippetMode: IContextKey<boolean>;
constructor(editor: editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
this._editor = editor;
this._variableResolver = new SnippetVariablesResolver(editor);
this._currentController = null;
this._inSnippetMode = CONTEXT_SNIPPET_MODE.bindTo(contextKeyService);
}
@ -400,6 +403,11 @@ export class SnippetController {
return SnippetController.ID;
}
public insertSnippet(template: string, overwriteBefore: number, overwriteAfter: number): void {
const snippet = CodeSnippet.fromTextmate(template, this._variableResolver);
this.run(snippet, overwriteBefore, overwriteAfter);
}
public run(snippet: CodeSnippet, overwriteBefore: number, overwriteAfter: number, stripPrefix?: boolean): void {
this._runAndRestoreController(() => {
if (snippet.isInsertOnly || snippet.isSingleTabstopOnly) {

View file

@ -216,6 +216,9 @@ export class SnippetParser {
compact(thisMarker.defaultValue, placeholders);
}
} else if (thisMarker instanceof Variable) {
compact(thisMarker.defaultValue, placeholders);
} else if (i > 0 && thisMarker instanceof Text && marker[i - 1] instanceof Text) {
(<Text>marker[i - 1]).string += (<Text>marker[i]).string;
marker.splice(i, 1);

View file

@ -20,7 +20,7 @@ export class SnippetVariablesResolver implements ISnippetVariableResolver {
resolve(name: string): string {
const model = this._editor.getModel();
if (!model) {
return;
throw new Error();
}
switch (name) {
case 'SELECTION':

View file

@ -38,7 +38,7 @@ suite('Snippet Variables Resolver', function () {
assert.equal(resolver.resolve('something'), undefined);
editor.setModel(null);
assert.equal(resolver.resolve('TM_FILENAME'), undefined);
assert.throws(() => resolver.resolve('TM_FILENAME'));
});
});

View file

@ -19,7 +19,7 @@ import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { CodeSnippet } from 'vs/editor/contrib/snippet/common/snippet';
import { SnippetController } from 'vs/editor/contrib/snippet/common/snippetController';
import { Context as SuggestContext, snippetSuggestSupport } from 'vs/editor/contrib/suggest/common/suggest';
import { Context as SuggestContext } from 'vs/editor/contrib/suggest/common/suggest';
import { SuggestModel } from '../common/suggestModel';
import { ICompletionItem } from '../common/completionModel';
import { SuggestWidget } from './suggestWidget';
@ -76,14 +76,6 @@ export class SuggestController implements IEditorContribution {
}
}
private static _codeSnippetForSuggestion({suggestion}: ICompletionItem): CodeSnippet {
switch (suggestion.snippetType) {
case 'textmate': return CodeSnippet.fromTextmate(suggestion.insertText);
case 'internal': return CodeSnippet.fromInternal(suggestion.insertText);
default: return CodeSnippet.none(suggestion.insertText);
}
}
private onDidSelectItem(item: ICompletionItem): void {
if (item) {
const {suggestion, position} = item;
@ -95,23 +87,22 @@ export class SuggestController implements IEditorContribution {
this.editor.pushUndoStop();
}
const snippet = SuggestController._codeSnippetForSuggestion(item);
SnippetController.get(this.editor).run(
snippet,
suggestion.overwriteBefore + columnDelta,
suggestion.overwriteAfter
);
if (suggestion.snippetType === 'textmate') {
SnippetController.get(this.editor).insertSnippet(
suggestion.insertText,
suggestion.overwriteBefore + columnDelta,
suggestion.overwriteAfter);
} else {
SnippetController.get(this.editor).run(
CodeSnippet.fromInternal(suggestion.insertText),
suggestion.overwriteBefore + columnDelta,
suggestion.overwriteAfter
);
}
if (suggestion.command) {
this.commandService.executeCommand(suggestion.command.id, ...suggestion.command.arguments).done(undefined, onUnexpectedError);
}
if (item.support !== snippetSuggestSupport) {
this.telemetryService.publicLog('suggestSnippetInsert', {
hasPlaceholders: snippet.placeHolders.length > 0
});
}
}
this.model.cancel();

View file

@ -14,7 +14,6 @@ import { endsWith } from 'vs/base/common/strings';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { CommonEditorRegistry, commonEditorContribution, EditorCommand } from 'vs/editor/common/editorCommonExtensions';
import { CodeSnippet } from 'vs/editor/contrib/snippet/common/snippet';
import { SnippetController, CONTEXT_SNIPPET_MODE } from 'vs/editor/contrib/snippet/common/snippetController';
import EditorContextKeys = editorCommon.EditorContextKeys;
@ -77,8 +76,7 @@ export class TabCompletionController implements editorCommon.IEditorContribution
performSnippetCompletions(): void {
if (this._currentSnippets.length === 1) {
const snippet = this._currentSnippets[0];
const codeSnippet = CodeSnippet.fromTextmate(snippet.codeSnippet);
this._snippetController.run(codeSnippet, snippet.prefix.length, 0);
this._snippetController.insertSnippet(snippet.codeSnippet, snippet.prefix.length, 0);
// } else {
// todo@joh - show suggest widget with proposals
}

View file

@ -9,7 +9,6 @@ import { Registry } from 'vs/platform/platform';
import { TPromise } from 'vs/base/common/winjs.base';
import { ICommonCodeEditor, EditorContextKeys } from 'vs/editor/common/editorCommon';
import { editorAction, ServicesAccessor, EditorAction } from 'vs/editor/common/editorCommonExtensions';
import { CodeSnippet } from 'vs/editor/contrib/snippet/common/snippet';
import { SnippetController } from 'vs/editor/contrib/snippet/common/snippetController';
import { IQuickOpenService, IPickOpenEntry } from 'vs/workbench/services/quickopen/common/quickOpenService';
import { ISnippetsRegistry, Extensions, ISnippet } from 'vs/editor/common/modes/snippetsRegistry';
@ -49,7 +48,7 @@ class ShowSnippetsActions extends EditorAction {
return quickOpenService.pick(picks).then(pick => {
if (pick) {
SnippetController.get(editor).run(CodeSnippet.fromTextmate(pick.snippet.codeSnippet), 0, 0);
SnippetController.get(editor).insertSnippet(pick.snippet.codeSnippet, 0, 0);
}
});
}