Skip to content

Commit 13effd4

Browse files
committed
yield when computing bracket ranges
1 parent e1f986f commit 13effd4

2 files changed

Lines changed: 41 additions & 26 deletions

File tree

src/vs/editor/contrib/smartSelect/bracketSelections.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,32 @@ import { Range } from 'vs/editor/common/core/range';
1010

1111
export class BracketSelectionRangeProvider implements SelectionRangeProvider {
1212

13-
provideSelectionRanges(model: ITextModel, position: Position): Range[] {
14-
let result: Range[] = [];
15-
this._computeBracketRanges(model, position, result);
16-
return result;
13+
provideSelectionRanges(model: ITextModel, position: Position): Promise<Range[]> {
14+
const bucket: Range[] = [];
15+
const ranges = new Map<string, Range[]>();
16+
return new Promise(resolve => BracketSelectionRangeProvider._bracketsRightYield(resolve, model, position, ranges))
17+
.then(() => new Promise(resolve => BracketSelectionRangeProvider._bracketsLeftYield(resolve, model, position, ranges, bucket)))
18+
.then(() => bucket);
1719
}
1820

19-
private _computeBracketRanges(model: ITextModel, position: Position, bucket: Range[]): void {
21+
private static readonly _maxDuration = 90;
2022

21-
let ranges = new Map<string, Range[]>();
22-
23-
// right/down
24-
let counts = new Map<string, number>();
25-
let pos: Position | undefined = position;
23+
private static _bracketsRightYield(resolve: () => void, model: ITextModel, pos: Position, ranges: Map<string, Range[]>): void {
24+
const counts = new Map<string, number>();
25+
const t1 = Date.now();
2626
while (true) {
2727
if (!pos) {
28+
resolve();
2829
break;
2930
}
3031
let bracket = model.findNextBracket(pos);
3132
if (!bracket) {
33+
resolve();
34+
break;
35+
}
36+
let d = Date.now() - t1;
37+
if (d > BracketSelectionRangeProvider._maxDuration) {
38+
setTimeout(() => BracketSelectionRangeProvider._bracketsRightYield(resolve, model, pos, ranges));
3239
break;
3340
}
3441
const key = bracket.close;
@@ -52,16 +59,24 @@ export class BracketSelectionRangeProvider implements SelectionRangeProvider {
5259
}
5360
pos = bracket.range.getEndPosition();
5461
}
62+
}
5563

56-
// left/up
57-
counts.clear();
58-
pos = position;
64+
private static _bracketsLeftYield(resolve: () => void, model: ITextModel, pos: Position, ranges: Map<string, Range[]>, bucket: Range[]): void {
65+
const counts = new Map<string, number>();
66+
const t1 = Date.now();
5967
while (true) {
6068
if (!pos) {
69+
resolve();
6170
break;
6271
}
6372
let bracket = model.findPrevBracket(pos);
6473
if (!bracket) {
74+
resolve();
75+
break;
76+
}
77+
let d = Date.now() - t1;
78+
if (d > BracketSelectionRangeProvider._maxDuration) {
79+
setTimeout(() => BracketSelectionRangeProvider._bracketsLeftYield(resolve, model, pos, ranges, bucket));
6580
break;
6681
}
6782
const key = bracket.close;

src/vs/editor/contrib/smartSelect/test/tokenSelectionSupport.test.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,12 @@ suite('SmartSelect', () => {
188188

189189
// -- bracket selections
190190

191-
function assertRanges(value: string, ...expected: IRange[]): void {
191+
async function assertRanges(value: string, ...expected: IRange[]): Promise<void> {
192192

193193
let model = modelService.createModel(value, new StaticLanguageSelector(mode.getLanguageIdentifier()), URI.parse('fake:lang'));
194194
let pos = model.getPositionAt(value.indexOf('I'));
195195
let provider = new BracketSelectionRangeProvider();
196-
let ranges = provider.provideSelectionRanges(model, pos);
196+
let ranges = await provider.provideSelectionRanges(model, pos);
197197
modelService.destroyModel(model.uri);
198198

199199
assert.equal(expected.length, ranges.length);
@@ -203,35 +203,35 @@ suite('SmartSelect', () => {
203203
}
204204
}
205205

206-
test('bracket selection', () => {
207-
assertRanges('(I)',
206+
test('bracket selection', async () => {
207+
await assertRanges('(I)',
208208
new Range(1, 2, 1, 3), new Range(1, 1, 1, 4)
209209
);
210210

211-
assertRanges('[[[](I)]]',
211+
await assertRanges('[[[](I)]]',
212212
new Range(1, 6, 1, 7), new Range(1, 5, 1, 8), // ()
213213
new Range(1, 3, 1, 8), new Range(1, 2, 1, 9), // [[]()]
214214
new Range(1, 2, 1, 9), new Range(1, 1, 1, 10), // [[[]()]]
215215
);
216216

217-
assertRanges('[a[](I)a]',
217+
await assertRanges('[a[](I)a]',
218218
new Range(1, 6, 1, 7), new Range(1, 5, 1, 8),
219219
new Range(1, 2, 1, 9), new Range(1, 1, 1, 10),
220220
);
221221

222222
// no bracket
223-
assertRanges('fofofIfofo');
223+
await assertRanges('fofofIfofo');
224224

225225
// empty
226-
assertRanges('[[[]()]]I');
227-
assertRanges('I[[[]()]]');
226+
await assertRanges('[[[]()]]I');
227+
await assertRanges('I[[[]()]]');
228228

229229
// edge
230-
assertRanges('[I[[]()]]', new Range(1, 2, 1, 9), new Range(1, 1, 1, 10));
231-
assertRanges('[[[]()]I]', new Range(1, 2, 1, 9), new Range(1, 1, 1, 10));
230+
await assertRanges('[I[[]()]]', new Range(1, 2, 1, 9), new Range(1, 1, 1, 10));
231+
await assertRanges('[[[]()]I]', new Range(1, 2, 1, 9), new Range(1, 1, 1, 10));
232232

233-
assertRanges('aaa(aaa)bbb(bIb)ccc(ccc)', new Range(1, 13, 1, 16), new Range(1, 12, 1, 17));
234-
assertRanges('(aaa(aaa)bbb(bIb)ccc(ccc))', new Range(1, 14, 1, 17), new Range(1, 13, 1, 18), new Range(1, 2, 1, 26), new Range(1, 1, 1, 27));
233+
await assertRanges('aaa(aaa)bbb(bIb)ccc(ccc)', new Range(1, 13, 1, 16), new Range(1, 12, 1, 17));
234+
await assertRanges('(aaa(aaa)bbb(bIb)ccc(ccc))', new Range(1, 14, 1, 17), new Range(1, 13, 1, 18), new Range(1, 2, 1, 26), new Range(1, 1, 1, 27));
235235
});
236236

237237
});

0 commit comments

Comments
 (0)