This commit is contained in:
Henning Dieterichs 2021-09-28 16:51:06 +02:00
parent 1977fba7c6
commit 76a2090489
No known key found for this signature in database
GPG key ID: 771381EFFDB9EC06
3 changed files with 27 additions and 18 deletions

View file

@ -583,6 +583,11 @@ export async function provideInlineCompletions(
};
}
/**
* Shrinks the range if the text has a suffix/prefix that agrees with the text buffer.
* E.g. text buffer: `ab[cdef]ghi`, [...] is the replace range, `cxyzf` is the new text.
* Then the minimized inline completion has range `abc[de]fghi` and text `xyz`.
*/
export function minimizeInlineCompletion(model: ITextModel, inlineCompletion: NormalizedInlineCompletion): NormalizedInlineCompletion;
export function minimizeInlineCompletion(model: ITextModel, inlineCompletion: NormalizedInlineCompletion | undefined): NormalizedInlineCompletion | undefined;
export function minimizeInlineCompletion(model: ITextModel, inlineCompletion: NormalizedInlineCompletion | undefined): NormalizedInlineCompletion | undefined {

View file

@ -16,7 +16,7 @@ import { CompletionItem } from 'vs/editor/contrib/suggest/suggest';
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
import { minimizeInlineCompletion } from './inlineCompletionsModel';
import { NormalizedInlineCompletion, normalizedInlineCompletionsEquals } from './inlineCompletionToGhostText';
import { compareBy, compareByNumberAsc, findMinBy } from './utils';
import { compareBy, compareByNumber, findMaxBy } from './utils';
export interface SuggestWidgetState {
/**
@ -78,25 +78,29 @@ export class SuggestWidgetInlineCompletionProvider extends Disposable {
if (suggestController) {
this._register(suggestController.registerSelector({
priority: 100,
select: (model, pos, items) => {
select: (model, pos, suggestItems) => {
const textModel = this.editor.getModel();
const preselectedMinimized = minimizeInlineCompletion(textModel, this.suggestControllerPreselector());
if (!preselectedMinimized) {
const normalizedItemToPreselect = minimizeInlineCompletion(textModel, this.suggestControllerPreselector());
if (!normalizedItemToPreselect) {
return -1;
}
const position = Position.lift(pos);
const result = findMinBy(
items
.map((item, index) => {
const completion = suggestionToInlineCompletion(suggestController, position, item, this.isShiftKeyPressed);
// Minimization normalizes ranges.
const minimized = minimizeInlineCompletion(textModel, completion);
const valid = minimized.range.equalsRange(preselectedMinimized.range) && preselectedMinimized.text.startsWith(minimized.text);
return { index, valid, length: minimized.text.length };
})
.filter(item => item.valid),
compareBy(s => s.length, compareByNumberAsc()));
const candidates = suggestItems
.map((suggestItem, index) => {
const inlineSuggestItem = suggestionToInlineCompletion(suggestController, position, suggestItem, this.isShiftKeyPressed);
const normalizedSuggestItem = minimizeInlineCompletion(textModel, inlineSuggestItem);
const valid =
normalizedSuggestItem.range.equalsRange(normalizedItemToPreselect.range) &&
normalizedItemToPreselect.text.startsWith(normalizedSuggestItem.text);
return { index, valid, prefixLength: normalizedSuggestItem.text.length, suggestItem };
})
.filter(item => item.valid);
const result = findMaxBy(
candidates,
compareBy(s => s.prefixLength, compareByNumber())
);
return result ? result.index : - 1;
}
}));

View file

@ -18,14 +18,14 @@ export function compareBy<TItem, TCompareBy>(selector: (item: TItem) => TCompare
return (a, b) => comparator(selector(a), selector(b));
}
export function compareByNumberAsc<T>(): Comparator<number> {
export function compareByNumber(): Comparator<number> {
return (a, b) => a - b;
}
export function findMinBy<T>(items: T[], comparator: Comparator<T>): T | undefined {
export function findMaxBy<T>(items: T[], comparator: Comparator<T>): T | undefined {
let min: T | undefined = undefined;
for (const item of items) {
if (min === undefined || comparator(item, min) < 0) {
if (min === undefined || comparator(item, min) > 0) {
min = item;
}
}