From 77df19537b7ba79f7f05a9efa86481f9abcd42ae Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 22 Nov 2016 20:42:15 -0800 Subject: [PATCH] Add IKeybindingService.resolve --- .../browser/keybindingServiceImpl.ts | 26 ++++++++++++------- .../platform/keybinding/common/keybinding.ts | 4 ++- .../test/common/mockKeybindingService.ts | 7 ++++- .../electron-browser/terminal.contribution.ts | 5 ++-- .../electron-browser/terminalInstance.ts | 24 ++++++----------- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts b/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts index bc68d738e71..1a80ba3d902 100644 --- a/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts +++ b/src/vs/platform/keybinding/browser/keybindingServiceImpl.ts @@ -15,9 +15,9 @@ import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ICommandService, CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; -import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver'; +import { KeybindingResolver, IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; import { IKeybindingItem, IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IMessageService } from 'vs/platform/message/common/message'; @@ -142,18 +142,26 @@ export abstract class KeybindingService implements IKeybindingService { return '// ' + nls.localize('unboundCommands', "Here are other available commands: ") + '\n// - ' + pretty; } - protected _dispatch(e: IKeyboardEvent): void { - let isModifierKey = (e.keyCode === KeyCode.Ctrl || e.keyCode === KeyCode.Shift || e.keyCode === KeyCode.Alt || e.keyCode === KeyCode.Meta); + public resolve(keybinding: Keybinding, target: IContextKeyServiceTarget): IResolveResult { + const keyCode = keybinding.extractKeyCode(); + let isModifierKey = (keyCode === KeyCode.Ctrl || keyCode === KeyCode.Shift || keyCode === KeyCode.Alt || keyCode === KeyCode.Meta); if (isModifierKey) { - return; + return null; } - let contextValue = this._contextKeyService.getContextValue(e.target); - // console.log(JSON.stringify(contextValue, null, '\t')); + let contextValue = this._contextKeyService.getContextValue(target); + + return this._getResolver().resolve(contextValue, this._currentChord, keybinding.value); + } + + protected _dispatch(e: IKeyboardEvent): void { + const resolveResult = this.resolve(new Keybinding(e.asKeybinding()), e.target); - let resolveResult = this._getResolver().resolve(contextValue, this._currentChord, e.asKeybinding()); + if (!resolveResult) { + return; + } - if (resolveResult && resolveResult.enterChord) { + if (resolveResult.enterChord) { e.preventDefault(); this._currentChord = resolveResult.enterChord; if (this._statusService) { diff --git a/src/vs/platform/keybinding/common/keybinding.ts b/src/vs/platform/keybinding/common/keybinding.ts index 5b133882eb9..451775534c0 100644 --- a/src/vs/platform/keybinding/common/keybinding.ts +++ b/src/vs/platform/keybinding/common/keybinding.ts @@ -7,7 +7,8 @@ import { IHTMLContentElement } from 'vs/base/common/htmlContent'; import { Keybinding } from 'vs/base/common/keybinding'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey'; +import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; import Event from 'vs/base/common/event'; export interface IUserFriendlyKeybinding { @@ -58,5 +59,6 @@ export interface IKeybindingService { getDefaultKeybindings(): string; lookupKeybindings(commandId: string): Keybinding[]; customKeybindingsCount(): number; + resolve(keybinding: Keybinding, target: IContextKeyServiceTarget): IResolveResult; } diff --git a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts index c41d8b4dc34..489ce3398f3 100644 --- a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts +++ b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts @@ -8,7 +8,8 @@ import { IHTMLContentElement } from 'vs/base/common/htmlContent'; import { Keybinding } from 'vs/base/common/keybinding'; import Event from 'vs/base/common/event'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService, IContextKeyServiceTarget, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; class MockKeybindingContextKey implements IContextKey { private _key: string; @@ -93,4 +94,8 @@ export class MockKeybindingService2 implements IKeybindingService { public customKeybindingsCount(): number { return 0; } + + public resolve(keybinding: Keybinding, target: IContextKeyServiceTarget): IResolveResult { + return null; + } } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index c2462b52932..5bbc097aa89 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -9,7 +9,6 @@ import 'vs/css!./media/xterm'; import * as panel from 'vs/workbench/browser/panel'; import * as platform from 'vs/base/common/platform'; import nls = require('vs/nls'); -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { GlobalQuickOpenAction } from 'vs/workbench/browser/parts/quickopen/quickopen.contribution'; import { ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, TERMINAL_DEFAULT_SHELL_LINUX, TERMINAL_DEFAULT_SHELL_OSX, TERMINAL_DEFAULT_SHELL_WINDOWS } from 'vs/workbench/parts/terminal/common/terminal'; @@ -157,10 +156,10 @@ let actionRegistry = Registry.as(ActionExtensions.Work actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_C, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }, + //linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }, // Don't apply to Mac since cmd+c works mac: { primary: null } -}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED)), 'Terminal: Copy Selection', category); +}, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED), 'Terminal: Copy Selection', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_BACKTICK } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 3a5b6305b71..48b32f4d840 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -41,7 +41,7 @@ export class TerminalInstance implements ITerminalInstance { private _onTitleChanged: Emitter; private _process: cp.ChildProcess; private _processId: number; - private _skipTerminalKeybindings: Keybinding[]; + private _skipTerminalCommands: string[]; private _title: string; private _toDispose: lifecycle.IDisposable[]; private _wrapperElement: HTMLDivElement; @@ -68,7 +68,7 @@ export class TerminalInstance implements ITerminalInstance { @IMessageService private _messageService: IMessageService ) { this._toDispose = []; - this._skipTerminalKeybindings = []; + this._skipTerminalCommands = []; this._isExiting = false; this._isLaunching = true; this._isVisible = false; @@ -119,15 +119,11 @@ export class TerminalInstance implements ITerminalInstance { return false; }); this._xterm.attachCustomKeydownHandler((event: KeyboardEvent) => { - // Allow the toggle tab mode keybinding to pass through the terminal so that focus can - // be escaped - let standardKeyboardEvent = new StandardKeyboardEvent(event); - - // TODO: Use this._contextKeyService.contextMatchesRules(rules); to check the context as - // well to ensure that only commands that are relevant given the context are skipped - // (eg. ctrl+c to copy when text selected or kill the process (don't skip) when not) - - if (this._skipTerminalKeybindings.some(k => standardKeyboardEvent.equals(k.value))) { + // Skip processing by xterm.js of commands within commandsToSkipShell + const standardKeyboardEvent = new StandardKeyboardEvent(event); + const keybinding = new Keybinding(standardKeyboardEvent.asKeybinding()); + const resolveResult = this._keybindingService.resolve(keybinding, standardKeyboardEvent.target); + if (resolveResult && this._skipTerminalCommands.some(k => k === resolveResult.commandId)) { event.preventDefault(); return false; } @@ -369,11 +365,7 @@ export class TerminalInstance implements ITerminalInstance { } public setCommandsToSkipShell(commands: string[]): void { - this._skipTerminalKeybindings = commands.map((c) => { - return this._keybindingService.lookupKeybindings(c); - }).reduce((prev, curr) => { - return prev.concat(curr); - }, []); + this._skipTerminalCommands = commands; } public setScrollback(lineCount: number): void { -- GitLab