diff --git a/src/vs/editor/browser/standalone/simpleServices.ts b/src/vs/editor/browser/standalone/simpleServices.ts index 480c423f3b5..894a39915b5 100644 --- a/src/vs/editor/browser/standalone/simpleServices.ts +++ b/src/vs/editor/browser/standalone/simpleServices.ts @@ -12,9 +12,9 @@ import { IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, import { IEditor, IEditorInput, IEditorOptions, IEditorService, IResourceInput, Position } from 'vs/platform/editor/common/editor'; import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService'; -import { KeybindingResolver, IOSupport } from 'vs/platform/keybinding/common/keybindingResolver'; +import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver'; import { IKeybindingEvent, IKeybindingItem, KeybindingSource } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfirmation, IMessageService } from 'vs/platform/message/common/message'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; @@ -327,15 +327,13 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { })); } - public addDynamicKeybinding(commandId: string, keybinding: number, handler: ICommandHandler, when: string): IDisposable { + public addDynamicKeybinding(commandId: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpr): IDisposable { let toDispose: IDisposable[] = []; - let parsedContext = IOSupport.readKeybindingWhen(when); - this._dynamicKeybindings.push({ keybinding: keybinding, command: commandId, - when: parsedContext, + when: when, weight1: 1000, weight2: 0 }); diff --git a/src/vs/editor/browser/standalone/standaloneCodeEditor.ts b/src/vs/editor/browser/standalone/standaloneCodeEditor.ts index 65a5e92193a..e143c6e913a 100644 --- a/src/vs/editor/browser/standalone/standaloneCodeEditor.ts +++ b/src/vs/editor/browser/standalone/standaloneCodeEditor.ts @@ -10,7 +10,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IEditorOptions, IActionDescriptor, ICodeEditorWidgetCreationOptions, IDiffEditorOptions, IModel, IModelChangedEvent, EventType } from 'vs/editor/common/editorCommon'; import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; @@ -20,6 +20,7 @@ import { CodeEditor } from 'vs/editor/browser/codeEditor'; import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IStandaloneColorService } from 'vs/editor/common/services/standaloneColorService'; +import { IOSupport } from 'vs/platform/keybinding/common/keybindingResolver'; /** * The options to create an editor. @@ -133,8 +134,8 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito return null; } let commandId = 'DYNAMIC_' + (++LAST_GENERATED_COMMAND_ID); - - this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, context); + let whenExpression = IOSupport.readKeybindingWhen(context); + this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, whenExpression); return commandId; } @@ -157,9 +158,13 @@ export class StandaloneEditor extends CodeEditor implements IStandaloneCodeEdito let handler: ICommandHandler = (accessor) => { return this.trigger('keyboard', descriptor.id, null); }; + let whenExpression = ContextKeyExpr.and( + IOSupport.readKeybindingWhen(descriptor.precondition), + IOSupport.readKeybindingWhen(descriptor.keybindingContext), + ); toDispose = toDispose.concat( descriptor.keybindings.map((kb) => { - return this._standaloneKeybindingService.addDynamicKeybinding(addedAction.uniqueId, kb, handler, descriptor.keybindingContext); + return this._standaloneKeybindingService.addDynamicKeybinding(addedAction.uniqueId, kb, handler, whenExpression); }) ); } @@ -226,7 +231,8 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon return null; } let commandId = 'DYNAMIC_' + (++LAST_GENERATED_COMMAND_ID); - this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, context); + let whenExpression = IOSupport.readKeybindingWhen(context); + this._standaloneKeybindingService.addDynamicKeybinding(commandId, keybinding, handler, whenExpression); return commandId; } @@ -249,9 +255,13 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon let handler: ICommandHandler = (ctx) => { return this.trigger('keyboard', descriptor.id, null); }; + let whenExpression = ContextKeyExpr.and( + IOSupport.readKeybindingWhen(descriptor.precondition), + IOSupport.readKeybindingWhen(descriptor.keybindingContext), + ); toDispose = toDispose.concat( descriptor.keybindings.map((kb) => { - return this._standaloneKeybindingService.addDynamicKeybinding(addedAction.uniqueId, kb, handler, descriptor.keybindingContext); + return this._standaloneKeybindingService.addDynamicKeybinding(addedAction.uniqueId, kb, handler, whenExpression); }) ); } diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index a0b1987a033..d4dec32f0ff 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -30,6 +30,7 @@ import { hash } from 'vs/base/common/hash'; import { EditorModeContext } from 'vs/editor/common/modes/editorModeContext'; import { MenuId, MenuRegistry, IMenuItem } from 'vs/platform/actions/common/actions'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { IOSupport } from 'vs/platform/keybinding/common/keybindingResolver'; import EditorContextKeys = editorCommon.EditorContextKeys; @@ -537,7 +538,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom // Generate a unique id to allow the same descriptor.id across multiple editor instances let uniqueId = this.getId() + ':' + descriptor.id; - let action = new DynamicEditorAction(descriptor, this); + let action = new DynamicEditorAction(descriptor.id, descriptor.label, descriptor.run, this); // Register the command toDispose.push(CommandsRegistry.registerCommand(uniqueId, () => action.run())); @@ -548,7 +549,10 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom id: uniqueId, title: descriptor.label }, - when: ContextKeyExpr.equals('editorId', this.getId()), + when: ContextKeyExpr.and( + ContextKeyExpr.equals('editorId', this.getId()), + IOSupport.readKeybindingWhen(descriptor.precondition) + ), group: descriptor.contextMenuGroupId, order: descriptor.contextMenuOrder || 0 }; diff --git a/src/vs/editor/common/editorAction.ts b/src/vs/editor/common/editorAction.ts index 404bd1646a4..0d5b7e24f8d 100644 --- a/src/vs/editor/common/editorAction.ts +++ b/src/vs/editor/common/editorAction.ts @@ -5,7 +5,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IActionDescriptor, ICommonCodeEditor, IEditorAction } from 'vs/editor/common/editorCommon'; +import { ICommonCodeEditor, IEditorAction } from 'vs/editor/common/editorCommon'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { EditorAction } from 'vs/editor/common/editorCommonExtensions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -62,10 +62,10 @@ export class DynamicEditorAction extends AbstractInternalEditorAction implements private _run: (editor: ICommonCodeEditor) => void; - constructor(descriptor: IActionDescriptor, editor: ICommonCodeEditor) { - super(descriptor.id, descriptor.label, descriptor.label, editor); + constructor(id: string, label: string, run: (editor: ICommonCodeEditor) => void | TPromise, editor: ICommonCodeEditor) { + super(id, label, label, editor); - this._run = descriptor.run; + this._run = run; } public isSupported(): boolean { diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 2c5646cb591..441a4848109 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -3358,10 +3358,18 @@ export interface IActionDescriptor { * A label of the action that will be presented to the user. */ label: string; + /** + * Precondition rule. + */ + precondition?: string; /** * An array of keybindings for the action. */ keybindings?: number[]; + /** + * The keybinding rule (condition on top of precondition). + */ + keybindingContext?: string; /** * Control if the action should show up in the context menu and where. * The context menu of the editor has these default: @@ -3376,10 +3384,6 @@ export interface IActionDescriptor { * Control the order in the context menu group. */ contextMenuOrder?: number; - /** - * The keybinding rule. - */ - keybindingContext?: string; /** * Method that will be executed when the action is triggered. * @param editor The editor instance is passed in as a convinience diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index d71b2c27649..d6af73f63df 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2802,10 +2802,18 @@ declare module monaco.editor { * A label of the action that will be presented to the user. */ label: string; + /** + * Precondition rule. + */ + precondition?: string; /** * An array of keybindings for the action. */ keybindings?: number[]; + /** + * The keybinding rule (condition on top of precondition). + */ + keybindingContext?: string; /** * Control if the action should show up in the context menu and where. * The context menu of the editor has these default: @@ -2820,10 +2828,6 @@ declare module monaco.editor { * Control the order in the context menu group. */ contextMenuOrder?: number; - /** - * The keybinding rule. - */ - keybindingContext?: string; /** * Method that will be executed when the action is triggered. * @param editor The editor instance is passed in as a convinience