提交 181cd201 编写于 作者: J Johannes Rieken

improve whitespace detection when searching for word at position, #29102

上级 1501dbe6
......@@ -57,10 +57,6 @@ export function ensureValidWordDefinition(wordDefinition?: RegExp): RegExp {
function getWordAtPosFast(column: number, wordDefinition: RegExp, text: string, textOffset: number): IWordAtPosition {
// find whitespace enclosed text around column and match from there
if (wordDefinition.test(' ')) {
return getWordAtPosSlow(column, wordDefinition, text, textOffset);
}
let pos = column - 1 - textOffset;
let start = text.lastIndexOf(' ', pos - 1) + 1;
let end = text.indexOf(' ', pos);
......@@ -113,10 +109,25 @@ function getWordAtPosSlow(column: number, wordDefinition: RegExp, text: string,
}
export function getWordAtText(column: number, wordDefinition: RegExp, text: string, textOffset: number): IWordAtPosition {
const result = getWordAtPosFast(column, wordDefinition, text, textOffset);
// if `words` can contain whitespace character we have to use the slow variant
// otherwise we use the fast variant of finding a word
wordDefinition.lastIndex = 0;
let match = wordDefinition.exec(text);
if (!match) {
return null;
}
// todo@joh the `match` could already be the (first) word
const ret = match[0].indexOf(' ') >= 0
// did match a word which contains a space character -> use slow word find
? getWordAtPosSlow(column, wordDefinition, text, textOffset)
// sane word definition -> use fast word find
: getWordAtPosFast(column, wordDefinition, text, textOffset);
// both (getWordAtPosFast and getWordAtPosSlow) leave the wordDefinition-RegExp
// in an undefined state and to not confuse other users of the wordDefinition
// we reset the lastIndex
wordDefinition.lastIndex = 0;
return result;
return ret;
}
......@@ -269,6 +269,34 @@ suite('ExtHostDocumentData', () => {
range = data.document.getWordRangeAtPosition(new Position(0, 11), /yy/);
assert.equal(range, undefined);
});
test('getWordRangeAtPosition doesn\'t quite use the regex as expected, #29102', function () {
data = new ExtHostDocumentData(undefined, URI.file(''), [
'some text here',
'/** foo bar */',
'function() {',
' "far boo"',
'}'
], '\n', 'text', 1, false);
let range = data.document.getWordRangeAtPosition(new Position(0, 0), /\/\*.+\*\//);
assert.equal(range, undefined);
range = data.document.getWordRangeAtPosition(new Position(1, 0), /\/\*.+\*\//);
assert.equal(range.start.line, 1);
assert.equal(range.start.character, 0);
assert.equal(range.end.line, 1);
assert.equal(range.end.character, 14);
range = data.document.getWordRangeAtPosition(new Position(3, 0), /("|').*\1/);
assert.equal(range, undefined);
range = data.document.getWordRangeAtPosition(new Position(3, 1), /("|').*\1/);
assert.equal(range.start.line, 3);
assert.equal(range.start.character, 1);
assert.equal(range.end.line, 3);
assert.equal(range.end.character, 10);
});
});
enum AssertDocumentLineMappingDirection {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册