diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 5f60c994fad..ae7b4852481 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -209,14 +209,16 @@ declare module 'vscode' { /** * Get a word-range at the given position. By default words are defined by * common separators, like space, -, _, etc. In addition, per languge custom - * [word definitions](#LanguageConfiguration.wordPattern) can be defined. + * [word definitions](#LanguageConfiguration.wordPattern) can be defined. It + * is also possible to provide a custom regular expression. * * The position will be [adjusted](#TextDocument.validatePosition). * * @param position A position. + * @param regex Optional regular expression that describes what a word is. * @return A range spanning a word, or `undefined`. */ - getWordRangeAtPosition(position: Position): Range; + getWordRangeAtPosition(position: Position, regex?: RegExp): Range; /** * Ensure a range is completely contained in this document. diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index 8f7b18db3ff..7b9eaf556da 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -5,6 +5,7 @@ 'use strict'; import { onUnexpectedError } from 'vs/base/common/errors'; +import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { MirrorModel2 } from 'vs/editor/common/model/mirrorModel2'; import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; @@ -262,7 +263,7 @@ export class ExtHostDocumentData extends MirrorModel2 { positionAt(offset) { return data.positionAt(offset); }, validateRange(ran) { return data.validateRange(ran); }, validatePosition(pos) { return data.validatePosition(pos); }, - getWordRangeAtPosition(pos) { return data.getWordRangeAtPosition(pos); } + getWordRangeAtPosition(pos, regexp?) { return data.getWordRangeAtPosition(pos, regexp); } }; } return this._document; @@ -410,12 +411,14 @@ export class ExtHostDocumentData extends MirrorModel2 { return new Position(line, character); } - getWordRangeAtPosition(_position: vscode.Position): vscode.Range { + getWordRangeAtPosition(_position: vscode.Position, regexp?: RegExp): vscode.Range { let position = this.validatePosition(_position); - + if (!regexp || regExpLeadsToEndlessLoop(regexp)) { + regexp = getWordDefinitionFor(this._languageId); + } let wordAtText = getWordAtText( position.character + 1, - ensureValidWordDefinition(getWordDefinitionFor(this._languageId)), + ensureValidWordDefinition(regexp), this._lines[position.line], 0 ); diff --git a/src/vs/workbench/test/node/api/extHostDocuments.test.ts b/src/vs/workbench/test/node/api/extHostDocuments.test.ts index 93c11669a18..b20a73865ef 100644 --- a/src/vs/workbench/test/node/api/extHostDocuments.test.ts +++ b/src/vs/workbench/test/node/api/extHostDocuments.test.ts @@ -204,6 +204,39 @@ suite('ExtHostDocument', () => { assertPositionAt(99, 3, 29); assertPositionAt(Number.MAX_VALUE, 3, 29); }); + + test('getWordRangeAtPosition', function () { + data = new ExtHostDocumentData(undefined, URI.file(''), [ + 'aaaa bbbb cccc abc' + ], '\n', 'text', 1, false); + + let range = data.getWordRangeAtPosition(new Position(0, 2)); + assert.equal(range.start.line, 0); + assert.equal(range.start.character, 0); + assert.equal(range.end.line, 0); + assert.equal(range.end.character, 4); + + range = data.getWordRangeAtPosition(new Position(0, 2), /.*/); + assert.equal(range.start.line, 0); + assert.equal(range.start.character, 0); + assert.equal(range.end.line, 0); + assert.equal(range.end.character, 4); + + range = data.getWordRangeAtPosition(new Position(0, 2), /a+.+?c/); + assert.equal(range.start.line, 0); + assert.equal(range.start.character, 0); + assert.equal(range.end.line, 0); + assert.equal(range.end.character, 11); + + range = data.getWordRangeAtPosition(new Position(0, 17), /a+.+?c/); + assert.equal(range.start.line, 0); + assert.equal(range.start.character, 15); + assert.equal(range.end.line, 0); + assert.equal(range.end.character, 18); + + range = data.getWordRangeAtPosition(new Position(0, 11), /yy/); + assert.equal(range, undefined); + }); }); enum AssertDocumentLineMappingDirection { @@ -372,4 +405,4 @@ suite('ExtHostDocument updates line mapping', () => { 'and finished with the fourth.', ], [createChangeEvent(new CodeEditorRange(1, 1, 1, 1), '', '\n')]); }); -}); \ No newline at end of file +});