mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-19 18:14:50 +01:00
improve whitespace detection when searching for word at position, #29102
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user