Skip to content

Commit 2540cbb

Browse files
committed
faster version of getWordAtPostFast, microsoft#2312
1 parent 9dfcad5 commit 2540cbb

1 file changed

Lines changed: 20 additions & 57 deletions

File tree

src/vs/editor/common/model/wordHelper.ts

Lines changed: 20 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -54,73 +54,36 @@ export function ensureValidWordDefinition(wordDefinition?: RegExp): RegExp {
5454
return result;
5555
}
5656

57-
function reverse(str: string): string {
58-
let reversedStr = '';
59-
for (let i = str.length - 1; i >= 0; i--) {
60-
reversedStr += str.charAt(i);
61-
}
62-
return reversedStr;
63-
}
64-
6557
function getWordAtPosFast(column: number, wordDefinition: RegExp, text: string, textOffset: number): IWordAtPosition {
66-
// matches at the desired column, once to right
67-
// and once to the left. The latter is achived
68-
// by reversing the string. Falls back to getWordAtPosSlow
69-
// when a word is longer than 100 characters. Will
70-
// not work with regular expressions that check the
71-
// shape of a word, like /aabb/
72-
73-
let pos = column - 1 - textOffset;
74-
wordDefinition.lastIndex = pos;
75-
let rightMatch = wordDefinition.exec(text);
76-
if (rightMatch && rightMatch.index > pos) {
77-
// |nW
78-
rightMatch = null;
79-
}
80-
81-
let leftTextReverse = reverse(text.substring(pos - 100, pos));
82-
wordDefinition.lastIndex = 0;
83-
let leftMatch = wordDefinition.exec(leftTextReverse);
84-
if (leftMatch) {
85-
86-
if (leftMatch.index > 0) {
87-
// |nW
88-
leftMatch = null;
89-
90-
} else if (wordDefinition.lastIndex === 100) {
91-
// |W*100 -> very long word
92-
return getWordAtPosSlow(column, wordDefinition, text, textOffset);
93-
}
94-
}
58+
// find whitespace enclosed text around column and match from there
9559

96-
if (!rightMatch && !leftMatch) {
97-
// nothing matched
98-
return null;
60+
if (wordDefinition.test(' ')) {
61+
return getWordAtPosSlow(column, wordDefinition, text, textOffset);
9962
}
10063

101-
let word = '';
102-
let start = pos;
103-
let end = pos;
104-
105-
if (leftMatch) {
106-
let leftWord = reverse(leftMatch[0]);
107-
start -= leftWord.length;
108-
word = leftWord;
64+
let pos = column - 1 - textOffset;
65+
let start = text.lastIndexOf(' ', pos - 1) + 1;
66+
let end = text.indexOf(' ', pos);
67+
if (end === -1) {
68+
end = text.length;
10969
}
11070

111-
if (rightMatch) {
112-
let rightWord = rightMatch[0];
113-
end += rightWord.length;
114-
word += rightWord;
71+
wordDefinition.lastIndex = start;
72+
let match: RegExpMatchArray;
73+
while (match = wordDefinition.exec(text)) {
74+
if (match.index <= pos && wordDefinition.lastIndex >= pos) {
75+
return {
76+
word: match[0],
77+
startColumn: textOffset + 1 + match.index,
78+
endColumn: textOffset + 1 + wordDefinition.lastIndex
79+
};
80+
}
11581
}
11682

117-
return {
118-
word,
119-
startColumn: textOffset + 1 + start,
120-
endColumn: textOffset + 1 + end
121-
};
83+
return null;
12284
}
12385

86+
12487
function getWordAtPosSlow(column: number, wordDefinition: RegExp, text: string, textOffset: number): IWordAtPosition {
12588
// matches all words starting at the beginning
12689
// of the input until it finds a match that encloses

0 commit comments

Comments
 (0)