提交 3a626d89 编写于 作者: J Johannes Rieken

shift+tab/shift+enter overwrite suffix when accepting a completion, #10266

上级 13dc6f18
......@@ -22,7 +22,7 @@ import * as nls from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { Context as SuggestContext, CompletionItem } from './suggest';
import { SuggestAlternatives } from './suggestAlternatives';
import { State, SuggestModel } from './suggestModel';
......@@ -34,7 +34,7 @@ import { IdleValue } from 'vs/base/common/async';
import { isObject } from 'vs/base/common/types';
import { CommitCharacterController } from './suggestCommitCharacters';
import { IPosition } from 'vs/editor/common/core/position';
import { TrackedRangeStickiness, ITextModel } from 'vs/editor/common/model';
import { TrackedRangeStickiness, ITextModel, IWordAtPosition } from 'vs/editor/common/model';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import * as platform from 'vs/base/common/platform';
......@@ -115,10 +115,10 @@ export class SuggestController implements IEditorContribution {
const widget = this._instantiationService.createInstance(SuggestWidget, this._editor);
this._toDispose.add(widget);
this._toDispose.add(widget.onDidSelect(item => this._insertSuggestion(item, false, true, true), this));
this._toDispose.add(widget.onDidSelect(item => this._insertSuggestion(item, false, true, true, false), this));
// Wire up logic to accept a suggestion on certain characters
const commitCharacterController = new CommitCharacterController(this._editor, widget, item => this._insertSuggestion(item, false, true, false));
const commitCharacterController = new CommitCharacterController(this._editor, widget, item => this._insertSuggestion(item, false, true, false, false));
this._toDispose.add(commitCharacterController);
this._toDispose.add(this._model.onDidSuggest(e => {
if (e.completionModel.items.length === 0) {
......@@ -223,7 +223,12 @@ export class SuggestController implements IEditorContribution {
this._lineSuffix.dispose();
}
protected _insertSuggestion(event: ISelectedSuggestion | undefined, keepAlternativeSuggestions: boolean, undoStopBefore: boolean, undoStopAfter: boolean): void {
protected _insertSuggestion(
event: ISelectedSuggestion | undefined,
keepAlternativeSuggestions: boolean,
undoStopBefore: boolean, undoStopAfter: boolean,
overwriteSuffix: boolean
): void {
if (!event || !event.item) {
this._alternatives.getValue().reset();
this._model.cancel();
......@@ -237,8 +242,8 @@ export class SuggestController implements IEditorContribution {
const model = this._editor.getModel();
const modelVersionNow = model.getAlternativeVersionId();
const { completion: suggestion, position } = event.item;
const editorColumn = this._editor.getPosition().column;
const columnDelta = editorColumn - position.column;
const editorPosition = this._editor.getPosition();
const columnDelta = editorPosition.column - position.column;
// pushing undo stops *before* additional text edits and
// *after* the main edit
......@@ -251,7 +256,7 @@ export class SuggestController implements IEditorContribution {
}
// keep item in memory
this._memoryService.memorize(model, this._editor.getPosition(), event.item);
this._memoryService.memorize(model, editorPosition, event.item);
let { insertText } = suggestion;
if (!(suggestion.insertTextRules! & CompletionItemInsertTextRule.InsertAsSnippet)) {
......@@ -260,7 +265,12 @@ export class SuggestController implements IEditorContribution {
const overwriteBefore = position.column - suggestion.range.startColumn;
const overwriteAfter = suggestion.range.endColumn - position.column;
const suffixDelta = this._lineSuffix.value ? this._lineSuffix.value.delta(this._editor.getPosition()) : 0;
let suffixDelta = this._lineSuffix.value ? this._lineSuffix.value.delta(position) : 0;
let word: IWordAtPosition | null;
if (overwriteAfter === 0 && overwriteSuffix && (word = model.getWordAtPosition(position))) {
suffixDelta += word.endColumn - position.column;
}
SnippetController2.get(this._editor).insert(insertText, {
overwriteBefore: overwriteBefore + columnDelta,
......@@ -300,7 +310,7 @@ export class SuggestController implements IEditorContribution {
if (modelVersionNow !== model.getAlternativeVersionId()) {
model.undo();
}
this._insertSuggestion(next, false, false, false);
this._insertSuggestion(next, false, false, false, overwriteSuffix);
break;
}
});
......@@ -382,7 +392,7 @@ export class SuggestController implements IEditorContribution {
return;
}
this._editor.pushUndoStop();
this._insertSuggestion({ index, item, model: completionModel }, true, false, false);
this._insertSuggestion({ index, item, model: completionModel }, true, false, false, false);
}, undefined, listener);
});
......@@ -392,9 +402,9 @@ export class SuggestController implements IEditorContribution {
this._editor.focus();
}
acceptSelectedSuggestion(keepAlternativeSuggestions?: boolean): void {
acceptSelectedSuggestion(keepAlternativeSuggestions: boolean, overwriteSuffix: boolean): void {
const item = this._widget.getValue().getFocusedItem();
this._insertSuggestion(item, !!keepAlternativeSuggestions, true, true);
this._insertSuggestion(item, keepAlternativeSuggestions, true, true, overwriteSuffix);
}
acceptNextSuggestion() {
......@@ -489,18 +499,37 @@ const SuggestCommand = EditorCommand.bindToContribution<SuggestController>(Sugge
registerEditorCommand(new SuggestCommand({
id: 'acceptSelectedSuggestion',
precondition: SuggestContext.Visible,
handler: x => x.acceptSelectedSuggestion(true),
kbOpts: {
weight: weight,
kbExpr: EditorContextKeys.textInputFocus,
primary: KeyCode.Tab
},
handler(x, args) {
let overwriteSuffix: boolean;
if (typeof args !== 'object') {
overwriteSuffix = false;
} else if (typeof args.overwriteSuffix !== 'boolean') {
overwriteSuffix = false;
} else {
overwriteSuffix = args.overwriteSuffix;
}
x.acceptSelectedSuggestion(true, overwriteSuffix);
}
}));
KeybindingsRegistry.registerKeybindingRule({
id: 'acceptSelectedSuggestion',
when: ContextKeyExpr.and(SuggestContext.Visible, EditorContextKeys.textInputFocus),
primary: KeyMod.Shift | KeyCode.Tab,
secondary: [KeyMod.Shift | KeyCode.Enter],
args: { overwriteSuffix: true },
weight
});
registerEditorCommand(new SuggestCommand({
id: 'acceptSelectedSuggestionOnEnter',
precondition: SuggestContext.Visible,
handler: x => x.acceptSelectedSuggestion(false),
handler: x => x.acceptSelectedSuggestion(false, false),
kbOpts: {
weight: weight,
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, SuggestContext.AcceptSuggestionsOnEnter, SuggestContext.MakesTextEdit),
......
......@@ -676,7 +676,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
return withOracle(async (sugget, editor) => {
class TestCtrl extends SuggestController {
_insertSuggestion(item: ISelectedSuggestion) {
super._insertSuggestion(item, false, true, true);
super._insertSuggestion(item, false, true, true, false);
}
}
const ctrl = <TestCtrl>editor.registerAndInstantiateContribution(TestCtrl);
......
......@@ -38,6 +38,7 @@ export interface IKeybindings {
export interface IKeybindingRule extends IKeybindings {
id: string;
weight: number;
args?: any;
when: ContextKeyExpr | null | undefined;
}
......@@ -132,7 +133,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
if (actualKb && actualKb.primary) {
const kk = createKeybinding(actualKb.primary, OS);
if (kk) {
this._registerDefaultKeybinding(kk, rule.id, undefined, rule.weight, 0, rule.when);
this._registerDefaultKeybinding(kk, rule.id, rule.args, rule.weight, 0, rule.when);
}
}
......@@ -141,7 +142,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
const k = actualKb.secondary[i];
const kk = createKeybinding(k, OS);
if (kk) {
this._registerDefaultKeybinding(kk, rule.id, undefined, rule.weight, -i - 1, rule.when);
this._registerDefaultKeybinding(kk, rule.id, rule.args, rule.weight, -i - 1, rule.when);
}
}
}
......
......@@ -919,7 +919,7 @@ class AcceptReplInputAction extends EditorAction {
}
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
SuggestController.get(editor).acceptSelectedSuggestion();
SuggestController.get(editor).acceptSelectedSuggestion(false, false);
accessor.get(IPrivateReplService).acceptReplInput();
}
}
......@@ -941,7 +941,7 @@ class FilterReplAction extends EditorAction {
}
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
SuggestController.get(editor).acceptSelectedSuggestion();
SuggestController.get(editor).acceptSelectedSuggestion(false, false);
accessor.get(IPrivateReplService).focusRepl();
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册