From 80e93de878192d5bce15c9d8c05d26cb66b9b1a5 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 19 May 2017 11:23:34 +0200 Subject: [PATCH] Bring editor command classes together --- src/vs/editor/common/config/config.ts | 140 ---------------- .../editor/common/controller/coreCommands.ts | 3 +- .../editor/common/editorCommonExtensions.ts | 156 ++++++++++++++++-- .../snippet/browser/snippetController2.ts | 3 +- .../test/common/wordOperations.test.ts | 2 +- .../emmet/electron-browser/emmetActions.ts | 3 +- .../browser/keybindingsEditorContribution.ts | 3 +- 7 files changed, 146 insertions(+), 164 deletions(-) delete mode 100644 src/vs/editor/common/config/config.ts diff --git a/src/vs/editor/common/config/config.ts b/src/vs/editor/common/config/config.ts deleted file mode 100644 index 59cdce4151f..00000000000 --- a/src/vs/editor/common/config/config.ts +++ /dev/null @@ -1,140 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import { TPromise } from 'vs/base/common/winjs.base'; -import { IEditorService } from 'vs/platform/editor/common/editor'; -import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandAndKeybindingRule, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import * as editorCommon from 'vs/editor/common/editorCommon'; -import { ICodeEditorService, getCodeEditor } from 'vs/editor/common/services/codeEditorService'; -import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; - -export interface ICommandKeybindingsOptions extends IKeybindings { - kbExpr?: ContextKeyExpr; - weight?: number; -} - -export interface ICommandOptions { - id: string; - precondition: ContextKeyExpr; - kbOpts?: ICommandKeybindingsOptions; - description?: ICommandHandlerDescription; -} - -export abstract class Command { - public readonly id: string; - public readonly precondition: ContextKeyExpr; - private readonly _kbOpts: ICommandKeybindingsOptions; - private readonly _description: ICommandHandlerDescription; - - constructor(opts: ICommandOptions) { - this.id = opts.id; - this.precondition = opts.precondition; - this._kbOpts = opts.kbOpts; - this._description = opts.description; - } - - public toCommandAndKeybindingRule(defaultWeight: number): ICommandAndKeybindingRule { - const kbOpts = this._kbOpts || { primary: 0 }; - - let kbWhen = kbOpts.kbExpr; - if (this.precondition) { - if (kbWhen) { - kbWhen = ContextKeyExpr.and(kbWhen, this.precondition); - } else { - kbWhen = this.precondition; - } - } - - const weight = (typeof kbOpts.weight === 'number' ? kbOpts.weight : defaultWeight); - - return { - id: this.id, - handler: (accessor, args) => this.runCommand(accessor, args), - weight: weight, - when: kbWhen, - primary: kbOpts.primary, - secondary: kbOpts.secondary, - win: kbOpts.win, - linux: kbOpts.linux, - mac: kbOpts.mac, - description: this._description - }; - } - - public abstract runCommand(accessor: ServicesAccessor, args: any): void | TPromise; -} - -export interface IContributionCommandOptions extends ICommandOptions { - handler: (controller: T) => void; -} - -export interface EditorControllerCommand { - new (opts: IContributionCommandOptions): EditorCommand; -} - -function findFocusedEditor(accessor: ServicesAccessor): editorCommon.ICommonCodeEditor { - return accessor.get(ICodeEditorService).getFocusedCodeEditor(); -} - -function getWorkbenchActiveEditor(accessor: ServicesAccessor): editorCommon.ICommonCodeEditor { - const editorService = accessor.get(IEditorService); - let activeEditor = (editorService).getActiveEditor && (editorService).getActiveEditor(); - return getCodeEditor(activeEditor); -} - -export abstract class EditorCommand extends Command { - - /** - * Create a command class that is bound to a certain editor contribution. - */ - public static bindToContribution(controllerGetter: (editor: editorCommon.ICommonCodeEditor) => T): EditorControllerCommand { - return class EditorControllerCommandImpl extends EditorCommand { - private _callback: (controller: T) => void; - - constructor(opts: IContributionCommandOptions) { - super(opts); - - this._callback = opts.handler; - } - - public runEditorCommand(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void { - let controller = controllerGetter(editor); - if (controller) { - this._callback(controllerGetter(editor)); - } - } - }; - } - - public runCommand(accessor: ServicesAccessor, args: any): void | TPromise { - // Find the editor with text focus - let editor = findFocusedEditor(accessor); - - if (!editor) { - // Fallback to use what the workbench considers the active editor - editor = getWorkbenchActiveEditor(accessor); - } - - if (!editor) { - // well, at least we tried... - return; - } - - return editor.invokeWithinContext((editorAccessor) => { - const kbService = editorAccessor.get(IContextKeyService); - if (!kbService.contextMatchesRules(this.precondition)) { - // precondition does not hold - return; - } - - return this.runEditorCommand(editorAccessor, editor, args); - }); - } - - public abstract runEditorCommand(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void | TPromise; -} diff --git a/src/vs/editor/common/controller/coreCommands.ts b/src/vs/editor/common/controller/coreCommands.ts index 8004f96f402..9172351e644 100644 --- a/src/vs/editor/common/controller/coreCommands.ts +++ b/src/vs/editor/common/controller/coreCommands.ts @@ -11,9 +11,8 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { CursorState, ICursors, RevealTarget, IColumnSelectData, CursorContext } from 'vs/editor/common/controller/cursorCommon'; import { CursorChangeReason, VerticalRevealType } from 'vs/editor/common/controller/cursorEvents'; import { CursorMoveCommands, CursorMove as CursorMove_ } from 'vs/editor/common/controller/cursorMoveCommands'; -import { EditorCommand, ICommandOptions, Command } from 'vs/editor/common/config/config'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { registerEditorCommand } from 'vs/editor/common/editorCommonExtensions'; +import { registerEditorCommand, ICommandOptions, EditorCommand, Command } from 'vs/editor/common/editorCommonExtensions'; import { IColumnSelectResult, ColumnSelection } from 'vs/editor/common/controller/cursorColumnSelection'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; diff --git a/src/vs/editor/common/editorCommonExtensions.ts b/src/vs/editor/common/editorCommonExtensions.ts index c80f219223d..e991a1a208c 100644 --- a/src/vs/editor/common/editorCommonExtensions.ts +++ b/src/vs/editor/common/editorCommonExtensions.ts @@ -8,22 +8,148 @@ import { illegalArgument } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; import { ServicesAccessor, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; +import { KeybindingsRegistry, ICommandAndKeybindingRule, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { Registry } from 'vs/platform/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ICommandOptions, Command as ConfigBasicCommand, EditorCommand as ConfigEditorCommand } from 'vs/editor/common/config/config'; import { Position } from 'vs/editor/common/core/position'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { IModelService } from 'vs/editor/common/services/modelService'; import { MenuId, MenuRegistry, IMenuItem } from 'vs/platform/actions/common/actions'; +import { IEditorService } from 'vs/platform/editor/common/editor'; +import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ICodeEditorService, getCodeEditor } from 'vs/editor/common/services/codeEditorService'; export type ServicesAccessor = ServicesAccessor; -export const Command = ConfigBasicCommand; -export const EditorCommand = ConfigEditorCommand; -export type ICommandOptions = ICommandOptions; export type ICommonEditorContributionCtor = IConstructorSignature1; +// ----- Generic Command + +export interface ICommandKeybindingsOptions extends IKeybindings { + kbExpr?: ContextKeyExpr; + weight?: number; +} +export interface ICommandOptions { + id: string; + precondition: ContextKeyExpr; + kbOpts?: ICommandKeybindingsOptions; + description?: ICommandHandlerDescription; +} +export abstract class Command { + public readonly id: string; + public readonly precondition: ContextKeyExpr; + private readonly _kbOpts: ICommandKeybindingsOptions; + private readonly _description: ICommandHandlerDescription; + + constructor(opts: ICommandOptions) { + this.id = opts.id; + this.precondition = opts.precondition; + this._kbOpts = opts.kbOpts; + this._description = opts.description; + } + + public toCommandAndKeybindingRule(defaultWeight: number): ICommandAndKeybindingRule { + const kbOpts = this._kbOpts || { primary: 0 }; + + let kbWhen = kbOpts.kbExpr; + if (this.precondition) { + if (kbWhen) { + kbWhen = ContextKeyExpr.and(kbWhen, this.precondition); + } else { + kbWhen = this.precondition; + } + } + + const weight = (typeof kbOpts.weight === 'number' ? kbOpts.weight : defaultWeight); + + return { + id: this.id, + handler: (accessor, args) => this.runCommand(accessor, args), + weight: weight, + when: kbWhen, + primary: kbOpts.primary, + secondary: kbOpts.secondary, + win: kbOpts.win, + linux: kbOpts.linux, + mac: kbOpts.mac, + description: this._description + }; + } + + public abstract runCommand(accessor: ServicesAccessor, args: any): void | TPromise; +} + +// ----- Editor Command & Editor Contribution Command + +function findFocusedEditor(accessor: ServicesAccessor): editorCommon.ICommonCodeEditor { + return accessor.get(ICodeEditorService).getFocusedCodeEditor(); +} +function getWorkbenchActiveEditor(accessor: ServicesAccessor): editorCommon.ICommonCodeEditor { + const editorService = accessor.get(IEditorService); + let activeEditor = (editorService).getActiveEditor && (editorService).getActiveEditor(); + return getCodeEditor(activeEditor); +} + +export interface IContributionCommandOptions extends ICommandOptions { + handler: (controller: T) => void; +} +export interface EditorControllerCommand { + new (opts: IContributionCommandOptions): EditorCommand; +} +export abstract class EditorCommand extends Command { + + /** + * Create a command class that is bound to a certain editor contribution. + */ + public static bindToContribution(controllerGetter: (editor: editorCommon.ICommonCodeEditor) => T): EditorControllerCommand { + return class EditorControllerCommandImpl extends EditorCommand { + private _callback: (controller: T) => void; + + constructor(opts: IContributionCommandOptions) { + super(opts); + + this._callback = opts.handler; + } + + public runEditorCommand(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void { + let controller = controllerGetter(editor); + if (controller) { + this._callback(controllerGetter(editor)); + } + } + }; + } + + public runCommand(accessor: ServicesAccessor, args: any): void | TPromise { + // Find the editor with text focus + let editor = findFocusedEditor(accessor); + + if (!editor) { + // Fallback to use what the workbench considers the active editor + editor = getWorkbenchActiveEditor(accessor); + } + + if (!editor) { + // well, at least we tried... + return; + } + + return editor.invokeWithinContext((editorAccessor) => { + const kbService = editorAccessor.get(IContextKeyService); + if (!kbService.contextMatchesRules(this.precondition)) { + // precondition does not hold + return; + } + + return this.runEditorCommand(editorAccessor, editor, args); + }); + } + + public abstract runEditorCommand(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void | TPromise; +} + +// ----- Editor Action + export interface IEditorCommandMenuOptions { group?: string; order?: number; @@ -33,7 +159,7 @@ export interface IActionOptions extends ICommandOptions { alias: string; menuOpts?: IEditorCommandMenuOptions; } -export abstract class EditorAction extends ConfigEditorCommand { +export abstract class EditorAction extends EditorCommand { public label: string; public alias: string; @@ -74,17 +200,17 @@ export abstract class EditorAction extends ConfigEditorCommand { public abstract run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void | TPromise; } -// --- Editor Actions +// --- Registration of commands and actions export function editorAction(ctor: { new (): EditorAction; }): void { CommonEditorRegistry.registerEditorAction(new ctor()); } -export function editorCommand(ctor: { new (): ConfigEditorCommand }): void { +export function editorCommand(ctor: { new (): EditorCommand }): void { registerEditorCommand(new ctor()); } -export function registerEditorCommand(editorCommand: T): T { +export function registerEditorCommand(editorCommand: T): T { CommonEditorRegistry.registerEditorCommand(editorCommand); return editorCommand; } @@ -103,7 +229,7 @@ export module CommonEditorRegistry { export function getEditorActions(): EditorAction[] { return EditorContributionRegistry.INSTANCE.getEditorActions(); } - export function getEditorCommand(commandId: string): ConfigEditorCommand { + export function getEditorCommand(commandId: string): EditorCommand { return EditorContributionRegistry.INSTANCE.getEditorCommand(commandId); } @@ -119,7 +245,7 @@ export module CommonEditorRegistry { return KeybindingsRegistry.WEIGHT.editorContrib(importance); } - export function registerEditorCommand(editorCommand: ConfigEditorCommand): void { + export function registerEditorCommand(editorCommand: EditorCommand): void { EditorContributionRegistry.INSTANCE.registerEditorCommand(editorCommand); } @@ -161,7 +287,7 @@ class EditorContributionRegistry { private editorContributions: ICommonEditorContributionCtor[]; private editorActions: EditorAction[]; - private editorCommands: { [commandId: string]: ConfigEditorCommand; }; + private editorCommands: { [commandId: string]: EditorCommand; }; constructor() { this.editorContributions = []; @@ -193,12 +319,12 @@ class EditorContributionRegistry { return this.editorActions.slice(0); } - public registerEditorCommand(editorCommand: ConfigEditorCommand) { + public registerEditorCommand(editorCommand: EditorCommand) { KeybindingsRegistry.registerCommandAndKeybindingRule(editorCommand.toCommandAndKeybindingRule(KeybindingsRegistry.WEIGHT.editorContrib())); this.editorCommands[editorCommand.id] = editorCommand; } - public getEditorCommand(commandId: string): ConfigEditorCommand { + public getEditorCommand(commandId: string): EditorCommand { return (this.editorCommands[commandId] || null); } diff --git a/src/vs/editor/contrib/snippet/browser/snippetController2.ts b/src/vs/editor/contrib/snippet/browser/snippetController2.ts index 6f156fffe2d..3983e58599e 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetController2.ts @@ -7,10 +7,9 @@ import { RawContextKey, IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ICommonCodeEditor } from 'vs/editor/common/editorCommon'; -import { commonEditorContribution, CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions'; +import { commonEditorContribution, CommonEditorRegistry, EditorCommand } from 'vs/editor/common/editorCommonExtensions'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { SnippetSession } from './snippetSession'; -import { EditorCommand } from 'vs/editor/common/config/config'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; diff --git a/src/vs/editor/contrib/wordOperations/test/common/wordOperations.test.ts b/src/vs/editor/contrib/wordOperations/test/common/wordOperations.test.ts index ab99938740b..d67a436a400 100644 --- a/src/vs/editor/contrib/wordOperations/test/common/wordOperations.test.ts +++ b/src/vs/editor/contrib/wordOperations/test/common/wordOperations.test.ts @@ -17,7 +17,7 @@ import { DeleteWordLeft, DeleteWordStartLeft, DeleteWordEndLeft, DeleteWordRight, DeleteWordStartRight, DeleteWordEndRight } from 'vs/editor/contrib/wordOperations/common/wordOperations'; -import { EditorCommand } from 'vs/editor/common/config/config'; +import { EditorCommand } from "vs/editor/common/editorCommonExtensions"; suite('WordOperations', () => { diff --git a/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts b/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts index d73bc725327..16c227e8800 100644 --- a/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts +++ b/src/vs/workbench/parts/emmet/electron-browser/emmetActions.ts @@ -7,8 +7,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ICommonCodeEditor } from 'vs/editor/common/editorCommon'; -import { EditorAction, ServicesAccessor, IActionOptions } from 'vs/editor/common/editorCommonExtensions'; -import { ICommandKeybindingsOptions } from 'vs/editor/common/config/config'; +import { EditorAction, ServicesAccessor, IActionOptions, ICommandKeybindingsOptions } from 'vs/editor/common/editorCommonExtensions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { grammarsExtPoint, ITMSyntaxExtensionPoint } from 'vs/editor/node/textMate/TMGrammars'; import { IModeService } from 'vs/editor/common/services/modeService'; diff --git a/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts b/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts index 7f73595d894..9733c62707f 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts @@ -15,7 +15,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { ServicesAccessor, registerEditorCommand } from 'vs/editor/common/editorCommonExtensions'; +import { ServicesAccessor, registerEditorCommand, EditorCommand } from 'vs/editor/common/editorCommonExtensions'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions'; import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2'; @@ -26,7 +26,6 @@ import { parseTree, Node } from 'vs/base/common/json'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { ScanCodeBinding } from 'vs/workbench/services/keybinding/common/scanCode'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { EditorCommand } from 'vs/editor/common/config/config'; const NLS_LAUNCH_MESSAGE = nls.localize('defineKeybinding.start', "Define Keybinding"); const NLS_KB_LAYOUT_INFO_MESSAGE = nls.localize('defineKeybinding.kbLayoutInfoMessage', "For your current keyboard layout press "); -- GitLab