From 51fb6d653edb440fce62d4ec4848dd9dd87f8001 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 4 Oct 2023 16:19:00 -0700 Subject: [PATCH] Initial attempt to support editor commands This depends on https://github.com/microsoft/vscode/pull/193937 and would allow Editor Commands' descriptions to be picked up in the TF-IDF indexing of commands. The problem I currently struggle with is what to do with this introduction of `ICommandMetadata`... do we want to add it to monaco? Do we want to add maybe a subset of it (just the description property)? Additionally, I noticed that the concept of a LocalizedString isn't a thing in the monaco API... so that would be _another_ thing to introduce. Should we add these types? Or should we have `description` be a `string` and then use that instead? --- src/vs/editor/browser/editorExtensions.ts | 2 + .../editor/browser/widget/codeEditorWidget.ts | 1 + src/vs/editor/common/editorAction.ts | 31 +++++---------- src/vs/editor/common/editorCommon.ts | 2 + .../common/standalone/standaloneEnums.ts | 38 +++++++++---------- .../browser/bracketMatching.ts | 2 +- .../browser/commandsQuickAccess.ts | 8 ++++ .../browser/standaloneCodeEditor.ts | 2 + src/vs/monaco.d.ts | 5 +++ 9 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/vs/editor/browser/editorExtensions.ts b/src/vs/editor/browser/editorExtensions.ts index 961941f76dd83..3b7f5c591fe97 100644 --- a/src/vs/editor/browser/editorExtensions.ts +++ b/src/vs/editor/browser/editorExtensions.ts @@ -376,11 +376,13 @@ export abstract class EditorAction extends EditorCommand { public readonly label: string; public readonly alias: string; + public readonly metadata: ICommandMetadata | undefined; constructor(opts: IActionOptions) { super(EditorAction.convertOptions(opts)); this.label = opts.label; this.alias = opts.alias; + this.metadata = opts.metadata; } public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Promise { diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index dd1275d834c70..3c2618e98d982 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -344,6 +344,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE action.id, action.label, action.alias, + action.metadata, action.precondition ?? undefined, (): Promise => { return this._instantiationService.invokeFunction((accessor) => { diff --git a/src/vs/editor/common/editorAction.ts b/src/vs/editor/common/editorAction.ts index 5cf40416a1ef2..ab44f9d4505e7 100644 --- a/src/vs/editor/common/editorAction.ts +++ b/src/vs/editor/common/editorAction.ts @@ -4,33 +4,20 @@ *--------------------------------------------------------------------------------------------*/ import { IEditorAction } from 'vs/editor/common/editorCommon'; +import { ICommandMetadata } from 'vs/platform/commands/common/commands'; import { IContextKeyService, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey'; export class InternalEditorAction implements IEditorAction { - public readonly id: string; - public readonly label: string; - public readonly alias: string; - - private readonly _precondition: ContextKeyExpression | undefined; - private readonly _run: (args: unknown) => Promise; - private readonly _contextKeyService: IContextKeyService; - constructor( - id: string, - label: string, - alias: string, - precondition: ContextKeyExpression | undefined, - run: () => Promise, - contextKeyService: IContextKeyService - ) { - this.id = id; - this.label = label; - this.alias = alias; - this._precondition = precondition; - this._run = run; - this._contextKeyService = contextKeyService; - } + public readonly id: string, + public readonly label: string, + public readonly alias: string, + public readonly metadata: ICommandMetadata | undefined, + private readonly _precondition: ContextKeyExpression | undefined, + private readonly _run: (args: unknown) => Promise, + private readonly _contextKeyService: IContextKeyService + ) { } public isSupported(): boolean { return this._contextKeyService.contextMatchesRules(this._precondition); diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 6ce806ff1090d..f4485ae9a6d85 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -15,6 +15,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { IModelDecoration, IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel, IValidEditOperation, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { IModelDecorationsChangedEvent } from 'vs/editor/common/textModelEvents'; +import { ICommandMetadata } from 'vs/platform/commands/common/commands'; /** * A builder and helper for edit operations for a command. @@ -155,6 +156,7 @@ export interface IEditorAction { readonly id: string; readonly label: string; readonly alias: string; + readonly metadata: ICommandMetadata | undefined; isSupported(): boolean; run(args?: unknown): Promise; } diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 622f4e56f23ee..44f9fb9b43406 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -572,28 +572,28 @@ export enum KeyCode { * Either the angle bracket key or the backslash key on the RT 102-key keyboard. */ IntlBackslash = 97, - Numpad0 = 98, - Numpad1 = 99, - Numpad2 = 100, - Numpad3 = 101, - Numpad4 = 102, - Numpad5 = 103, - Numpad6 = 104, - Numpad7 = 105, - Numpad8 = 106, - Numpad9 = 107, - NumpadMultiply = 108, - NumpadAdd = 109, - NUMPAD_SEPARATOR = 110, - NumpadSubtract = 111, - NumpadDecimal = 112, - NumpadDivide = 113, + Numpad0 = 98,// VK_NUMPAD0, 0x60, Numeric keypad 0 key + Numpad1 = 99,// VK_NUMPAD1, 0x61, Numeric keypad 1 key + Numpad2 = 100,// VK_NUMPAD2, 0x62, Numeric keypad 2 key + Numpad3 = 101,// VK_NUMPAD3, 0x63, Numeric keypad 3 key + Numpad4 = 102,// VK_NUMPAD4, 0x64, Numeric keypad 4 key + Numpad5 = 103,// VK_NUMPAD5, 0x65, Numeric keypad 5 key + Numpad6 = 104,// VK_NUMPAD6, 0x66, Numeric keypad 6 key + Numpad7 = 105,// VK_NUMPAD7, 0x67, Numeric keypad 7 key + Numpad8 = 106,// VK_NUMPAD8, 0x68, Numeric keypad 8 key + Numpad9 = 107,// VK_NUMPAD9, 0x69, Numeric keypad 9 key + NumpadMultiply = 108,// VK_MULTIPLY, 0x6A, Multiply key + NumpadAdd = 109,// VK_ADD, 0x6B, Add key + NUMPAD_SEPARATOR = 110,// VK_SEPARATOR, 0x6C, Separator key + NumpadSubtract = 111,// VK_SUBTRACT, 0x6D, Subtract key + NumpadDecimal = 112,// VK_DECIMAL, 0x6E, Decimal key + NumpadDivide = 113,// VK_DIVIDE, 0x6F, /** * Cover all key codes when IME is processing input. */ KEY_IN_COMPOSITION = 114, - ABNT_C1 = 115, - ABNT_C2 = 116, + ABNT_C1 = 115,// Brazilian (ABNT) Keyboard + ABNT_C2 = 116,// Brazilian (ABNT) Keyboard AudioVolumeMute = 117, AudioVolumeUp = 118, AudioVolumeDown = 119, @@ -924,4 +924,4 @@ export enum WrappingIndent { * DeepIndent => wrapped lines get +2 indentation toward the parent. */ DeepIndent = 3 -} +} \ No newline at end of file diff --git a/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts b/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts index bfa675232e92a..ffd9e3240dd8f 100644 --- a/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts +++ b/src/vs/editor/contrib/bracketMatching/browser/bracketMatching.ts @@ -53,7 +53,7 @@ class SelectToBracketAction extends EditorAction { alias: 'Select to Bracket', precondition: undefined, metadata: { - description: `Select to Bracket`, + description: nls.localize2('smartSelect.selectToBracketDescription', "Select the text inside and including the brackets or curly braces"), args: [{ name: 'args', schema: { diff --git a/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts b/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts index 9b91b082ab640..9fd9fc7a23344 100644 --- a/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts +++ b/src/vs/editor/contrib/quickAccess/browser/commandsQuickAccess.ts @@ -5,6 +5,7 @@ import { stripIcons } from 'vs/base/common/iconLabels'; import { IEditor } from 'vs/editor/common/editorCommon'; +import { isLocalizedString } from 'vs/platform/action/common/action'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -38,10 +39,17 @@ export abstract class AbstractEditorCommandsQuickAccessProvider extends Abstract const editorCommandPicks: ICommandQuickPick[] = []; for (const editorAction of activeTextEditorControl.getSupportedActions()) { + const metadataDescription = editorAction.metadata?.description; + const commandDescription = metadataDescription === undefined || isLocalizedString(metadataDescription) + ? metadataDescription + // TODO: this type will eventually not be a string and when that happens, this should simplified. + : { value: metadataDescription, original: metadataDescription }; + editorCommandPicks.push({ commandId: editorAction.id, commandAlias: editorAction.alias, label: stripIcons(editorAction.label) || editorAction.id, + commandDescription, }); } diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 02ff64c602bb3..9e1da128caecd 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -367,6 +367,8 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon uniqueId, label, label, + // TODO: support this somehow? Do I need the metadata to be a part of the API? + undefined, precondition, (...args: unknown[]) => Promise.resolve(_descriptor.run(this, ...args)), this._contextKeyService diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e322762b77473..15a38e014cffa 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3,6 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// TODO +// eslint-disable-next-line local/code-import-patterns +import { ICommandMetadata } from 'vs/platform/commands/common/commands'; + declare let MonacoEnvironment: monaco.Environment | undefined; interface Window { @@ -2469,6 +2473,7 @@ declare namespace monaco.editor { readonly id: string; readonly label: string; readonly alias: string; + readonly metadata: ICommandMetadata | undefined; isSupported(): boolean; run(args?: unknown): Promise; }