Path: blob/main/src/vs/editor/contrib/suggest/browser/wordDistance.ts
4797 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { binarySearch, isFalsyOrEmpty } from '../../../../base/common/arrays.js';6import { ICodeEditor } from '../../../browser/editorBrowser.js';7import { EditorOption } from '../../../common/config/editorOptions.js';8import { IPosition } from '../../../common/core/position.js';9import { Range } from '../../../common/core/range.js';10import { CompletionItem, CompletionItemKind } from '../../../common/languages.js';11import { IEditorWorkerService } from '../../../common/services/editorWorker.js';12import { BracketSelectionRangeProvider } from '../../smartSelect/browser/bracketSelections.js';1314export abstract class WordDistance {1516static readonly None = new class extends WordDistance {17distance() { return 0; }18};1920static async create(service: IEditorWorkerService, editor: ICodeEditor): Promise<WordDistance> {2122if (!editor.getOption(EditorOption.suggest).localityBonus) {23return WordDistance.None;24}2526if (!editor.hasModel()) {27return WordDistance.None;28}2930const model = editor.getModel();31const position = editor.getPosition();3233if (!service.canComputeWordRanges(model.uri)) {34return WordDistance.None;35}3637const [ranges] = await new BracketSelectionRangeProvider().provideSelectionRanges(model, [position]);38if (ranges.length === 0) {39return WordDistance.None;40}4142const wordRanges = await service.computeWordRanges(model.uri, ranges[0].range);43if (!wordRanges) {44return WordDistance.None;45}4647// remove current word48const wordUntilPos = model.getWordUntilPosition(position);49delete wordRanges[wordUntilPos.word];5051return new class extends WordDistance {52distance(anchor: IPosition, item: CompletionItem) {53if (!position.equals(editor.getPosition())) {54return 0;55}56if (item.kind === CompletionItemKind.Keyword) {57return 2 << 20;58}59const word = typeof item.label === 'string' ? item.label : item.label.label;60const wordLines = wordRanges[word];61if (isFalsyOrEmpty(wordLines)) {62return 2 << 20;63}64const idx = binarySearch(wordLines, Range.fromPositions(anchor), Range.compareRangesUsingStarts);65const bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];66let blockDistance = ranges.length;67for (const range of ranges) {68if (!Range.containsRange(range.range, bestWordRange)) {69break;70}71blockDistance -= 1;72}73return blockDistance;74}75};76}7778abstract distance(anchor: IPosition, suggestion: CompletionItem): number;79}808182