diff --git a/src/vs/editor/contrib/snippet/common/snippetVariables.ts b/src/vs/editor/contrib/snippet/common/snippetVariables.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b965e9475a9fdd313506bbc0319aff99c11a304 --- /dev/null +++ b/src/vs/editor/contrib/snippet/common/snippetVariables.ts @@ -0,0 +1,72 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { basename, dirname } from 'vs/base/common/paths'; +import * as editorCommon from 'vs/editor/common/editorCommon'; +import { ISnippetVariableResolver } from './snippet'; + +export class SnippetVariablesResolver implements ISnippetVariableResolver { + + private _editor: editorCommon.ICommonCodeEditor; + + constructor(editor: editorCommon.ICommonCodeEditor) { + this._editor = editor; + } + + resolve(name: string): string { + const model = this._editor.getModel(); + if (!model) { + return; + } + switch (name) { + case 'SELECTION': + case 'TM_SELECTED_TEXT': return this._tmSelectedText(); + case 'TM_CURRENT_LINE': return this._tmCurrentLine(); + case 'TM_CURRENT_WORD': return this._tmCurrentWord(); + case 'TM_LINE_INDEX': return this._tmLineIndex(); + case 'TM_LINE_NUMBER': return this._tmLineNumber(); + case 'TM_FILENAME': return this._tmFilename(); + case 'TM_DIRECTORY': return this._tmDirectory(); + case 'TM_FILEPATH': return this._tmFilepath(); + } + return; + } + + private _tmCurrentLine(): string { + const {positionLineNumber} = this._editor.getSelection(); + return this._editor.getModel().getValueInRange({ startLineNumber: positionLineNumber, startColumn: 1, endLineNumber: positionLineNumber, endColumn: Number.MAX_VALUE }); + } + + private _tmCurrentWord(): string { + const word = this._editor.getModel().getWordAtPosition(this._editor.getPosition()); + return word && word.word; + } + + private _tmFilename(): string { + return basename(this._editor.getModel().uri.fsPath); + } + + private _tmDirectory(): string { + return dirname(this._editor.getModel().uri.fsPath); + } + + private _tmFilepath(): string { + return this._editor.getModel().uri.fsPath; + } + + private _tmLineIndex(): string { + return String(this._editor.getSelection().positionLineNumber - 1); + } + + private _tmLineNumber(): string { + return String(this._editor.getSelection().positionLineNumber); + } + + private _tmSelectedText(): string { + return this._editor.getModel().getValueInRange(this._editor.getSelection()); + } +} diff --git a/src/vs/editor/contrib/snippet/test/common/snippetVariables.test.ts b/src/vs/editor/contrib/snippet/test/common/snippetVariables.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..dafa1399963ae06a8612b091fe37efab315dd999 --- /dev/null +++ b/src/vs/editor/contrib/snippet/test/common/snippetVariables.test.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as assert from 'assert'; +import URI from 'vs/base/common/uri'; +import { Selection } from 'vs/editor/common/core/selection'; +import { SnippetVariablesResolver } from 'vs/editor/contrib/snippet/common/snippetVariables'; +import { MockCodeEditor, withMockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor'; +import { Model } from 'vs/editor/common/model/model'; + +suite('Snippet Variables Resolver', function () { + + const model = Model.createFromString('', undefined, undefined, URI.parse('file:///foo/files/text.txt')); + + function variablesTest(callback: (editor: MockCodeEditor, resolver: SnippetVariablesResolver) => any) { + + + const lines: string[] = [ + 'this is line one', + 'this is line two' + ]; + + model.setValue(lines.join('\n')); + + withMockCodeEditor(lines, { model }, editor => { + callback(editor, new SnippetVariablesResolver(editor)); + }); + } + + test('editor variables, basics', function () { + + variablesTest((editor, resolver) => { + assert.equal(resolver.resolve('TM_FILENAME'), 'text.txt'); + assert.equal(resolver.resolve('something'), undefined); + + editor.setModel(null); + assert.equal(resolver.resolve('TM_FILENAME'), undefined); + }); + }); + + test('editor variables, file/dir', function () { + + variablesTest((editor, resolver) => { + assert.equal(resolver.resolve('TM_FILENAME'), 'text.txt'); + assert.equal(resolver.resolve('TM_DIRECTORY'), '/foo/files'); + assert.equal(resolver.resolve('TM_FILEPATH'), '/foo/files/text.txt'); + + editor.setModel(Model.createFromString('', undefined, undefined, URI.parse('http://www.pb.o/abc/def/ghi'))); + assert.equal(resolver.resolve('TM_FILENAME'), 'ghi'); + assert.equal(resolver.resolve('TM_DIRECTORY'), '/abc/def'); + assert.equal(resolver.resolve('TM_FILEPATH'), '/abc/def/ghi'); + }); + }); + + test('editor variables, selection', function () { + + variablesTest((editor, resolver) => { + + editor.setSelection(new Selection(1, 2, 2, 3)); + assert.equal(resolver.resolve('TM_SELECTED_TEXT'), 'his is line one\nth'); + assert.equal(resolver.resolve('TM_CURRENT_LINE'), 'this is line two'); + assert.equal(resolver.resolve('TM_LINE_INDEX'), '1'); + assert.equal(resolver.resolve('TM_LINE_NUMBER'), '2'); + + editor.setSelection(new Selection(2, 3, 1, 2)); + assert.equal(resolver.resolve('TM_SELECTED_TEXT'), 'his is line one\nth'); + assert.equal(resolver.resolve('TM_CURRENT_LINE'), 'this is line one'); + assert.equal(resolver.resolve('TM_LINE_INDEX'), '0'); + assert.equal(resolver.resolve('TM_LINE_NUMBER'), '1'); + + editor.setSelection(new Selection(1, 2, 1, 2)); + assert.equal(resolver.resolve('TM_SELECTED_TEXT'), ''); + + assert.equal(resolver.resolve('TM_CURRENT_WORD'), 'this'); + }); + }); + +});