Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/suggest/browser/wordDistance.ts
4797 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { binarySearch, isFalsyOrEmpty } from '../../../../base/common/arrays.js';
7
import { ICodeEditor } from '../../../browser/editorBrowser.js';
8
import { EditorOption } from '../../../common/config/editorOptions.js';
9
import { IPosition } from '../../../common/core/position.js';
10
import { Range } from '../../../common/core/range.js';
11
import { CompletionItem, CompletionItemKind } from '../../../common/languages.js';
12
import { IEditorWorkerService } from '../../../common/services/editorWorker.js';
13
import { BracketSelectionRangeProvider } from '../../smartSelect/browser/bracketSelections.js';
14
15
export abstract class WordDistance {
16
17
static readonly None = new class extends WordDistance {
18
distance() { return 0; }
19
};
20
21
static async create(service: IEditorWorkerService, editor: ICodeEditor): Promise<WordDistance> {
22
23
if (!editor.getOption(EditorOption.suggest).localityBonus) {
24
return WordDistance.None;
25
}
26
27
if (!editor.hasModel()) {
28
return WordDistance.None;
29
}
30
31
const model = editor.getModel();
32
const position = editor.getPosition();
33
34
if (!service.canComputeWordRanges(model.uri)) {
35
return WordDistance.None;
36
}
37
38
const [ranges] = await new BracketSelectionRangeProvider().provideSelectionRanges(model, [position]);
39
if (ranges.length === 0) {
40
return WordDistance.None;
41
}
42
43
const wordRanges = await service.computeWordRanges(model.uri, ranges[0].range);
44
if (!wordRanges) {
45
return WordDistance.None;
46
}
47
48
// remove current word
49
const wordUntilPos = model.getWordUntilPosition(position);
50
delete wordRanges[wordUntilPos.word];
51
52
return new class extends WordDistance {
53
distance(anchor: IPosition, item: CompletionItem) {
54
if (!position.equals(editor.getPosition())) {
55
return 0;
56
}
57
if (item.kind === CompletionItemKind.Keyword) {
58
return 2 << 20;
59
}
60
const word = typeof item.label === 'string' ? item.label : item.label.label;
61
const wordLines = wordRanges[word];
62
if (isFalsyOrEmpty(wordLines)) {
63
return 2 << 20;
64
}
65
const idx = binarySearch(wordLines, Range.fromPositions(anchor), Range.compareRangesUsingStarts);
66
const bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
67
let blockDistance = ranges.length;
68
for (const range of ranges) {
69
if (!Range.containsRange(range.range, bestWordRange)) {
70
break;
71
}
72
blockDistance -= 1;
73
}
74
return blockDistance;
75
}
76
};
77
}
78
79
abstract distance(anchor: IPosition, suggestion: CompletionItem): number;
80
}
81
82