Skip to content

Commit

Permalink
Fixes #173209 (#180505)
Browse files Browse the repository at this point in the history
* Fixes accept next word bug

* Fixes #173209
  • Loading branch information
hediet authored Apr 21, 2023
1 parent 8bf021c commit 4f3df05
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 30 deletions.
25 changes: 25 additions & 0 deletions src/vs/editor/contrib/inlineCompletions/browser/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ export class AcceptNextWordOfInlineCompletion extends EditorAction {
}
}

export class AcceptNextLineOfInlineCompletion extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.acceptNextLine',
label: nls.localize('action.inlineSuggest.acceptNextLine', "Accept Next Line Of Inline Suggestion"),
alias: 'Accept Next Line Of Inline Suggestion',
precondition: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible),
kbOpts: {
weight: KeybindingWeight.EditorContrib + 1,
},
menuOpts: [{
menuId: MenuId.InlineSuggestionToolbar,
title: nls.localize('acceptLine', 'Accept Line'),
group: 'secondary',
order: 2,
}],
});
}

public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor): Promise<void> {
const controller = InlineCompletionsController.get(editor);
controller?.model.get()?.acceptNextLine(controller.editor);
}
}

export class AcceptInlineCompletion extends EditorAction {
constructor() {
super({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { EditorContributionInstantiation, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { HoverParticipantRegistry } from 'vs/editor/contrib/hover/browser/hoverTypes';
import { TriggerInlineSuggestionAction, ShowNextInlineSuggestionAction, ShowPreviousInlineSuggestionAction, AcceptNextWordOfInlineCompletion, AcceptInlineCompletion, HideInlineCompletion, ToggleAlwaysShowInlineSuggestionToolbar } from 'vs/editor/contrib/inlineCompletions/browser/commands';
import { TriggerInlineSuggestionAction, ShowNextInlineSuggestionAction, ShowPreviousInlineSuggestionAction, AcceptNextWordOfInlineCompletion, AcceptInlineCompletion, HideInlineCompletion, ToggleAlwaysShowInlineSuggestionToolbar, AcceptNextLineOfInlineCompletion } from 'vs/editor/contrib/inlineCompletions/browser/commands';
import { InlineCompletionsHoverParticipant } from 'vs/editor/contrib/inlineCompletions/browser/hoverParticipant';
import { InlineCompletionsController } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController';
import { registerAction2 } from 'vs/platform/actions/common/actions';
Expand All @@ -16,6 +16,7 @@ registerEditorAction(TriggerInlineSuggestionAction);
registerEditorAction(ShowNextInlineSuggestionAction);
registerEditorAction(ShowPreviousInlineSuggestionAction);
registerEditorAction(AcceptNextWordOfInlineCompletion);
registerEditorAction(AcceptNextLineOfInlineCompletion);
registerEditorAction(AcceptInlineCompletion);
registerEditorAction(HideInlineCompletion);
registerAction2(ToggleAlwaysShowInlineSuggestionToolbar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class InlineCompletionsController extends Disposable {
this.updateObservables(tx,
e.isUndoing ? VersionIdChangeReason.Undo
: e.isRedoing ? VersionIdChangeReason.Redo
: this.model.get()?.isAcceptingPartialWord ? VersionIdChangeReason.AcceptWord
: this.model.get()?.isAcceptingPartially ? VersionIdChangeReason.AcceptWord
: VersionIdChangeReason.Other
)
)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export class InlineCompletionsModel extends Disposable {
private readonly _source = this._register(this._instantiationService.createInstance(InlineCompletionsSource, this.textModel, this.textModelVersionId, this._debounceValue));
private readonly _isActive = observableValue('isActive', false);

private _isAcceptingPartialWord = false;
public get isAcceptingPartialWord() { return this._isAcceptingPartialWord; }
private _isAcceptingPartially = false;
public get isAcceptingPartially() { return this._isAcceptingPartially; }

private _isNavigatingCurrentInlineCompletion = false;
public get isNavigatingCurrentInlineCompletion() { return this._isNavigatingCurrentInlineCompletion; }
Expand Down Expand Up @@ -301,6 +301,45 @@ export class InlineCompletionsModel extends Disposable {
}

public acceptNextWord(editor: ICodeEditor): void {
this.acceptNext(editor, (pos, text) => {
const langId = this.textModel.getLanguageIdAtPosition(pos.lineNumber, pos.column);
const config = this._languageConfigurationService.getLanguageConfiguration(langId);
const wordRegExp = new RegExp(config.wordDefinition.source, config.wordDefinition.flags.replace('g', ''));

const m1 = text.match(wordRegExp);
let acceptUntilIndexExclusive = 0;
if (m1 && m1.index !== undefined) {
if (m1.index === 0) {
acceptUntilIndexExclusive = m1[0].length;
} else {
acceptUntilIndexExclusive = m1.index;
}
} else {
acceptUntilIndexExclusive = text.length;
}

const wsRegExp = /\s+/g;
const m2 = wsRegExp.exec(text);
if (m2 && m2.index !== undefined) {
if (m2.index + m2[0].length < acceptUntilIndexExclusive) {
acceptUntilIndexExclusive = m2.index + m2[0].length;
}
}
return acceptUntilIndexExclusive;
});
}

public acceptNextLine(editor: ICodeEditor): void {
this.acceptNext(editor, (pos, text) => {
const m = text.match(/\n/);
if (m && m.index !== undefined) {
return m.index + 1;
}
return text.length;
});
}

private acceptNext(editor: ICodeEditor, getAcceptUntilIndex: (position: Position, text: string) => number): void {
if (editor.getModel() !== this.textModel) {
throw new BugIndicatingError();
}
Expand All @@ -324,29 +363,8 @@ export class InlineCompletionsModel extends Disposable {
const position = new Position(ghostText.lineNumber, firstPart.column);

const line = firstPart.lines.join('\n');
const langId = this.textModel.getLanguageIdAtPosition(ghostText.lineNumber, 1);
const config = this._languageConfigurationService.getLanguageConfiguration(langId);
const wordRegExp = new RegExp(config.wordDefinition.source, config.wordDefinition.flags.replace('g', ''));

const m1 = line.match(wordRegExp);
let acceptUntilIndexExclusive = 0;
if (m1 && m1.index !== undefined) {
if (m1.index === 0) {
acceptUntilIndexExclusive = m1[0].length;
} else {
acceptUntilIndexExclusive = m1.index;
}
} else {
acceptUntilIndexExclusive = line.length;
}

const wsRegExp = /\s+/g;
const m2 = wsRegExp.exec(line);
if (m2 && m2.index !== undefined) {
if (m2.index + m2[0].length < acceptUntilIndexExclusive) {
acceptUntilIndexExclusive = m2.index + m2[0].length;
}
}
const acceptUntilIndexExclusive = getAcceptUntilIndex(position, line);

if (acceptUntilIndexExclusive === line.length && ghostText.parts.length === 1) {
this.accept(editor);
Expand All @@ -355,7 +373,7 @@ export class InlineCompletionsModel extends Disposable {

const partialText = line.substring(0, acceptUntilIndexExclusive);

this._isAcceptingPartialWord = true;
this._isAcceptingPartially = true;
try {
editor.pushUndoStop();
editor.executeEdits('inlineSuggestion.accept', [
Expand All @@ -364,7 +382,7 @@ export class InlineCompletionsModel extends Disposable {
const length = lengthOfText(partialText);
editor.setPosition(addPositions(position, length));
} finally {
this._isAcceptingPartialWord = false;
this._isAcceptingPartially = false;
}

if (completion.source.provider.handlePartialAccept) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export class UpToDateInlineCompletions implements IDisposable {
description: 'inline-completion-tracking-range'
},
}])[0];
this._inlineCompletions.unshift(new InlineCompletionWithUpdatedRange(inlineCompletion, id, this.versionId, range));
this._inlineCompletions.unshift(new InlineCompletionWithUpdatedRange(inlineCompletion, id, this.rangeVersion, range));
this.prependedInlineCompletionItems.push(inlineCompletion);
}

Expand Down Expand Up @@ -327,10 +327,11 @@ export class InlineCompletionWithUpdatedRange {
}

public canBeReused(model: ITextModel, position: Position): boolean {
return this._isValid
const result = this._isValid
&& this.getUpdatedRange(undefined).containsPosition(position)
&& this.isVisible(model, position, undefined)
&& !this.isSmallerThanOriginal(undefined);
return result;
}

private isSmallerThanOriginal(reader: IReader | undefined): boolean {
Expand Down

0 comments on commit 4f3df05

Please sign in to comment.