monaco-editor
Version:
A browser based code editor
315 lines • 14.9 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { asyncTransaction, transaction } from '../../../../../base/common/observable.js';
import { splitLines } from '../../../../../base/common/strings.js';
import * as nls from '../../../../../nls.js';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from '../../../../../platform/accessibility/common/accessibility.js';
import { Action2, MenuId } from '../../../../../platform/actions/common/actions.js';
import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.js';
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
import { KeybindingsRegistry } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
import { INotificationService, Severity } from '../../../../../platform/notification/common/notification.js';
import { EditorAction, EditorCommand } from '../../../../browser/editorExtensions.js';
import { EditorContextKeys } from '../../../../common/editorContextKeys.js';
import { Context as SuggestContext } from '../../../suggest/browser/suggest.js';
import { hideInlineCompletionId, inlineSuggestCommitId, jumpToNextInlineEditId, showNextInlineSuggestionActionId, showPreviousInlineSuggestionActionId, toggleShowCollapsedId } from './commandIds.js';
import { InlineCompletionContextKeys } from './inlineCompletionContextKeys.js';
import { InlineCompletionsController } from './inlineCompletionsController.js';
export class ShowNextInlineSuggestionAction extends EditorAction {
static { this.ID = showNextInlineSuggestionActionId; }
constructor() {
super({
id: ShowNextInlineSuggestionAction.ID,
label: nls.localize2(1174, "Show Next Inline Suggestion"),
precondition: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible),
kbOpts: {
weight: 100,
primary: 512 /* KeyMod.Alt */ | 94 /* KeyCode.BracketRight */,
},
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
controller?.model.get()?.next();
}
}
export class ShowPreviousInlineSuggestionAction extends EditorAction {
static { this.ID = showPreviousInlineSuggestionActionId; }
constructor() {
super({
id: ShowPreviousInlineSuggestionAction.ID,
label: nls.localize2(1175, "Show Previous Inline Suggestion"),
precondition: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible),
kbOpts: {
weight: 100,
primary: 512 /* KeyMod.Alt */ | 92 /* KeyCode.BracketLeft */,
},
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
controller?.model.get()?.previous();
}
}
export class TriggerInlineSuggestionAction extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.trigger',
label: nls.localize2(1176, "Trigger Inline Suggestion"),
precondition: EditorContextKeys.writable
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
await asyncTransaction(async (tx) => {
/** @description triggerExplicitly from command */
await controller?.model.get()?.triggerExplicitly(tx);
controller?.playAccessibilitySignal(tx);
});
}
}
export class ExplicitTriggerInlineEditAction extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.triggerInlineEditExplicit',
label: nls.localize2(1177, "Trigger Next Edit Suggestion"),
precondition: EditorContextKeys.writable,
});
}
async run(accessor, editor) {
const notificationService = accessor.get(INotificationService);
const controller = InlineCompletionsController.get(editor);
await controller?.model.get()?.triggerExplicitly(undefined, true);
if (!controller?.model.get()?.inlineEditAvailable.get()) {
notificationService.notify({
severity: Severity.Info,
message: nls.localize(1165, "No inline edit is available.")
});
}
}
}
export class TriggerInlineEditAction extends EditorCommand {
constructor() {
super({
id: 'editor.action.inlineSuggest.triggerInlineEdit',
precondition: EditorContextKeys.writable,
});
}
async runEditorCommand(accessor, editor, args) {
const controller = InlineCompletionsController.get(editor);
await controller?.model.get()?.trigger(undefined, { onlyFetchInlineEdits: true });
}
}
export class AcceptNextWordOfInlineCompletion extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.acceptNextWord',
label: nls.localize2(1178, "Accept Next Word Of Inline Suggestion"),
precondition: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible),
kbOpts: {
weight: 100 /* KeybindingWeight.EditorContrib */ + 1,
primary: 2048 /* KeyMod.CtrlCmd */ | 17 /* KeyCode.RightArrow */,
kbExpr: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible, InlineCompletionContextKeys.cursorBeforeGhostText, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()),
},
menuOpts: [{
menuId: MenuId.InlineSuggestionToolbar,
title: nls.localize(1166, 'Accept Word'),
group: 'primary',
order: 2,
}],
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
await controller?.model.get()?.acceptNextWord();
}
}
export class AcceptNextLineOfInlineCompletion extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.acceptNextLine',
label: nls.localize2(1179, "Accept Next Line Of Inline Suggestion"),
precondition: ContextKeyExpr.and(EditorContextKeys.writable, InlineCompletionContextKeys.inlineSuggestionVisible),
kbOpts: {
weight: 100 /* KeybindingWeight.EditorContrib */ + 1,
},
menuOpts: [{
menuId: MenuId.InlineSuggestionToolbar,
title: nls.localize(1167, 'Accept Line'),
group: 'secondary',
order: 2,
}],
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
await controller?.model.get()?.acceptNextLine();
}
}
export class AcceptInlineCompletion extends EditorAction {
constructor() {
super({
id: inlineSuggestCommitId,
label: nls.localize2(1180, "Accept Inline Suggestion"),
precondition: ContextKeyExpr.or(InlineCompletionContextKeys.inlineSuggestionVisible, InlineCompletionContextKeys.inlineEditVisible),
menuOpts: [{
menuId: MenuId.InlineSuggestionToolbar,
title: nls.localize(1168, "Accept"),
group: 'primary',
order: 2,
}, {
menuId: MenuId.InlineEditsActions,
title: nls.localize(1169, "Accept"),
group: 'primary',
order: 2,
}],
kbOpts: [
{
primary: 2 /* KeyCode.Tab */,
weight: 200,
kbExpr: ContextKeyExpr.or(ContextKeyExpr.and(InlineCompletionContextKeys.inlineSuggestionVisible, EditorContextKeys.tabMovesFocus.toNegated(), SuggestContext.Visible.toNegated(), EditorContextKeys.hoverFocused.toNegated(), InlineCompletionContextKeys.hasSelection.toNegated(), InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize), ContextKeyExpr.and(InlineCompletionContextKeys.inlineEditVisible, EditorContextKeys.tabMovesFocus.toNegated(), SuggestContext.Visible.toNegated(), EditorContextKeys.hoverFocused.toNegated(), InlineCompletionContextKeys.tabShouldAcceptInlineEdit)),
}
],
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.getInFocusedEditorOrParent(accessor);
if (controller) {
controller.model.get()?.accept(controller.editor);
controller.editor.focus();
}
}
}
KeybindingsRegistry.registerKeybindingRule({
id: inlineSuggestCommitId,
weight: 202, // greater than jump
primary: 2 /* KeyCode.Tab */,
when: ContextKeyExpr.and(InlineCompletionContextKeys.inInlineEditsPreviewEditor)
});
export class JumpToNextInlineEdit extends EditorAction {
constructor() {
super({
id: jumpToNextInlineEditId,
label: nls.localize2(1181, "Jump to next inline edit"),
precondition: InlineCompletionContextKeys.inlineEditVisible,
menuOpts: [{
menuId: MenuId.InlineEditsActions,
title: nls.localize(1170, "Jump"),
group: 'primary',
order: 1,
when: InlineCompletionContextKeys.cursorAtInlineEdit.toNegated(),
}],
kbOpts: {
primary: 2 /* KeyCode.Tab */,
weight: 201,
kbExpr: ContextKeyExpr.and(InlineCompletionContextKeys.inlineEditVisible, EditorContextKeys.tabMovesFocus.toNegated(), SuggestContext.Visible.toNegated(), EditorContextKeys.hoverFocused.toNegated(), InlineCompletionContextKeys.tabShouldJumpToInlineEdit),
}
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.get(editor);
if (controller) {
controller.jump();
}
}
}
export class HideInlineCompletion extends EditorAction {
static { this.ID = hideInlineCompletionId; }
constructor() {
super({
id: HideInlineCompletion.ID,
label: nls.localize2(1182, "Hide Inline Suggestion"),
precondition: ContextKeyExpr.or(InlineCompletionContextKeys.inlineSuggestionVisible, InlineCompletionContextKeys.inlineEditVisible),
kbOpts: {
weight: 100 /* KeybindingWeight.EditorContrib */ + 90, // same as hiding the suggest widget
primary: 9 /* KeyCode.Escape */,
},
menuOpts: [{
menuId: MenuId.InlineEditsActions,
title: nls.localize(1171, "Reject"),
group: 'primary',
order: 3,
}]
});
}
async run(accessor, editor) {
const controller = InlineCompletionsController.getInFocusedEditorOrParent(accessor);
transaction(tx => {
controller?.model.get()?.stop('explicitCancel', tx);
});
controller?.editor.focus();
}
}
export class ToggleInlineCompletionShowCollapsed extends EditorAction {
static { this.ID = toggleShowCollapsedId; }
constructor() {
super({
id: ToggleInlineCompletionShowCollapsed.ID,
label: nls.localize2(1183, "Toggle Inline Suggestions Show Collapsed"),
precondition: ContextKeyExpr.true(),
});
}
async run(accessor, editor) {
const configurationService = accessor.get(IConfigurationService);
const showCollapsed = configurationService.getValue('editor.inlineSuggest.edits.showCollapsed');
configurationService.updateValue('editor.inlineSuggest.edits.showCollapsed', !showCollapsed);
}
}
KeybindingsRegistry.registerKeybindingRule({
id: HideInlineCompletion.ID,
weight: -1, // very weak
primary: 9 /* KeyCode.Escape */,
secondary: [1024 /* KeyMod.Shift */ | 9 /* KeyCode.Escape */],
when: ContextKeyExpr.and(InlineCompletionContextKeys.inInlineEditsPreviewEditor)
});
export class ToggleAlwaysShowInlineSuggestionToolbar extends Action2 {
static { this.ID = 'editor.action.inlineSuggest.toggleAlwaysShowToolbar'; }
constructor() {
super({
id: ToggleAlwaysShowInlineSuggestionToolbar.ID,
title: nls.localize(1172, "Always Show Toolbar"),
f1: false,
precondition: undefined,
menu: [{
id: MenuId.InlineSuggestionToolbar,
group: 'secondary',
order: 10,
}],
toggled: ContextKeyExpr.equals('config.editor.inlineSuggest.showToolbar', 'always')
});
}
async run(accessor) {
const configService = accessor.get(IConfigurationService);
const currentValue = configService.getValue('editor.inlineSuggest.showToolbar');
const newValue = currentValue === 'always' ? 'onHover' : 'always';
configService.updateValue('editor.inlineSuggest.showToolbar', newValue);
}
}
export class DevExtractReproSample extends EditorAction {
constructor() {
super({
id: 'editor.action.inlineSuggest.dev.extractRepro',
label: nls.localize(1173, "Developer: Extract Inline Suggest State"),
alias: 'Developer: Inline Suggest Extract Repro',
precondition: ContextKeyExpr.or(InlineCompletionContextKeys.inlineEditVisible, InlineCompletionContextKeys.inlineSuggestionVisible),
});
}
async run(accessor, editor) {
const clipboardService = accessor.get(IClipboardService);
const controller = InlineCompletionsController.get(editor);
const m = controller?.model.get();
if (!m) {
return;
}
const repro = m.extractReproSample();
const inlineCompletionLines = splitLines(JSON.stringify({ inlineCompletion: repro.inlineCompletion }, null, 4));
const json = inlineCompletionLines.map(l => '// ' + l).join('\n');
const reproStr = `${repro.documentValue}\n\n// <json>\n${json}\n// </json>\n`;
await clipboardService.writeText(reproStr);
return { reproCase: reproStr };
}
}
//# sourceMappingURL=commands.js.map