mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Add a trace statement to be able to track down which implementation handles a MultiCommand
This commit is contained in:
parent
9089e0cbd9
commit
afca44535d
|
@ -281,7 +281,7 @@ abstract class EditorOrNativeTextInputCommand {
|
|||
|
||||
constructor(target: MultiCommand) {
|
||||
// 1. handle case when focus is in editor.
|
||||
target.addImplementation(10000, (accessor: ServicesAccessor, args: any) => {
|
||||
target.addImplementation(10000, 'code-editor', (accessor: ServicesAccessor, args: any) => {
|
||||
// Only if editor text focus (i.e. not if editor has widget focus).
|
||||
const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
if (focusedEditor && focusedEditor.hasTextFocus()) {
|
||||
|
@ -291,7 +291,7 @@ abstract class EditorOrNativeTextInputCommand {
|
|||
});
|
||||
|
||||
// 2. handle case when focus is in some other `input` / `textarea`.
|
||||
target.addImplementation(1000, (accessor: ServicesAccessor, args: any) => {
|
||||
target.addImplementation(1000, 'generic-dom-input-textarea', (accessor: ServicesAccessor, args: any) => {
|
||||
// Only if focused on an element that allows for entering text
|
||||
const activeElement = <HTMLElement>document.activeElement;
|
||||
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
|
||||
|
@ -302,7 +302,7 @@ abstract class EditorOrNativeTextInputCommand {
|
|||
});
|
||||
|
||||
// 3. (default) handle case when focus is somewhere else.
|
||||
target.addImplementation(0, (accessor: ServicesAccessor, args: any) => {
|
||||
target.addImplementation(0, 'generic-dom', (accessor: ServicesAccessor, args: any) => {
|
||||
// Redirecting to active editor
|
||||
const activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
|
||||
if (activeEditor) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import { withNullAsUndefined, assertType } from 'vs/base/common/types';
|
|||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
|
||||
export type ServicesAccessor = InstantiationServicesAccessor;
|
||||
|
@ -149,20 +150,26 @@ export abstract class Command {
|
|||
*/
|
||||
export type CommandImplementation = (accessor: ServicesAccessor, args: unknown) => boolean | Promise<void>;
|
||||
|
||||
interface ICommandImplementationRegistration {
|
||||
priority: number;
|
||||
name: string;
|
||||
implementation: CommandImplementation;
|
||||
}
|
||||
|
||||
export class MultiCommand extends Command {
|
||||
|
||||
private readonly _implementations: [number, CommandImplementation][] = [];
|
||||
private readonly _implementations: ICommandImplementationRegistration[] = [];
|
||||
|
||||
/**
|
||||
* A higher priority gets to be looked at first
|
||||
*/
|
||||
public addImplementation(priority: number, implementation: CommandImplementation): IDisposable {
|
||||
this._implementations.push([priority, implementation]);
|
||||
this._implementations.sort((a, b) => b[0] - a[0]);
|
||||
public addImplementation(priority: number, name: string, implementation: CommandImplementation): IDisposable {
|
||||
this._implementations.push({ priority, name, implementation });
|
||||
this._implementations.sort((a, b) => b.priority - a.priority);
|
||||
return {
|
||||
dispose: () => {
|
||||
for (let i = 0; i < this._implementations.length; i++) {
|
||||
if (this._implementations[i][1] === implementation) {
|
||||
if (this._implementations[i].implementation === implementation) {
|
||||
this._implementations.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
|
@ -172,9 +179,11 @@ export class MultiCommand extends Command {
|
|||
}
|
||||
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void | Promise<void> {
|
||||
const logService = accessor.get(ILogService);
|
||||
for (const impl of this._implementations) {
|
||||
const result = impl[1](accessor, args);
|
||||
const result = impl.implementation(accessor, args);
|
||||
if (result) {
|
||||
logService.trace(`Command '${this.id}' was handled by '${impl.name}'.`);
|
||||
if (typeof result === 'boolean') {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ function registerExecCommandImpl(target: MultiCommand | undefined, browserComman
|
|||
}
|
||||
|
||||
// 1. handle case when focus is in editor.
|
||||
target.addImplementation(10000, (accessor: ServicesAccessor, args: any) => {
|
||||
target.addImplementation(10000, 'code-editor', (accessor: ServicesAccessor, args: any) => {
|
||||
// Only if editor text focus (i.e. not if editor has widget focus).
|
||||
const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
if (focusedEditor && focusedEditor.hasTextFocus()) {
|
||||
|
@ -186,7 +186,7 @@ function registerExecCommandImpl(target: MultiCommand | undefined, browserComman
|
|||
});
|
||||
|
||||
// 2. (default) handle case when focus is somewhere else.
|
||||
target.addImplementation(0, (accessor: ServicesAccessor, args: any) => {
|
||||
target.addImplementation(0, 'generic-dom', (accessor: ServicesAccessor, args: any) => {
|
||||
document.execCommand(browserCommand);
|
||||
return true;
|
||||
});
|
||||
|
@ -197,7 +197,7 @@ registerExecCommandImpl(CopyAction, 'copy');
|
|||
|
||||
if (PasteAction) {
|
||||
// 1. Paste: handle case when focus is in editor.
|
||||
PasteAction.addImplementation(10000, (accessor: ServicesAccessor, args: any) => {
|
||||
PasteAction.addImplementation(10000, 'code-editor', (accessor: ServicesAccessor, args: any) => {
|
||||
const codeEditorService = accessor.get(ICodeEditorService);
|
||||
const clipboardService = accessor.get(IClipboardService);
|
||||
|
||||
|
@ -235,7 +235,7 @@ if (PasteAction) {
|
|||
});
|
||||
|
||||
// 2. Paste: (default) handle case when focus is somewhere else.
|
||||
PasteAction.addImplementation(0, (accessor: ServicesAccessor, args: any) => {
|
||||
PasteAction.addImplementation(0, 'generic-dom', (accessor: ServicesAccessor, args: any) => {
|
||||
document.execCommand('paste');
|
||||
return true;
|
||||
});
|
||||
|
|
|
@ -83,10 +83,10 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
|
|||
}));
|
||||
|
||||
const PRIORITY = 105;
|
||||
this._register(UndoCommand.addImplementation(PRIORITY, () => {
|
||||
this._register(UndoCommand.addImplementation(PRIORITY, 'custom-editor', () => {
|
||||
return this.withActiveCustomEditor(editor => editor.undo());
|
||||
}));
|
||||
this._register(RedoCommand.addImplementation(PRIORITY, () => {
|
||||
this._register(RedoCommand.addImplementation(PRIORITY, 'custom-editor', () => {
|
||||
return this.withActiveCustomEditor(editor => editor.redo());
|
||||
}));
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ CommandsRegistry.registerCommand({
|
|||
});
|
||||
|
||||
function overrideActionForActiveExtensionEditorWebview(command: MultiCommand | undefined, f: (webview: Webview) => void) {
|
||||
command?.addImplementation(105, (accessor) => {
|
||||
command?.addImplementation(105, 'extensions-editor', (accessor) => {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const editor = editorService.activeEditorPane;
|
||||
if (editor instanceof ExtensionEditor) {
|
||||
|
|
|
@ -389,7 +389,7 @@ configurationRegistry.registerConfiguration({
|
|||
}
|
||||
});
|
||||
|
||||
UndoCommand.addImplementation(110, (accessor: ServicesAccessor) => {
|
||||
UndoCommand.addImplementation(110, 'explorer', (accessor: ServicesAccessor) => {
|
||||
const undoRedoService = accessor.get(IUndoRedoService);
|
||||
const explorerService = accessor.get(IExplorerService);
|
||||
if (explorerService.hasViewFocus() && undoRedoService.canUndo(UNDO_REDO_SOURCE)) {
|
||||
|
@ -400,7 +400,7 @@ UndoCommand.addImplementation(110, (accessor: ServicesAccessor) => {
|
|||
return false;
|
||||
});
|
||||
|
||||
RedoCommand.addImplementation(110, (accessor: ServicesAccessor) => {
|
||||
RedoCommand.addImplementation(110, 'explorer', (accessor: ServicesAccessor) => {
|
||||
const undoRedoService = accessor.get(IUndoRedoService);
|
||||
const explorerService = accessor.get(IExplorerService);
|
||||
if (explorerService.hasViewFocus() && undoRedoService.canRedo(UNDO_REDO_SOURCE)) {
|
||||
|
|
|
@ -43,7 +43,7 @@ class NotebookClipboardContribution extends Disposable {
|
|||
const PRIORITY = 105;
|
||||
|
||||
if (CopyAction) {
|
||||
this._register(CopyAction.addImplementation(PRIORITY, accessor => {
|
||||
this._register(CopyAction.addImplementation(PRIORITY, 'notebook-clipboard', accessor => {
|
||||
const activeElement = <HTMLElement>document.activeElement;
|
||||
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
|
||||
return false;
|
||||
|
@ -80,7 +80,7 @@ class NotebookClipboardContribution extends Disposable {
|
|||
}
|
||||
|
||||
if (PasteAction) {
|
||||
PasteAction.addImplementation(PRIORITY, accessor => {
|
||||
PasteAction.addImplementation(PRIORITY, 'notebook-clipboard', accessor => {
|
||||
const activeElement = <HTMLElement>document.activeElement;
|
||||
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
|
||||
return false;
|
||||
|
@ -137,7 +137,7 @@ class NotebookClipboardContribution extends Disposable {
|
|||
}
|
||||
|
||||
if (CutAction) {
|
||||
CutAction.addImplementation(PRIORITY, accessor => {
|
||||
CutAction.addImplementation(PRIORITY, 'notebook-clipboard', accessor => {
|
||||
const activeElement = <HTMLElement>document.activeElement;
|
||||
if (activeElement && ['input', 'textarea'].indexOf(activeElement.tagName.toLowerCase()) >= 0) {
|
||||
return false;
|
||||
|
|
|
@ -18,7 +18,7 @@ class NotebookUndoRedoContribution extends Disposable {
|
|||
super();
|
||||
|
||||
const PRIORITY = 105;
|
||||
this._register(UndoCommand.addImplementation(PRIORITY, () => {
|
||||
this._register(UndoCommand.addImplementation(PRIORITY, 'notebook-undo-redo', () => {
|
||||
const editor = getNotebookEditorFromEditorPane(this._editorService.activeEditorPane);
|
||||
if (editor?.viewModel) {
|
||||
return editor.viewModel.undo().then(cellResources => {
|
||||
|
@ -37,7 +37,7 @@ class NotebookUndoRedoContribution extends Disposable {
|
|||
return false;
|
||||
}));
|
||||
|
||||
this._register(RedoCommand.addImplementation(PRIORITY, () => {
|
||||
this._register(RedoCommand.addImplementation(PRIORITY, 'notebook-undo-redo', () => {
|
||||
const editor = getNotebookEditorFromEditorPane(this._editorService.activeEditorPane);
|
||||
if (editor?.viewModel) {
|
||||
return editor.viewModel.redo().then(cellResources => {
|
||||
|
|
|
@ -39,23 +39,23 @@ function withWebview(accessor: ServicesAccessor, f: (webviewe: ElectronWebviewBa
|
|||
|
||||
const PRIORITY = 105;
|
||||
|
||||
UndoCommand.addImplementation(PRIORITY, accessor => {
|
||||
UndoCommand.addImplementation(PRIORITY, 'notebook-webview', accessor => {
|
||||
return withWebview(accessor, webview => webview.undo());
|
||||
});
|
||||
|
||||
RedoCommand.addImplementation(PRIORITY, accessor => {
|
||||
RedoCommand.addImplementation(PRIORITY, 'notebook-webview', accessor => {
|
||||
return withWebview(accessor, webview => webview.redo());
|
||||
});
|
||||
|
||||
CopyAction?.addImplementation(PRIORITY, accessor => {
|
||||
CopyAction?.addImplementation(PRIORITY, 'notebook-webview', accessor => {
|
||||
return withWebview(accessor, webview => webview.copy());
|
||||
});
|
||||
|
||||
PasteAction?.addImplementation(PRIORITY, accessor => {
|
||||
PasteAction?.addImplementation(PRIORITY, 'notebook-webview', accessor => {
|
||||
return withWebview(accessor, webview => webview.paste());
|
||||
});
|
||||
|
||||
CutAction?.addImplementation(PRIORITY, accessor => {
|
||||
CutAction?.addImplementation(PRIORITY, 'notebook-webview', accessor => {
|
||||
return withWebview(accessor, webview => webview.cut());
|
||||
});
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/browser/w
|
|||
const PRIORITY = 100;
|
||||
|
||||
function overrideCommandForWebview(command: MultiCommand | undefined, f: (webview: Webview) => void) {
|
||||
command?.addImplementation(PRIORITY, accessor => {
|
||||
command?.addImplementation(PRIORITY, 'webiew', accessor => {
|
||||
const webviewService = accessor.get(IWebviewService);
|
||||
const webview = webviewService.activeWebview;
|
||||
if (webview?.isFocused) {
|
||||
|
|
Loading…
Reference in a new issue