From 8311f7559d327285f23690a6411cecadefa3174f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:48:19 -0700 Subject: [PATCH 01/16] Add wrapper function for concise terminal actions --- .../terminal/browser/terminalActions.ts | 146 +++++++++++------- 1 file changed, 86 insertions(+), 60 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 21057d4cb12e0..57eebed301c9a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -16,7 +16,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { EndOfLinePreference } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; -import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; +import { Action2, registerAction2, IAction2Options } from 'vs/platform/actions/common/actions'; import { ICommandActionTitle } from 'vs/platform/action/common/action'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -35,7 +35,7 @@ import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/edito import { ResourceContextKey } from 'vs/workbench/common/contextkeys'; import { Direction, ICreateTerminalOptions, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess'; -import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, ITerminalProfileService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, ITerminalProfileResolverService, ITerminalProfileService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { createProfileSchemaEnums } from 'vs/platform/terminal/common/terminalProfiles'; import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; @@ -128,48 +128,81 @@ export class TerminalLaunchHelpAction extends Action { } } -export function registerTerminalActions() { +/** + * A wrapper function around registerAction2 to help make registering terminal actions more concise. + * The following default options are used if undefined: + * + * - `f1`: true + * - `category`: Terminal + * - `precondition`: TerminalContextKeys.processSupported + */ +function registerTerminalAction( + options: IAction2Options & { run: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } +): void { + // Set defaults + options.f1 = options.f1 ?? true; + options.category = options.category ?? category; + options.precondition = options.precondition ?? TerminalContextKeys.processSupported; + // Remove run function from options so it's not passed through to registerAction2 + const runFunc = options.run; + const strictOptions: IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } = options; + delete (strictOptions as IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise })['run']; + // Register registerAction2(class extends Action2 { constructor() { - super({ - id: TerminalCommandId.NewInActiveWorkspace, - title: { value: localize('workbench.action.terminal.newInActiveWorkspace', "Create New Terminal (In Active Workspace)"), original: 'Create New Terminal (In Active Workspace)' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); + super(strictOptions as IAction2Options); } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); - if (terminalService.isProcessSupportRegistered) { - const instance = await terminalService.createTerminal({ location: terminalService.defaultLocation }); + run(accessor: ServicesAccessor, args?: unknown) { + return runFunc(getTerminalServices(accessor), accessor, args); + } + }); +} + +interface ITerminalServicesCollection { + service: ITerminalService; + groupService: ITerminalGroupService; + instanceService: ITerminalInstanceService; + editorService: ITerminalEditorService; + profileService: ITerminalProfileService; + profileResolverService: ITerminalProfileResolverService; +} + +function getTerminalServices(accessor: ServicesAccessor): ITerminalServicesCollection { + return { + service: accessor.get(ITerminalService), + groupService: accessor.get(ITerminalGroupService), + instanceService: accessor.get(ITerminalInstanceService), + editorService: accessor.get(ITerminalEditorService), + profileService: accessor.get(ITerminalProfileService), + profileResolverService: accessor.get(ITerminalProfileResolverService) + }; +} + +export function registerTerminalActions() { + registerTerminalAction({ + id: TerminalCommandId.NewInActiveWorkspace, + title: { value: localize('workbench.action.terminal.newInActiveWorkspace', "Create New Terminal (In Active Workspace)"), original: 'Create New Terminal (In Active Workspace)' }, + run: async (c) => { + if (c.service.isProcessSupportRegistered) { + const instance = await c.service.createTerminal({ location: c.service.defaultLocation }); if (!instance) { return; } - terminalService.setActiveInstance(instance); + c.service.setActiveInstance(instance); } - await terminalGroupService.showPanel(true); + await c.groupService.showPanel(true); } }); // Register new with profile command refreshTerminalActions([]); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CreateTerminalEditor, - title: { value: localize('workbench.action.terminal.createTerminalEditor', "Create New Terminal in Editor Area"), original: 'Create New Terminal in Editor Area' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor, args?: unknown) { - const terminalService = accessor.get(ITerminalService); + registerTerminalAction({ + id: TerminalCommandId.CreateTerminalEditor, + title: { value: localize('workbench.action.terminal.createTerminalEditor', "Create New Terminal in Editor Area"), original: 'Create New Terminal in Editor Area' }, + run: async (c, _, args) => { const options = (typeof args === 'object' && args && 'location' in args) ? args as ICreateTerminalOptions : { location: TerminalLocation.Editor }; - const instance = await terminalService.createTerminal(options); + const instance = await c.service.createTerminal(options); instance.focusWhenReady(); } }); @@ -315,40 +348,33 @@ export function registerTerminalActions() { await terminalGroupService.showPanel(true); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.RunRecentCommand, - title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: [ - { - primary: KeyMod.CtrlCmd | KeyCode.KeyR, - mac: { primary: KeyMod.WinCtrl | KeyCode.KeyR }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), - weight: KeybindingWeight.WorkbenchContrib - }, - { - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyR, - mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyR }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), - weight: KeybindingWeight.WorkbenchContrib - } - ] - }); - } - async run(accessor: ServicesAccessor): Promise { - const terminalGroupService = accessor.get(ITerminalGroupService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const instance = accessor.get(ITerminalService).activeInstance; + + registerTerminalAction({ + id: TerminalCommandId.RunRecentCommand, + title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: [ + { + primary: KeyMod.CtrlCmd | KeyCode.KeyR, + mac: { primary: KeyMod.WinCtrl | KeyCode.KeyR }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED), + weight: KeybindingWeight.WorkbenchContrib + }, + { + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyR, + mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyR }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + weight: KeybindingWeight.WorkbenchContrib + } + ], + run: async (c) => { + const instance = c.service.activeInstance; if (instance) { await instance.runRecent('command'); if (instance?.target === TerminalLocation.Editor) { - await terminalEditorService.revealActiveEditor(); + await c.editorService.revealActiveEditor(); } else { - await terminalGroupService.showPanel(false); + await c.groupService.showPanel(false); } } } From 032d76f3008d5d2fee017fc0a4999c5838dd63a3 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 07:50:27 -0700 Subject: [PATCH 02/16] Convert remaining simple actions in terminalActions --- .../terminal/browser/terminalActions.ts | 2450 +++++++---------- 1 file changed, 995 insertions(+), 1455 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 57eebed301c9a..6a251f04ade17 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -17,7 +17,6 @@ import { EndOfLinePreference } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2, IAction2Options } from 'vs/platform/actions/common/actions'; -import { ICommandActionTitle } from 'vs/platform/action/common/action'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -207,145 +206,100 @@ export function registerTerminalActions() { } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CreateTerminalEditorSide, - title: { value: localize('workbench.action.terminal.createTerminalEditorSide', "Create New Terminal in Editor Area to the Side"), original: 'Create New Terminal in Editor Area to the Side' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const instance = await terminalService.createTerminal({ + registerTerminalAction({ + id: TerminalCommandId.CreateTerminalEditorSide, + title: { value: localize('workbench.action.terminal.createTerminalEditorSide', "Create New Terminal in Editor Area to the Side"), original: 'Create New Terminal in Editor Area to the Side' }, + run: async (c) => { + const instance = await c.service.createTerminal({ location: { viewColumn: SIDE_GROUP } }); instance.focusWhenReady(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.MoveToEditor, - title: terminalStrings.moveToEditor, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive.toNegated(), TerminalContextKeys.viewShowing) - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - terminalService.doWithActiveInstance(instance => terminalService.moveToEditor(instance)); + registerTerminalAction({ + id: TerminalCommandId.MoveToEditor, + title: terminalStrings.moveToEditor, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive.toNegated(), TerminalContextKeys.viewShowing), + run: (c) => { + c.service.doWithActiveInstance(instance => c.service.moveToEditor(instance)); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.MoveToEditorInstance, - title: terminalStrings.moveToEditor, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen) - }); - } - async run(accessor: ServicesAccessor) { + registerTerminalAction({ + id: TerminalCommandId.MoveToEditorInstance, + title: terminalStrings.moveToEditor, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + run: async (c, accessor) => { const selectedInstances = getSelectedInstances(accessor); if (!selectedInstances || selectedInstances.length === 0) { return; } - const terminalService = accessor.get(ITerminalService); for (const instance of selectedInstances) { - terminalService.moveToEditor(instance); + c.service.moveToEditor(instance); } selectedInstances[selectedInstances.length - 1].focus(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.MoveToTerminalPanel, - title: terminalStrings.moveToTerminalPanel, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive), - }); - } - async run(accessor: ServicesAccessor, resource: unknown) { - const castedResource = URI.isUri(resource) ? resource : undefined; - await accessor.get(ITerminalService).moveToTerminalView(castedResource); + registerTerminalAction({ + id: TerminalCommandId.MoveToTerminalPanel, + title: terminalStrings.moveToTerminalPanel, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive), + run: async (c, _, args: unknown) => { + const resource = URI.isUri(args) ? args : undefined; + await c.service.moveToTerminalView(resource); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ShowTabs, - title: { value: localize('workbench.action.terminal.showTabs', "Show Tabs"), original: 'Show Tabs' }, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).showTabs(); + registerTerminalAction({ + id: TerminalCommandId.ShowTabs, + title: { value: localize('workbench.action.terminal.showTabs', "Show Tabs"), original: 'Show Tabs' }, + f1: false, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.showTabs(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusPreviousPane, - title: { value: localize('workbench.action.terminal.focusPreviousPane', "Focus Previous Terminal in Terminal Group"), original: 'Focus Previous Terminal in Terminal Group' }, - f1: true, - category, - keybinding: { - primary: KeyMod.Alt | KeyCode.LeftArrow, - secondary: [KeyMod.Alt | KeyCode.UpArrow], - mac: { - primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.LeftArrow, - secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.UpArrow] - }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); - terminalGroupService.activeGroup?.focusPreviousPane(); - await terminalGroupService.showPanel(true); + registerTerminalAction({ + id: TerminalCommandId.FocusPreviousPane, + title: { value: localize('workbench.action.terminal.focusPreviousPane', "Focus Previous Terminal in Terminal Group"), original: 'Focus Previous Terminal in Terminal Group' }, + keybinding: { + primary: KeyMod.Alt | KeyCode.LeftArrow, + secondary: [KeyMod.Alt | KeyCode.UpArrow], + mac: { + primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.LeftArrow, + secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.UpArrow] + }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.groupService.activeGroup?.focusPreviousPane(); + await c.groupService.showPanel(true); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusNextPane, - title: { value: localize('workbench.action.terminal.focusNextPane', "Focus Next Terminal in Terminal Group"), original: 'Focus Next Terminal in Terminal Group' }, - f1: true, - category, - keybinding: { - primary: KeyMod.Alt | KeyCode.RightArrow, - secondary: [KeyMod.Alt | KeyCode.DownArrow], - mac: { - primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.RightArrow, - secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.DownArrow] - }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); - terminalGroupService.activeGroup?.focusNextPane(); - await terminalGroupService.showPanel(true); + + registerTerminalAction({ + id: TerminalCommandId.FocusNextPane, + title: { value: localize('workbench.action.terminal.focusNextPane', "Focus Next Terminal in Terminal Group"), original: 'Focus Next Terminal in Terminal Group' }, + keybinding: { + primary: KeyMod.Alt | KeyCode.RightArrow, + secondary: [KeyMod.Alt | KeyCode.DownArrow], + mac: { + primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.RightArrow, + secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.DownArrow] + }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.groupService.activeGroup?.focusNextPane(); + await c.groupService.showPanel(true); } }); @@ -379,18 +333,14 @@ export function registerTerminalActions() { } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CopyLastCommandOutput, - title: { value: localize('workbench.action.terminal.copyLastCommand', 'Copy Last Command Output'), original: 'Copy Last Command Output' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor): Promise { - const instance = accessor.get(ITerminalService).activeInstance; + + registerTerminalAction({ + id: TerminalCommandId.CopyLastCommandOutput, + title: { value: localize('workbench.action.terminal.copyLastCommand', 'Copy Last Command Output'), original: 'Copy Last Command Output' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { + const clipboardService = accessor.get(IClipboardService); + const instance = c.service.activeInstance; const commands = instance?.capabilities.get(TerminalCapability.CommandDetection)?.commands; if (!commands || commands.length === 0) { return; @@ -401,222 +351,161 @@ export function registerTerminalActions() { } const output = command.getOutput(); if (output && typeof output === 'string') { - await accessor.get(IClipboardService).writeText(output); + await clipboardService.writeText(output); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.GoToRecentDirectory, - title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.KeyG, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - async run(accessor: ServicesAccessor): Promise { - const terminalGroupService = accessor.get(ITerminalGroupService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const instance = accessor.get(ITerminalService).activeInstance; + + registerTerminalAction({ + id: TerminalCommandId.GoToRecentDirectory, + title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.KeyG, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + run: async (c) => { + const instance = c.service.activeInstance; if (instance) { await instance.runRecent('cwd'); if (instance?.target === TerminalLocation.Editor) { - await terminalEditorService.revealActiveEditor(); + await c.editorService.revealActiveEditor(); } else { - await terminalGroupService.showPanel(false); + await c.groupService.showPanel(false); } } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ResizePaneLeft, - title: { value: localize('workbench.action.terminal.resizePaneLeft', "Resize Terminal Left"), original: 'Resize Terminal Left' }, - f1: true, - category, - keybinding: { - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).activeGroup?.resizePane(Direction.Left); + + registerTerminalAction({ + id: TerminalCommandId.ResizePaneLeft, + title: { value: localize('workbench.action.terminal.resizePaneLeft', "Resize Terminal Left"), original: 'Resize Terminal Left' }, + keybinding: { + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.activeGroup?.resizePane(Direction.Left); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ResizePaneRight, - title: { value: localize('workbench.action.terminal.resizePaneRight', "Resize Terminal Right"), original: 'Resize Terminal Right' }, - f1: true, - category, - keybinding: { - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).activeGroup?.resizePane(Direction.Right); + + registerTerminalAction({ + id: TerminalCommandId.ResizePaneRight, + title: { value: localize('workbench.action.terminal.resizePaneRight', "Resize Terminal Right"), original: 'Resize Terminal Right' }, + keybinding: { + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.activeGroup?.resizePane(Direction.Right); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ResizePaneUp, - title: { value: localize('workbench.action.terminal.resizePaneUp', "Resize Terminal Up"), original: 'Resize Terminal Up' }, - f1: true, - category, - keybinding: { - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).activeGroup?.resizePane(Direction.Up); + + registerTerminalAction({ + id: TerminalCommandId.ResizePaneUp, + title: { value: localize('workbench.action.terminal.resizePaneUp', "Resize Terminal Up"), original: 'Resize Terminal Up' }, + keybinding: { + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.activeGroup?.resizePane(Direction.Up); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ResizePaneDown, - title: { value: localize('workbench.action.terminal.resizePaneDown', "Resize Terminal Down"), original: 'Resize Terminal Down' }, - f1: true, - category, - keybinding: { - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow }, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).activeGroup?.resizePane(Direction.Down); + + registerTerminalAction({ + id: TerminalCommandId.ResizePaneDown, + title: { value: localize('workbench.action.terminal.resizePaneDown', "Resize Terminal Down"), original: 'Resize Terminal Down' }, + keybinding: { + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow }, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.activeGroup?.resizePane(Direction.Down); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Focus, - title: terminalStrings.focus, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); - const instance = terminalService.activeInstance || await terminalService.createTerminal({ location: TerminalLocation.Panel }); + + registerTerminalAction({ + id: TerminalCommandId.Focus, + title: terminalStrings.focus, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + const instance = c.service.activeInstance || await c.service.createTerminal({ location: TerminalLocation.Panel }); if (!instance) { return; } - terminalService.setActiveInstance(instance); - return terminalGroupService.showPanel(true); + c.service.setActiveInstance(instance); + return c.groupService.showPanel(true); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusTabs, - title: { value: localize('workbench.action.terminal.focus.tabsView', "Focus Terminal Tabs View"), original: 'Focus Terminal Tabs View' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backslash, - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus), - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).focusTabs(); + + registerTerminalAction({ + id: TerminalCommandId.FocusTabs, + title: { value: localize('workbench.action.terminal.focus.tabsView', "Focus Terminal Tabs View"), original: 'Focus Terminal Tabs View' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backslash, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus), + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.groupService.focusTabs(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusNext, - title: { value: localize('workbench.action.terminal.focusNext', "Focus Next Terminal Group"), original: 'Focus Next Terminal Group' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.PageDown, - mac: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.BracketRight - }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.editorFocus.negate()), - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); - terminalGroupService.setActiveGroupToNext(); - await terminalGroupService.showPanel(true); + + registerTerminalAction({ + id: TerminalCommandId.FocusNext, + title: { value: localize('workbench.action.terminal.focusNext', "Focus Next Terminal Group"), original: 'Focus Next Terminal Group' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.PageDown, + mac: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.BracketRight + }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.editorFocus.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + run: async (c) => { + c.groupService.setActiveGroupToNext(); + await c.groupService.showPanel(true); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusPrevious, - title: { value: localize('workbench.action.terminal.focusPrevious', "Focus Previous Terminal Group"), original: 'Focus Previous Terminal Group' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.PageUp, - mac: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.BracketLeft - }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.editorFocus.negate()), - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); - terminalGroupService.setActiveGroupToPrevious(); - await terminalGroupService.showPanel(true); + + registerTerminalAction({ + id: TerminalCommandId.FocusPrevious, + title: { value: localize('workbench.action.terminal.focusPrevious', "Focus Previous Terminal Group"), original: 'Focus Previous Terminal Group' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.PageUp, + mac: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.BracketLeft + }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.editorFocus.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + run: async (c) => { + c.groupService.setActiveGroupToPrevious(); + await c.groupService.showPanel(true); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.RunSelectedText, - title: { value: localize('workbench.action.terminal.runSelectedText', "Run Selected Text In Active Terminal"), original: 'Run Selected Text In Active Terminal' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); - const codeEditorService = accessor.get(ICodeEditorService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const instance = await terminalService.getActiveOrCreateInstance(); + registerTerminalAction({ + id: TerminalCommandId.RunSelectedText, + title: { value: localize('workbench.action.terminal.runSelectedText', "Run Selected Text In Active Terminal"), original: 'Run Selected Text In Active Terminal' }, + run: async (c, accessor) => { + const codeEditorService = accessor.get(ICodeEditorService); + const instance = await c.service.getActiveOrCreateInstance(); const editor = codeEditorService.getActiveCodeEditor(); if (!editor || !editor.hasModel()) { return; @@ -630,23 +519,15 @@ export function registerTerminalActions() { text = editor.getModel().getValueInRange(selection, endOfLinePreference); } instance.sendText(text, true, true); - await revealActiveTerminal(instance, terminalEditorService, terminalGroupService); + await revealActiveTerminal(instance, c.editorService, c.groupService); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.RunActiveFile, - title: { value: localize('workbench.action.terminal.runActiveFile', "Run Active File In Active Terminal"), original: 'Run Active File In Active Terminal' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); + + registerTerminalAction({ + id: TerminalCommandId.RunActiveFile, + title: { value: localize('workbench.action.terminal.runActiveFile', "Run Active File In Active Terminal"), original: 'Run Active File In Active Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { const codeEditorService = accessor.get(ICodeEditorService); const notificationService = accessor.get(INotificationService); const workbenchEnvironmentService = accessor.get(IWorkbenchEnvironmentService); @@ -656,13 +537,13 @@ export function registerTerminalActions() { return; } - let instance = terminalService.activeInstance; + let instance = c.service.activeInstance; // Don't use task terminals or other terminals that don't accept input if (instance?.xterm?.isStdinDisabled || instance?.shellLaunchConfig.type === 'Task') { - instance = await terminalService.createTerminal(); - terminalService.setActiveInstance(instance); - await revealActiveTerminal(instance, terminalEditorService, terminalGroupService); + instance = await c.service.createTerminal(); + c.service.setActiveInstance(instance); + await revealActiveTerminal(instance, c.editorService, c.groupService); } const isRemote = instance ? instance.isRemote : (workbenchEnvironmentService.remoteAuthority ? true : false); @@ -673,270 +554,202 @@ export function registerTerminalActions() { } if (!instance) { - instance = await terminalService.getActiveOrCreateInstance(); + instance = await c.service.getActiveOrCreateInstance(); } // TODO: Convert this to ctrl+c, ctrl+v for pwsh? await instance.sendPath(uri, true); - return terminalGroupService.showPanel(); + return c.groupService.showPanel(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollDownLine, - title: { value: localize('workbench.action.terminal.scrollDown', "Scroll Down (Line)"), original: 'Scroll Down (Line)' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollDownLine(); + + registerTerminalAction({ + id: TerminalCommandId.ScrollDownLine, + title: { value: localize('workbench.action.terminal.scrollDown', "Scroll Down (Line)"), original: 'Scroll Down (Line)' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.activeInstance?.scrollDownLine(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollDownPage, - title: { value: localize('workbench.action.terminal.scrollDownPage', "Scroll Down (Page)"), original: 'Scroll Down (Page)' }, - f1: true, - category, - keybinding: { - primary: KeyMod.Shift | KeyCode.PageDown, - mac: { primary: KeyCode.PageDown }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); + + registerTerminalAction({ + id: TerminalCommandId.ScrollDownPage, + title: { value: localize('workbench.action.terminal.scrollDownPage', "Scroll Down (Page)"), original: 'Scroll Down (Page)' }, + keybinding: { + primary: KeyMod.Shift | KeyCode.PageDown, + mac: { primary: KeyCode.PageDown }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.activeInstance?.scrollDownPage(); } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollDownPage(); + }); + + registerTerminalAction({ + id: TerminalCommandId.ScrollToBottom, + title: { value: localize('workbench.action.terminal.scrollToBottom', "Scroll to Bottom"), original: 'Scroll to Bottom' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.End, + linux: { primary: KeyMod.Shift | KeyCode.End }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.activeInstance?.scrollToBottom(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollToBottom, - title: { value: localize('workbench.action.terminal.scrollToBottom', "Scroll to Bottom"), original: 'Scroll to Bottom' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.End, - linux: { primary: KeyMod.Shift | KeyCode.End }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollToBottom(); - } - }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollUpLine, - title: { value: localize('workbench.action.terminal.scrollUp', "Scroll Up (Line)"), original: 'Scroll Up (Line)' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollUpLine(); + + registerTerminalAction({ + id: TerminalCommandId.ScrollUpLine, + title: { value: localize('workbench.action.terminal.scrollUp', "Scroll Up (Line)"), original: 'Scroll Up (Line)' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.activeInstance?.scrollUpLine(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollUpPage, - title: { value: localize('workbench.action.terminal.scrollUpPage', "Scroll Up (Page)"), original: 'Scroll Up (Page)' }, - f1: true, - category, - keybinding: { - primary: KeyMod.Shift | KeyCode.PageUp, - mac: { primary: KeyCode.PageUp }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollUpPage(); + + registerTerminalAction({ + id: TerminalCommandId.ScrollUpPage, + title: { value: localize('workbench.action.terminal.scrollUpPage', "Scroll Up (Page)"), original: 'Scroll Up (Page)' }, + f1: true, + category, + keybinding: { + primary: KeyMod.Shift | KeyCode.PageUp, + mac: { primary: KeyCode.PageUp }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.service.activeInstance?.scrollUpPage(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollToTop, - title: { value: localize('workbench.action.terminal.scrollToTop', "Scroll to Top"), original: 'Scroll to Top' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.Home, - linux: { primary: KeyMod.Shift | KeyCode.Home }, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.scrollToTop(); + + registerTerminalAction({ + id: TerminalCommandId.ScrollToTop, + title: { value: localize('workbench.action.terminal.scrollToTop', "Scroll to Top"), original: 'Scroll to Top' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.Home, + linux: { primary: KeyMod.Shift | KeyCode.Home }, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.altBufferActive.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.activeInstance?.scrollToTop(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ClearSelection, - title: { value: localize('workbench.action.terminal.clearSelection', "Clear Selection"), original: 'Clear Selection' }, - f1: true, - category, - keybinding: { - primary: KeyCode.Escape, - when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.textSelected, TerminalContextKeys.notFindVisible), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - const terminalInstance = accessor.get(ITerminalService).activeInstance; - if (terminalInstance && terminalInstance.hasSelection()) { - terminalInstance.clearSelection(); + + registerTerminalAction({ + id: TerminalCommandId.ClearSelection, + title: { value: localize('workbench.action.terminal.clearSelection', "Clear Selection"), original: 'Clear Selection' }, + keybinding: { + primary: KeyCode.Escape, + when: ContextKeyExpr.and(TerminalContextKeys.focus, TerminalContextKeys.textSelected, TerminalContextKeys.notFindVisible), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + const instance = c.service.activeInstance; + if (instance?.hasSelection()) { + instance.clearSelection(); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeIcon, - title: terminalStrings.changeIcon, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor, resource: unknown) { - getActiveInstance(accessor, resource)?.changeIcon(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeIcon, + title: terminalStrings.changeIcon, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor, args: unknown) => { + await getActiveInstance(accessor, args)?.changeIcon(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeIconPanel, - title: terminalStrings.changeIcon, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - return accessor.get(ITerminalGroupService).activeInstance?.changeIcon(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeIconPanel, + title: terminalStrings.changeIcon, + f1: false, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + await c.groupService.activeInstance?.changeIcon(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeIconInstance, - title: terminalStrings.changeIcon, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection) - }); - } - async run(accessor: ServicesAccessor) { - return getSelectedInstances(accessor)?.[0].changeIcon(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeIconInstance, + title: terminalStrings.changeIcon, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), + run: async (c, accessor) => { + await getSelectedInstances(accessor)?.[0].changeIcon(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeColor, - title: terminalStrings.changeColor, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor, resource: unknown) { - getActiveInstance(accessor, resource)?.changeColor(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeColor, + title: terminalStrings.changeColor, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor, args) => { + await getActiveInstance(accessor, args)?.changeColor(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeColorPanel, - title: terminalStrings.changeColor, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - return accessor.get(ITerminalGroupService).activeInstance?.changeColor(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeColorPanel, + title: terminalStrings.changeColor, + f1: false, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + await c.groupService.activeInstance?.changeColor(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ChangeColorInstance, - title: terminalStrings.changeColor, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection) - }); - } - async run(accessor: ServicesAccessor) { - return getSelectedInstances(accessor)?.[0].changeColor(); + + registerTerminalAction({ + id: TerminalCommandId.ChangeColorInstance, + title: terminalStrings.changeColor, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), + run: async (c, accessor) => { + await getSelectedInstances(accessor)?.[0].changeColor(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Rename, - title: terminalStrings.rename, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor, resource: unknown) { - renameWithQuickPick(accessor, resource); + registerTerminalAction({ + id: TerminalCommandId.Rename, + title: terminalStrings.rename, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor, args) => { + await renameWithQuickPick(accessor, args); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.RenamePanel, - title: terminalStrings.rename, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - renameWithQuickPick(accessor); + + registerTerminalAction({ + id: TerminalCommandId.RenamePanel, + title: terminalStrings.rename, + f1: false, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { + await renameWithQuickPick(accessor); } }); + // TODO: Use terminal service collection, move to bottom async function renameWithQuickPick(accessor: ServicesAccessor, resource?: unknown) { const instance = getActiveInstance(accessor, resource); if (instance) { @@ -948,40 +761,32 @@ export function registerTerminalActions() { } } - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.RenameInstance, - title: terminalStrings.rename, - f1: false, - category, - keybinding: { - primary: KeyCode.F2, - mac: { - primary: KeyCode.Enter - }, - when: ContextKeyExpr.and(TerminalContextKeys.tabsFocus), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); + registerTerminalAction({ + id: TerminalCommandId.RenameInstance, + title: terminalStrings.rename, + f1: false, + keybinding: { + primary: KeyCode.F2, + mac: { + primary: KeyCode.Enter + }, + when: ContextKeyExpr.and(TerminalContextKeys.tabsFocus), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), + run: async (c, accessor) => { const notificationService = accessor.get(INotificationService); - const instance = getSelectedInstances(accessor)?.[0]; if (!instance) { return; } - - terminalService.setEditingTerminal(instance); - terminalService.setEditable(instance, { + c.service.setEditingTerminal(instance); + c.service.setEditable(instance, { validationMessage: value => validateTerminalName(value), onFinish: async (value, success) => { // Cancel editing first as instance.rename will trigger a rerender automatically - terminalService.setEditable(instance, null); - terminalService.setEditingTerminal(undefined); + c.service.setEditable(instance, null); + c.service.setEditingTerminal(undefined); if (success) { try { await instance.rename(value); @@ -994,40 +799,22 @@ export function registerTerminalActions() { } }); - - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.DetachSession, - title: { value: localize('workbench.action.terminal.detachSession', "Detach Session"), original: 'Detach Session' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - await terminalService.activeInstance?.detachProcessAndDispose(TerminalExitReason.User); + registerTerminalAction({ + id: TerminalCommandId.DetachSession, + title: { value: localize('workbench.action.terminal.detachSession', "Detach Session"), original: 'Detach Session' }, + run: async (c) => { + c.service.activeInstance?.detachProcessAndDispose(TerminalExitReason.User); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.AttachToSession, - title: { value: localize('workbench.action.terminal.attachToSession', "Attach to Session"), original: 'Attach to Session' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { + + registerTerminalAction({ + id: TerminalCommandId.AttachToSession, + title: { value: localize('workbench.action.terminal.attachToSession', "Attach to Session"), original: 'Attach to Session' }, + run: async (c, accessor) => { const quickInputService = accessor.get(IQuickInputService); - const terminalService = accessor.get(ITerminalService); const labelService = accessor.get(ILabelService); const remoteAgentService = accessor.get(IRemoteAgentService); const notificationService = accessor.get(INotificationService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); const remoteAuthority = remoteAgentService.getConnection()?.remoteAuthority ?? undefined; const backend = await accessor.get(ITerminalInstanceService).getBackend(remoteAuthority); @@ -1040,7 +827,7 @@ export function registerTerminalActions() { backend.reduceConnectionGraceTime(); - const unattachedTerms = terms.filter(term => !terminalService.isAttachedToTerminal(term)); + const unattachedTerms = terms.filter(term => !c.service.isAttachedToTerminal(term)); const items = unattachedTerms.map(term => { const cwdLabel = labelService.getUriLabel(URI.file(term.cwd)); return { @@ -1056,441 +843,348 @@ export function registerTerminalActions() { } const selected = await quickInputService.pick(items, { canPickMany: false }); if (selected) { - const instance = await terminalService.createTerminal({ + const instance = await c.service.createTerminal({ config: { attachPersistentProcess: selected.term } }); - terminalService.setActiveInstance(instance); - await focusActiveTerminal(instance, terminalEditorService, terminalGroupService); + c.service.setActiveInstance(instance); + await focusActiveTerminal(instance, c.editorService, c.groupService); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.QuickOpenTerm, - title: { value: localize('quickAccessTerminal', "Switch Active Terminal"), original: 'Switch Active Terminal' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { + + registerTerminalAction({ + id: TerminalCommandId.QuickOpenTerm, + title: { value: localize('quickAccessTerminal', "Switch Active Terminal"), original: 'Switch Active Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c, accessor) => { accessor.get(IQuickInputService).quickAccess.show(TerminalQuickAccessProvider.PREFIX); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollToPreviousCommand, - title: { value: localize('workbench.action.terminal.scrollToPreviousCommand', "Scroll To Previous Command"), original: 'Scroll To Previous Command' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.UpArrow, - when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.ScrollToPreviousCommand, + title: { value: localize('workbench.action.terminal.scrollToPreviousCommand', "Scroll To Previous Command"), original: 'Scroll To Previous Command' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.UpArrow, + when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + // TODO: Change doWithActiveInstance pattern to use specialized registerTerminalAction + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.scrollToPreviousMark(undefined, undefined, t.capabilities.has(TerminalCapability.CommandDetection)); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ScrollToNextCommand, - title: { value: localize('workbench.action.terminal.scrollToNextCommand', "Scroll To Next Command"), original: 'Scroll To Next Command' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.DownArrow, - when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.ScrollToNextCommand, + title: { value: localize('workbench.action.terminal.scrollToNextCommand', "Scroll To Next Command"), original: 'Scroll To Next Command' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.DownArrow, + when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.scrollToNextMark(); t.focus(); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectToPreviousCommand, - title: { value: localize('workbench.action.terminal.selectToPreviousCommand', "Select To Previous Command"), original: 'Select To Previous Command' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.SelectToPreviousCommand, + title: { value: localize('workbench.action.terminal.selectToPreviousCommand', "Select To Previous Command"), original: 'Select To Previous Command' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.selectToPreviousMark(); t.focus(); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectToNextCommand, - title: { value: localize('workbench.action.terminal.selectToNextCommand', "Select To Next Command"), original: 'Select To Next Command' }, - f1: true, - category, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow, - when: TerminalContextKeys.focus, - weight: KeybindingWeight.WorkbenchContrib - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.SelectToNextCommand, + title: { value: localize('workbench.action.terminal.selectToNextCommand', "Select To Next Command"), original: 'Select To Next Command' }, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow, + when: TerminalContextKeys.focus, + weight: KeybindingWeight.WorkbenchContrib + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: (c) => { + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.selectToNextMark(); t.focus(); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectToPreviousLine, - title: { value: localize('workbench.action.terminal.selectToPreviousLine', "Select To Previous Line"), original: 'Select To Previous Line' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.SelectToPreviousLine, + title: { value: localize('workbench.action.terminal.selectToPreviousLine', "Select To Previous Line"), original: 'Select To Previous Line' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.selectToPreviousLine(); t.focus(); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectToNextLine, - title: { value: localize('workbench.action.terminal.selectToNextLine', "Select To Next Line"), original: 'Select To Next Line' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => { + + registerTerminalAction({ + id: TerminalCommandId.SelectToNextLine, + title: { value: localize('workbench.action.terminal.selectToNextLine', "Select To Next Line"), original: 'Select To Next Line' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + c.service.doWithActiveInstance(t => { t.xterm?.markTracker.selectToNextLine(); t.focus(); }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ToggleEscapeSequenceLogging, - title: { value: localize('workbench.action.terminal.toggleEscapeSequenceLogging', "Toggle Escape Sequence Logging"), original: 'Toggle Escape Sequence Logging' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - await terminalService.toggleEscapeSequenceLogging(); + + registerTerminalAction({ + id: TerminalCommandId.ToggleEscapeSequenceLogging, + title: { value: localize('workbench.action.terminal.toggleEscapeSequenceLogging', "Toggle Escape Sequence Logging"), original: 'Toggle Escape Sequence Logging' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + await c.service.toggleEscapeSequenceLogging(); } }); - registerAction2(class extends Action2 { - constructor() { - const title = localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"); - super({ - id: TerminalCommandId.SendSequence, - title: { value: title, original: 'Send Custom Sequence To Terminal' }, - category, - description: { - description: title, - args: [{ - name: 'args', - schema: { - type: 'object', - required: ['text'], - properties: { - text: { type: 'string' } - }, - } - }] - }, - precondition: TerminalContextKeys.processSupported - }); - } - run(accessor: ServicesAccessor, args?: { text?: string }) { - terminalSendSequenceCommand(accessor, args); + + registerTerminalAction({ + id: TerminalCommandId.SendSequence, + // TODO: Pull into terminalStrings + title: { value: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), original: 'Send Custom Sequence To Terminal' }, + description: { + description: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), + args: [{ + name: 'args', + schema: { + type: 'object', + required: ['text'], + properties: { + text: { type: 'string' } + }, + } + }] + }, + run: async (c, accessor, args) => { + // TODO: Come up with a nicer way to parse args + const sequence = args && typeof args === 'object' && 'text' in args ? args as { text?: string } : undefined; + terminalSendSequenceCommand(accessor, sequence); } }); - registerAction2(class extends Action2 { - constructor() { - const title = localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"); - super({ - id: TerminalCommandId.NewWithCwd, - title: { value: title, original: 'Create New Terminal Starting in a Custom Working Directory' }, - category, - description: { - description: title, - args: [{ - name: 'args', - schema: { - type: 'object', - required: ['cwd'], - properties: { - cwd: { - description: localize('workbench.action.terminal.newWithCwd.cwd', "The directory to start the terminal at"), - type: 'string' - } - }, + + registerTerminalAction({ + id: TerminalCommandId.NewWithCwd, + // TODO: Pull into terminalStrings + title: { value: localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"), original: 'Create New Terminal Starting in a Custom Working Directory' }, + description: { + description: localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"), + args: [{ + name: 'args', + schema: { + type: 'object', + required: ['cwd'], + properties: { + cwd: { + description: localize('workbench.action.terminal.newWithCwd.cwd', "The directory to start the terminal at"), + type: 'string' } - }] - }, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor, args?: { cwd?: string }) { - const terminalService = accessor.get(ITerminalService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); - if (terminalService.isProcessSupportRegistered) { - const instance = await terminalService.createTerminal({ - cwd: args?.cwd - }); - if (!instance) { - return; + }, } - terminalService.setActiveInstance(instance); - await focusActiveTerminal(instance, terminalEditorService, terminalGroupService); + }] + }, + run: async (c, _, args) => { + const cwd = args && typeof args === 'object' && 'cwd' in args && typeof args.cwd === 'string' ? args.cwd : undefined; + const instance = await c.service.createTerminal({ cwd }); + if (!instance) { + return; } + c.service.setActiveInstance(instance); + await focusActiveTerminal(instance, c.editorService, c.groupService); } }); - registerAction2(class extends Action2 { - constructor() { - const title = localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"); - super({ - id: TerminalCommandId.RenameWithArgs, - title: { value: title, original: 'Rename the Currently Active Terminal' }, - category, - description: { - description: title, - args: [{ - name: 'args', - schema: { - type: 'object', - required: ['name'], - properties: { - name: { - description: localize('workbench.action.terminal.renameWithArg.name', "The new name for the terminal"), - type: 'string', - minLength: 1 - } - } + + registerTerminalAction({ + id: TerminalCommandId.RenameWithArgs, + // TODO: Move to terminalStrings + title: { value: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), original: 'Rename the Currently Active Terminal' }, + description: { + description: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), + args: [{ + name: 'args', + schema: { + type: 'object', + required: ['name'], + properties: { + name: { + description: localize('workbench.action.terminal.renameWithArg.name', "The new name for the terminal"), + type: 'string', + minLength: 1 } - }] - }, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor, args?: { name?: string }) { + } + } + }] + }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor, args) => { const notificationService = accessor.get(INotificationService); - if (!args?.name) { + const name = args && typeof args === 'object' && 'name' in args && typeof args.name === 'string' ? args.name : undefined; + if (!name) { notificationService.warn(localize('workbench.action.terminal.renameWithArg.noName', "No name argument provided")); return; } - accessor.get(ITerminalService).activeInstance?.rename(args.name); + c.service.activeInstance?.rename(name); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Relaunch, - title: { value: localize('workbench.action.terminal.relaunch', "Relaunch Active Terminal"), original: 'Relaunch Active Terminal' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.relaunch(); + + registerTerminalAction({ + id: TerminalCommandId.Relaunch, + title: { value: localize('workbench.action.terminal.relaunch', "Relaunch Active Terminal"), original: 'Relaunch Active Terminal' }, + run: async (c) => { + c.service.activeInstance?.relaunch(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Split, - title: terminalStrings.split, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.webExtensionContributedProfile), - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Digit5, - weight: KeybindingWeight.WorkbenchContrib, - mac: { - primary: KeyMod.CtrlCmd | KeyCode.Backslash, - secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Digit5] - }, - when: TerminalContextKeys.focus - }, - icon: Codicon.splitHorizontal, - description: { - description: 'workbench.action.terminal.split', - args: [{ - name: 'profile', - schema: { - type: 'object' - } - }] + + registerTerminalAction({ + id: TerminalCommandId.Split, + title: terminalStrings.split, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.webExtensionContributedProfile), + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Digit5, + weight: KeybindingWeight.WorkbenchContrib, + mac: { + primary: KeyMod.CtrlCmd | KeyCode.Backslash, + secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Digit5] + }, + when: TerminalContextKeys.focus + }, + icon: Codicon.splitHorizontal, + description: { + // TODO: This is meant to be a localized string? Is this used anywhere? + description: 'workbench.action.terminal.split', + args: [{ + name: 'profile', + schema: { + type: 'object' } - }); - } - async run(accessor: ServicesAccessor, optionsOrProfile?: ICreateTerminalOptions | ITerminalProfile) { + }] + }, + run: async (c, accessor, args) => { + // TODO: Validate arg shape + const optionsOrProfile = args as ICreateTerminalOptions | ITerminalProfile | undefined; const commandService = accessor.get(ICommandService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); - const terminalService = accessor.get(ITerminalService); const workspaceContextService = accessor.get(IWorkspaceContextService); const options = convertOptionsOrProfileToOptions(optionsOrProfile); - const activeInstance = terminalService.getInstanceHost(options?.location).activeInstance; + const activeInstance = c.service.getInstanceHost(options?.location).activeInstance; if (!activeInstance) { return; } - const cwd = await getCwdForSplit(terminalService.configHelper, activeInstance, workspaceContextService.getWorkspace().folders, commandService); + const cwd = await getCwdForSplit(c.service.configHelper, activeInstance, workspaceContextService.getWorkspace().folders, commandService); if (cwd === undefined) { return; } - const instance = await terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); - await focusActiveTerminal(instance, terminalEditorService, terminalGroupService); + const instance = await c.service.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); + await focusActiveTerminal(instance, c.editorService, c.groupService); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SplitInstance, - title: terminalStrings.split, - f1: false, - category, - precondition: TerminalContextKeys.processSupported, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Digit5, - mac: { - primary: KeyMod.CtrlCmd | KeyCode.Backslash, - secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Digit5] - }, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.tabsFocus - } - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); + + registerTerminalAction({ + id: TerminalCommandId.SplitInstance, + title: terminalStrings.split, + f1: false, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Digit5, + mac: { + primary: KeyMod.CtrlCmd | KeyCode.Backslash, + secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Digit5] + }, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.tabsFocus + }, + run: async (c, accessor) => { const instances = getSelectedInstances(accessor); if (instances) { for (const t of instances) { - terminalService.setActiveInstance(t); - terminalService.doWithActiveInstance(async instance => { - await terminalService.createTerminal({ location: { parentTerminal: instance } }); - await terminalGroupService.showPanel(true); + c.service.setActiveInstance(t); + // TODO: This should await??? + c.service.doWithActiveInstance(async instance => { + await c.service.createTerminal({ location: { parentTerminal: instance } }); + await c.groupService.showPanel(true); }); } } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Unsplit, - title: terminalStrings.unsplit, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(async t => accessor.get(ITerminalGroupService).unsplitInstance(t)); + + registerTerminalAction({ + id: TerminalCommandId.Unsplit, + title: terminalStrings.unsplit, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c) => { + await c.service.doWithActiveInstance(async t => c.groupService.unsplitInstance(t)); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.UnsplitInstance, - title: terminalStrings.unsplit, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); + + registerTerminalAction({ + id: TerminalCommandId.UnsplitInstance, + title: terminalStrings.unsplit, + f1: false, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { const instances = getSelectedInstances(accessor); // should not even need this check given the context key // but TS complains if (instances?.length === 1) { - const group = terminalGroupService.getGroupForInstance(instances[0]); + const group = c.groupService.getGroupForInstance(instances[0]); if (group && group?.terminalInstances.length > 1) { - terminalGroupService.unsplitInstance(instances[0]); + c.groupService.unsplitInstance(instances[0]); } } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.JoinInstance, - title: { value: localize('workbench.action.terminal.joinInstance', "Join Terminals"), original: 'Join Terminals' }, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection.toNegated()) - }); - } - async run(accessor: ServicesAccessor) { + + registerTerminalAction({ + id: TerminalCommandId.JoinInstance, + title: { value: localize('workbench.action.terminal.joinInstance', "Join Terminals"), original: 'Join Terminals' }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection.toNegated()), + run: async (c, accessor) => { const instances = getSelectedInstances(accessor); if (instances && instances.length > 1) { - accessor.get(ITerminalGroupService).joinInstances(instances); + c.groupService.joinInstances(instances); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Join, - title: { value: localize('workbench.action.terminal.join', "Join Terminals"), original: 'Join Terminals' }, - category, - f1: true, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated)) - }); - } - async run(accessor: ServicesAccessor) { + + registerTerminalAction({ + id: TerminalCommandId.Join, + title: { value: localize('workbench.action.terminal.join', "Join Terminals"), original: 'Join Terminals' }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated)), + run: async (c, accessor) => { const themeService = accessor.get(IThemeService); - const groupService = accessor.get(ITerminalGroupService); const notificationService = accessor.get(INotificationService); + const quickInputService = accessor.get(IQuickInputService); const picks: ITerminalQuickPickItem[] = []; - if (groupService.instances.length <= 1) { + if (c.groupService.instances.length <= 1) { notificationService.warn(localize('workbench.action.terminal.join.insufficientTerminals', 'Insufficient terminals for the join action')); return; } - const otherInstances = groupService.instances.filter(i => i.instanceId !== groupService.activeInstance?.instanceId); + const otherInstances = c.groupService.instances.filter(i => i.instanceId !== c.groupService.activeInstance?.instanceId); for (const terminal of otherInstances) { - const group = groupService.getGroupForInstance(terminal); + const group = c.groupService.getGroupForInstance(terminal); if (group?.terminalInstances.length === 1) { const iconId = getIconId(accessor, terminal); const label = `$(${iconId}): ${terminal.title}`; @@ -1514,105 +1208,85 @@ export function registerTerminalActions() { notificationService.warn(localize('workbench.action.terminal.join.onlySplits', 'All terminals are joined already')); return; } - const result = await accessor.get(IQuickInputService).pick(picks, {}); + const result = await quickInputService.pick(picks, {}); if (result) { - groupService.joinInstances([result.terminal, groupService.activeInstance!]); + c.groupService.joinInstances([result.terminal, c.groupService.activeInstance!]); } } - } - ); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SplitInActiveWorkspace, - title: { value: localize('workbench.action.terminal.splitInActiveWorkspace', "Split Terminal (In Active Workspace)"), original: 'Split Terminal (In Active Workspace)' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported, - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); - await terminalService.doWithActiveInstance(async t => { - const instance = await terminalService.createTerminal({ location: { parentTerminal: t } }); - if (instance?.target !== TerminalLocation.Editor) { - await terminalGroupService.showPanel(true); - } - }); - } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectAll, - title: { value: localize('workbench.action.terminal.selectAll', "Select All"), original: 'Select All' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: [{ - // Don't use ctrl+a by default as that would override the common go to start - // of prompt shell binding - primary: 0, - // Technically this doesn't need to be here as it will fall back to this - // behavior anyway when handed to xterm.js, having this handled by VS Code - // makes it easier for users to see how it works though. - mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyA }, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.focus - }] + + registerTerminalAction({ + id: TerminalCommandId.SplitInActiveWorkspace, + title: { value: localize('workbench.action.terminal.splitInActiveWorkspace', "Split Terminal (In Active Workspace)"), original: 'Split Terminal (In Active Workspace)' }, + run: async (c) => { + await c.service.doWithActiveInstance(async t => { + const instance = await c.service.createTerminal({ location: { parentTerminal: t } }); + if (instance?.target !== TerminalLocation.Editor) { + await c.groupService.showPanel(true); + } }); } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.selectAll(); + }); + + registerTerminalAction({ + id: TerminalCommandId.SelectAll, + title: { value: localize('workbench.action.terminal.selectAll', "Select All"), original: 'Select All' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: [{ + // Don't use ctrl+a by default as that would override the common go to start + // of prompt shell binding + primary: 0, + // Technically this doesn't need to be here as it will fall back to this + // behavior anyway when handed to xterm.js, having this handled by VS Code + // makes it easier for users to see how it works though. + mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyA }, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.focus + }], + run: (c) => { + c.service.activeInstance?.selectAll(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.New, - title: { value: localize('workbench.action.terminal.new', "Create New Terminal"), original: 'Create New Terminal' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.webExtensionContributedProfile), - icon: newTerminalIcon, - keybinding: { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backquote, - mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Backquote }, - weight: KeybindingWeight.WorkbenchContrib - }, - description: { - description: 'workbench.action.terminal.new', - args: [{ - name: 'eventOrOptions', - schema: { - type: 'object' - } - }] + + registerTerminalAction({ + id: TerminalCommandId.New, + title: { value: localize('workbench.action.terminal.new', "Create New Terminal"), original: 'Create New Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.webExtensionContributedProfile), + icon: newTerminalIcon, + keybinding: { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Backquote, + mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Backquote }, + weight: KeybindingWeight.WorkbenchContrib + }, + description: { + // TODO: This is meant to be localized? + description: 'workbench.action.terminal.new', + args: [{ + name: 'eventOrOptions', + schema: { + type: 'object' } - }); - } - async run(accessor: ServicesAccessor, eventOrOptions: MouseEvent | ICreateTerminalOptions | undefined) { - const terminalService = accessor.get(ITerminalService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); - const terminalProfileService = accessor.get(ITerminalProfileService); + }] + }, + run: async (c, accessor, args) => { + // TODO: Improve cast + let eventOrOptions = args as MouseEvent | ICreateTerminalOptions | undefined; const workspaceContextService = accessor.get(IWorkspaceContextService); const commandService = accessor.get(ICommandService); const folders = workspaceContextService.getWorkspace().folders; if (eventOrOptions && eventOrOptions instanceof MouseEvent && (eventOrOptions.altKey || eventOrOptions.ctrlKey)) { - await terminalService.createTerminal({ location: { splitActiveTerminal: true } }); + await c.service.createTerminal({ location: { splitActiveTerminal: true } }); return; } - if (terminalService.isProcessSupportRegistered) { + if (c.service.isProcessSupportRegistered) { eventOrOptions = !eventOrOptions || eventOrOptions instanceof MouseEvent ? {} : eventOrOptions; let instance: ITerminalInstance | undefined; if (folders.length <= 1) { // Allow terminal service to handle the path when there is only a // single root - instance = await terminalService.createTerminal(eventOrOptions); + instance = await c.service.createTerminal(eventOrOptions); } else { const cwd = (await pickTerminalCwd(accessor))?.cwd; if (!cwd) { @@ -1620,12 +1294,12 @@ export function registerTerminalActions() { return; } eventOrOptions.cwd = cwd; - instance = await terminalService.createTerminal(eventOrOptions); + instance = await c.service.createTerminal(eventOrOptions); } - terminalService.setActiveInstance(instance); - await focusActiveTerminal(instance, terminalEditorService, terminalGroupService); + c.service.setActiveInstance(instance); + await focusActiveTerminal(instance, c.editorService, c.groupService); } else { - if (terminalProfileService.contributedProfiles.length > 0) { + if (c.profileService.contributedProfiles.length > 0) { commandService.executeCommand(TerminalCommandId.NewWithProfile); } else { commandService.executeCommand(TerminalCommandId.Toggle); @@ -1633,522 +1307,385 @@ export function registerTerminalActions() { } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Kill, - title: { value: localize('workbench.action.terminal.kill', "Kill the Active Terminal Instance"), original: 'Kill the Active Terminal Instance' }, - f1: true, - category, - precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - icon: killTerminalIcon - }); - } - async run(accessor: ServicesAccessor) { - const terminalGroupService = accessor.get(ITerminalGroupService); - const terminalService = accessor.get(ITerminalService); - const instance = terminalGroupService.activeInstance; + + registerTerminalAction({ + id: TerminalCommandId.Kill, + title: { value: localize('workbench.action.terminal.kill', "Kill the Active Terminal Instance"), original: 'Kill the Active Terminal Instance' }, + // TODO: Define preconditions at top of file + precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + icon: killTerminalIcon, + run: async (c) => { + const instance = c.groupService.activeInstance; if (!instance) { return; } - await terminalService.safeDisposeTerminal(instance); - if (terminalGroupService.instances.length > 0) { - await terminalGroupService.showPanel(true); + await c.service.safeDisposeTerminal(instance); + if (c.groupService.instances.length > 0) { + await c.groupService.showPanel(true); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.KillAll, - title: { value: localize('workbench.action.terminal.killAll', "Kill All Terminals"), original: 'Kill All Terminals' }, - f1: true, - category, - precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - icon: Codicon.trash - }); - } - async run(accessor: ServicesAccessor) { - const terminalService = accessor.get(ITerminalService); + + registerTerminalAction({ + id: TerminalCommandId.KillAll, + title: { value: localize('workbench.action.terminal.killAll', "Kill All Terminals"), original: 'Kill All Terminals' }, + precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + icon: Codicon.trash, + run: async (c) => { const disposePromises: Promise[] = []; - for (const instance of terminalService.instances) { - disposePromises.push(terminalService.safeDisposeTerminal(instance)); + for (const instance of c.service.instances) { + disposePromises.push(c.service.safeDisposeTerminal(instance)); } await Promise.all(disposePromises); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.KillEditor, - title: { value: localize('workbench.action.terminal.killEditor', "Kill the Active Terminal in Editor Area"), original: 'Kill the Active Terminal in Editor Area' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.KeyW, - win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KeyW] }, - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(TerminalContextKeys.focus, ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeTerminal), TerminalContextKeys.editorFocus) - } - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ICommandService).executeCommand(CLOSE_EDITOR_COMMAND_ID); + registerTerminalAction({ + id: TerminalCommandId.KillEditor, + title: { value: localize('workbench.action.terminal.killEditor', "Kill the Active Terminal in Editor Area"), original: 'Kill the Active Terminal in Editor Area' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.KeyW, + win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KeyW] }, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and(TerminalContextKeys.focus, ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeTerminal), TerminalContextKeys.editorFocus) + }, + run: async (c, accessor) => { + await accessor.get(ICommandService).executeCommand(CLOSE_EDITOR_COMMAND_ID); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.KillInstance, - title: terminalStrings.kill, - f1: false, - category, - precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - keybinding: { - primary: KeyCode.Delete, - mac: { - primary: KeyMod.CtrlCmd | KeyCode.Backspace, - secondary: [KeyCode.Delete] - }, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.tabsFocus - } - }); - } - async run(accessor: ServicesAccessor) { + registerTerminalAction({ + id: TerminalCommandId.KillInstance, + title: terminalStrings.kill, + f1: false, + precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + keybinding: { + primary: KeyCode.Delete, + mac: { + primary: KeyMod.CtrlCmd | KeyCode.Backspace, + secondary: [KeyCode.Delete] + }, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.tabsFocus + }, + run: async (c, accessor) => { const selectedInstances = getSelectedInstances(accessor); if (!selectedInstances) { return; } const listService = accessor.get(IListService); - const terminalService = accessor.get(ITerminalService); - const terminalGroupService = accessor.get(ITerminalGroupService); const disposePromises: Promise[] = []; for (const instance of selectedInstances) { - disposePromises.push(terminalService.safeDisposeTerminal(instance)); + disposePromises.push(c.service.safeDisposeTerminal(instance)); } await Promise.all(disposePromises); - if (terminalService.instances.length > 0) { - terminalGroupService.focusTabs(); + if (c.service.instances.length > 0) { + c.groupService.focusTabs(); listService.lastFocusedList?.focusNext(); } } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.FocusHover, - title: terminalStrings.focusHover, - f1: true, - category, - precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - keybinding: { - primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyI), - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus) - } - }); - } - async run(accessor: ServicesAccessor) { - accessor.get(ITerminalGroupService).focusHover(); + + registerTerminalAction({ + id: TerminalCommandId.FocusHover, + title: terminalStrings.focusHover, + precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + keybinding: { + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyI), + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus) + }, + run: async (c) => { + // TODO: Remove braces for single line run functions + c.groupService.focusHover(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Clear, - title: { value: localize('workbench.action.terminal.clear', "Clear"), original: 'Clear' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: [{ - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyK }, - // Weight is higher than work workbench contributions so the keybinding remains - // highest priority when chords are registered afterwards - weight: KeybindingWeight.WorkbenchContrib + 1, - // Disable the keybinding when accessibility mode is enabled as chords include - // important screen reader keybindings such as cmd+k, cmd+i to show the hover - when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), - }] - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).doWithActiveInstance(t => t.clearBuffer()); + + registerTerminalAction({ + id: TerminalCommandId.Clear, + title: { value: localize('workbench.action.terminal.clear', "Clear"), original: 'Clear' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: [{ + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyK }, + // Weight is higher than work workbench contributions so the keybinding remains + // highest priority when chords are registered afterwards + weight: KeybindingWeight.WorkbenchContrib + 1, + // Disable the keybinding when accessibility mode is enabled as chords include + // important screen reader keybindings such as cmd+k, cmd+i to show the hover + when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), + }], + run: async (c) => { + c.service.doWithActiveInstance(t => t.clearBuffer()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectDefaultProfile, - title: { value: localize('workbench.action.terminal.selectDefaultShell', "Select Default Profile"), original: 'Select Default Profile' }, - f1: true, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).showProfileQuickPick('setDefault'); + registerTerminalAction({ + id: TerminalCommandId.SelectDefaultProfile, + title: { value: localize('workbench.action.terminal.selectDefaultShell', "Select Default Profile"), original: 'Select Default Profile' }, + run: async (c) => { + await c.service.showProfileQuickPick('setDefault'); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CreateWithProfileButton, - title: TerminalCommandId.CreateWithProfileButton, - f1: false, - category, - precondition: TerminalContextKeys.processSupported - }); - } - async run(accessor: ServicesAccessor) { + registerTerminalAction({ + id: TerminalCommandId.CreateWithProfileButton, + title: TerminalCommandId.CreateWithProfileButton, + f1: false, + run: async (c) => { } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ConfigureTerminalSettings, - title: { value: localize('workbench.action.terminal.openSettings', "Configure Terminal Settings"), original: 'Configure Terminal Settings' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor) { + registerTerminalAction({ + id: TerminalCommandId.ConfigureTerminalSettings, + title: { value: localize('workbench.action.terminal.openSettings', "Configure Terminal Settings"), original: 'Configure Terminal Settings' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { await accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: '@feature:terminal' }); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SetDimensions, - title: { value: localize('workbench.action.terminal.setFixedDimensions', "Set Fixed Dimensions"), original: 'Set Fixed Dimensions' }, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen) - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.setFixedDimensions()); + registerTerminalAction({ + id: TerminalCommandId.SetDimensions, + title: { value: localize('workbench.action.terminal.setFixedDimensions', "Set Fixed Dimensions"), original: 'Set Fixed Dimensions' }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + run: async (c) => { + await c.service.doWithActiveInstance(t => t.setFixedDimensions()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SizeToContentWidth, - title: { value: localize('workbench.action.terminal.sizeToContentWidth', "Toggle Size to Content Width"), original: 'Toggle Size to Content Width' }, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - keybinding: { - primary: KeyMod.Alt | KeyCode.KeyZ, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.focus - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.toggleSizeToContentWidth()); + registerTerminalAction({ + id: TerminalCommandId.SizeToContentWidth, + title: { value: localize('workbench.action.terminal.sizeToContentWidth', "Toggle Size to Content Width"), original: 'Toggle Size to Content Width' }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), + keybinding: { + primary: KeyMod.Alt | KeyCode.KeyZ, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.focus + }, + run: async (c) => { + await c.service.doWithActiveInstance(t => t.toggleSizeToContentWidth()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SizeToContentWidthInstance, - title: terminalStrings.toggleSizeToContentWidth, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus) - }); - } - async run(accessor: ServicesAccessor) { - return getSelectedInstances(accessor)?.[0].toggleSizeToContentWidth(); + registerTerminalAction({ + id: TerminalCommandId.SizeToContentWidthInstance, + title: terminalStrings.toggleSizeToContentWidth, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus), + run: async (c, accessor) => { + await getSelectedInstances(accessor)?.[0].toggleSizeToContentWidth(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ClearPreviousSessionHistory, - title: { value: localize('workbench.action.terminal.clearPreviousSessionHistory', "Clear Previous Session History"), original: 'Clear Previous Session History' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - run(accessor: ServicesAccessor) { + + registerTerminalAction({ + id: TerminalCommandId.ClearPreviousSessionHistory, + title: { value: localize('workbench.action.terminal.clearPreviousSessionHistory', "Clear Previous Session History"), original: 'Clear Previous Session History' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor) => { getCommandHistory(accessor).clear(); clearShellFileHistory(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectPrevSuggestion, - title: { value: localize('workbench.action.terminal.selectPrevSuggestion', "Select the Previous Suggestion"), original: 'Select the Previous Suggestion' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - // Up is bound to other workbench keybindings that this needs to beat - primary: KeyCode.UpArrow, - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.selectPreviousSuggestion()); + + registerTerminalAction({ + id: TerminalCommandId.SelectPrevSuggestion, + title: { value: localize('workbench.action.terminal.selectPrevSuggestion', "Select the Previous Suggestion"), original: 'Select the Previous Suggestion' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + // Up is bound to other workbench keybindings that this needs to beat + primary: KeyCode.UpArrow, + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + c.service.doWithActiveInstance(t => t.selectPreviousSuggestion()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectPrevPageSuggestion, - title: { value: localize('workbench.action.terminal.selectPrevPageSuggestion', "Select the Previous Page Suggestion"), original: 'Select the Previous Page Suggestion' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - // Up is bound to other workbench keybindings that this needs to beat - primary: KeyCode.PageUp, - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.selectPreviousPageSuggestion()); + + registerTerminalAction({ + id: TerminalCommandId.SelectPrevPageSuggestion, + title: { value: localize('workbench.action.terminal.selectPrevPageSuggestion', "Select the Previous Page Suggestion"), original: 'Select the Previous Page Suggestion' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + // Up is bound to other workbench keybindings that this needs to beat + primary: KeyCode.PageUp, + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + c.service.doWithActiveInstance(t => t.selectPreviousPageSuggestion()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectNextSuggestion, - title: { value: localize('workbench.action.terminal.selectNextSuggestion', "Select the Next Suggestion"), original: 'Select the Next Suggestion' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - // Down is bound to other workbench keybindings that this needs to beat - primary: KeyCode.DownArrow, - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.selectNextSuggestion()); + + registerTerminalAction({ + id: TerminalCommandId.SelectNextSuggestion, + title: { value: localize('workbench.action.terminal.selectNextSuggestion', "Select the Next Suggestion"), original: 'Select the Next Suggestion' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + // Down is bound to other workbench keybindings that this needs to beat + primary: KeyCode.DownArrow, + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + c.service.doWithActiveInstance(t => t.selectNextSuggestion()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SelectNextPageSuggestion, - title: { value: localize('workbench.action.terminal.selectNextPageSuggestion', "Select the Next Page Suggestion"), original: 'Select the Next Page Suggestion' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - // Down is bound to other workbench keybindings that this needs to beat - primary: KeyCode.PageDown, - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).doWithActiveInstance(t => t.selectNextPageSuggestion()); + + registerTerminalAction({ + id: TerminalCommandId.SelectNextPageSuggestion, + title: { value: localize('workbench.action.terminal.selectNextPageSuggestion', "Select the Next Page Suggestion"), original: 'Select the Next Page Suggestion' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + // Down is bound to other workbench keybindings that this needs to beat + primary: KeyCode.PageDown, + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + c.service.doWithActiveInstance(t => t.selectNextPageSuggestion()); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.AcceptSelectedSuggestion, - title: { value: localize('workbench.action.terminal.acceptSelectedSuggestion', "Accept Selected Suggestion"), original: 'Accept Selected Suggestion' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - primary: KeyCode.Enter, - secondary: [KeyCode.Tab], - // Enter is bound to other workbench keybindings that this needs to beat - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.acceptSelectedSuggestion(); + + registerTerminalAction({ + id: TerminalCommandId.AcceptSelectedSuggestion, + title: { value: localize('workbench.action.terminal.acceptSelectedSuggestion', "Accept Selected Suggestion"), original: 'Accept Selected Suggestion' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + primary: KeyCode.Enter, + secondary: [KeyCode.Tab], + // Enter is bound to other workbench keybindings that this needs to beat + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + await c.service.activeInstance?.acceptSelectedSuggestion(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.HideSuggestWidget, - title: { value: localize('workbench.action.terminal.hideSuggestWidget', "Hide Suggest Widget"), original: 'Hide Suggest Widget' }, - f1: false, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), - keybinding: { - primary: KeyCode.Escape, - // Escape is bound to other workbench keybindings that this needs to beat - weight: KeybindingWeight.WorkbenchContrib + 1 - } - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.hideSuggestWidget(); + + registerTerminalAction({ + id: TerminalCommandId.HideSuggestWidget, + title: { value: localize('workbench.action.terminal.hideSuggestWidget', "Hide Suggest Widget"), original: 'Hide Suggest Widget' }, + f1: false, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus, TerminalContextKeys.isOpen, TerminalContextKeys.suggestWidgetVisible), + keybinding: { + primary: KeyCode.Escape, + // Escape is bound to other workbench keybindings that this needs to beat + weight: KeybindingWeight.WorkbenchContrib + 1 + }, + run: async (c) => { + c.service.activeInstance?.hideSuggestWidget(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.ShowQuickFixes, - title: { value: localize('workbench.action.terminal.showQuickFixes', "Show Terminal Quick Fixes"), original: 'Show Terminal Quick Fixes' }, - category, - precondition: TerminalContextKeys.focus, - keybinding: { - primary: KeyMod.CtrlCmd | KeyCode.Period, - weight: KeybindingWeight.WorkbenchContrib - } - }); - } - run(accessor: ServicesAccessor) { - accessor.get(ITerminalService).activeInstance?.quickFix?.showMenu(); + + registerTerminalAction({ + id: TerminalCommandId.ShowQuickFixes, + title: { value: localize('workbench.action.terminal.showQuickFixes', "Show Terminal Quick Fixes"), original: 'Show Terminal Quick Fixes' }, + precondition: TerminalContextKeys.focus, + keybinding: { + primary: KeyMod.CtrlCmd | KeyCode.Period, + weight: KeybindingWeight.WorkbenchContrib + }, + run: async (c) => { + c.service.activeInstance?.quickFix?.showMenu(); } }); // Some commands depend on platform features if (BrowserFeatures.clipboard.writeText) { - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CopySelection, - title: { value: localize('workbench.action.terminal.copySelection', "Copy Selection"), original: 'Copy Selection' }, - f1: true, - category, - // TODO: Why is copy still showing up when text isn't selected? - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), - keybinding: [{ - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyC, - mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyC }, - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) - }] - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.copySelection(); + registerTerminalAction({ + id: TerminalCommandId.CopySelection, + title: { value: localize('workbench.action.terminal.copySelection', "Copy Selection"), original: 'Copy Selection' }, + // TODO: Why is copy still showing up when text isn't selected? + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), + keybinding: [{ + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyC, + mac: { primary: KeyMod.CtrlCmd | KeyCode.KeyC }, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) + }], + run: async (c) => { + await c.service.activeInstance?.copySelection(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CopyAndClearSelection, - title: { value: localize('workbench.action.terminal.copyAndClearSelection', "Copy and Clear Selection"), original: 'Copy and Clear Selection' }, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), - keybinding: [{ - win: { primary: KeyMod.CtrlCmd | KeyCode.KeyC }, - weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) - }] - }); - } - async run(accessor: ServicesAccessor) { - const instance = accessor.get(ITerminalService).activeInstance; + + registerTerminalAction({ + id: TerminalCommandId.CopyAndClearSelection, + title: { value: localize('workbench.action.terminal.copyAndClearSelection', "Copy and Clear Selection"), original: 'Copy and Clear Selection' }, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), + keybinding: [{ + win: { primary: KeyMod.CtrlCmd | KeyCode.KeyC }, + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) + }], + run: async (c) => { + const instance = c.service.activeInstance; await instance?.copySelection(); instance?.clearSelection(); } }); - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.CopySelectionAsHtml, - title: { value: localize('workbench.action.terminal.copySelectionAsHtml', "Copy Selection as HTML"), original: 'Copy Selection as HTML' }, - f1: true, - category, - precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected) - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.copySelection(true); + + registerTerminalAction({ + id: TerminalCommandId.CopySelectionAsHtml, + title: { value: localize('workbench.action.terminal.copySelectionAsHtml', "Copy Selection as HTML"), original: 'Copy Selection as HTML' }, + f1: true, + category, + precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), + run: async (c) => { + await c.service.activeInstance?.copySelection(true); } }); } if (BrowserFeatures.clipboard.readText) { - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.Paste, - title: { value: localize('workbench.action.terminal.paste', "Paste into Active Terminal"), original: 'Paste into Active Terminal' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: [{ - primary: KeyMod.CtrlCmd | KeyCode.KeyV, - win: { primary: KeyMod.CtrlCmd | KeyCode.KeyV, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyV] }, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyV }, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.focus - }], - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.paste(); + registerTerminalAction({ + id: TerminalCommandId.Paste, + title: { value: localize('workbench.action.terminal.paste', "Paste into Active Terminal"), original: 'Paste into Active Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: [{ + primary: KeyMod.CtrlCmd | KeyCode.KeyV, + win: { primary: KeyMod.CtrlCmd | KeyCode.KeyV, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyV] }, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyV }, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.focus + }], + run: async (c) => { + await c.service.activeInstance?.paste(); } }); } if (BrowserFeatures.clipboard.readText && isLinux) { - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.PasteSelection, - title: { value: localize('workbench.action.terminal.pasteSelection', "Paste Selection into Active Terminal"), original: 'Paste Selection into Active Terminal' }, - f1: true, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - keybinding: [{ - linux: { primary: KeyMod.Shift | KeyCode.Insert }, - weight: KeybindingWeight.WorkbenchContrib, - when: TerminalContextKeys.focus - }], - }); - } - async run(accessor: ServicesAccessor) { - await accessor.get(ITerminalService).activeInstance?.pasteSelection(); + registerTerminalAction({ + id: TerminalCommandId.PasteSelection, + title: { value: localize('workbench.action.terminal.pasteSelection', "Paste Selection into Active Terminal"), original: 'Paste Selection into Active Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + keybinding: [{ + linux: { primary: KeyMod.Shift | KeyCode.Insert }, + weight: KeybindingWeight.WorkbenchContrib, + when: TerminalContextKeys.focus + }], + run: async (c) => { + await c.service.activeInstance?.pasteSelection(); } }); } - const switchTerminalTitle: ICommandActionTitle = { value: localize('workbench.action.terminal.switchTerminal', "Switch Terminal"), original: 'Switch Terminal' }; - registerAction2(class extends Action2 { - constructor() { - super({ - id: TerminalCommandId.SwitchTerminal, - title: switchTerminalTitle, - f1: false, - category, - precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) - }); - } - async run(accessor: ServicesAccessor, item?: string) { - const terminalService = accessor.get(ITerminalService); - const terminalProfileService = accessor.get(ITerminalProfileService); - const terminalGroupService = accessor.get(ITerminalGroupService); + registerTerminalAction({ + id: TerminalCommandId.SwitchTerminal, + title: { value: localize('workbench.action.terminal.switchTerminal', "Switch Terminal"), original: 'Switch Terminal' }, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), + run: async (c, accessor, args) => { + // TODO: Improve cast + const item = args as string | undefined; if (!item || !item.split) { - return Promise.resolve(null); + return; } if (item === switchTerminalActionViewItemSeparator) { - terminalService.refreshActiveGroup(); - return Promise.resolve(null); + c.service.refreshActiveGroup(); + return; } if (item === switchTerminalShowTabsTitle) { accessor.get(IConfigurationService).updateValue(TerminalSettingId.TabsEnabled, true); @@ -2158,28 +1695,27 @@ export function registerTerminalActions() { const terminalIndexRe = /^([0-9]+): /; const indexMatches = terminalIndexRe.exec(item); if (indexMatches) { - terminalGroupService.setActiveGroupByIndex(Number(indexMatches[1]) - 1); - return terminalGroupService.showPanel(true); + c.groupService.setActiveGroupByIndex(Number(indexMatches[1]) - 1); + return c.groupService.showPanel(true); } - const quickSelectProfiles = terminalProfileService.availableProfiles; + const quickSelectProfiles = c.profileService.availableProfiles; // Remove 'New ' from the selected item to get the profile name const profileSelection = item.substring(4); if (quickSelectProfiles) { const profile = quickSelectProfiles.find(profile => profile.profileName === profileSelection); if (profile) { - const instance = await terminalService.createTerminal({ + const instance = await c.service.createTerminal({ config: profile }); - terminalService.setActiveInstance(instance); + c.service.setActiveInstance(instance); } else { console.warn(`No profile with name "${profileSelection}"`); } } else { console.warn(`Unmatched terminal item: "${item}"`); } - return Promise.resolve(); } }); } @@ -2188,6 +1724,7 @@ interface IRemoteTerminalPick extends IQuickPickItem { term: IRemoteTerminalAttachTarget; } +// TODO: Change to work with terminal service collection function getSelectedInstances(accessor: ServicesAccessor): ITerminalInstance[] | undefined { const listService = accessor.get(IListService); const terminalService = accessor.get(ITerminalService); @@ -2235,6 +1772,7 @@ let newWithProfileAction: IDisposable; export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { const profileEnum = createProfileSchemaEnums(detectedProfiles); newWithProfileAction?.dispose(); + // TODO: Use new register function newWithProfileAction = registerAction2(class extends Action2 { constructor() { super({ @@ -2327,7 +1865,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { }); } -/** doc */ +// TODO: Work with terminal service collection function getActiveInstance(accessor: ServicesAccessor, resource: unknown): ITerminalInstance | undefined { const terminalService = accessor.get(ITerminalService); const castedResource = URI.isUri(resource) ? resource : undefined; @@ -2405,6 +1943,7 @@ export function shrinkWorkspaceFolderCwdPairs(pairs: WorkspaceFolderCwdPair[]): return selectedPairsInOrder; } +// TODO: Work with terminal service collection async function focusActiveTerminal(instance: ITerminalInstance, terminalEditorService: ITerminalEditorService, terminalGroupService: ITerminalGroupService): Promise { if (instance.target === TerminalLocation.Editor) { await terminalEditorService.revealActiveEditor(); @@ -2414,6 +1953,7 @@ async function focusActiveTerminal(instance: ITerminalInstance, terminalEditorSe } } +// TODO: Work with terminal service collection async function revealActiveTerminal(instance: ITerminalInstance, terminalEditorService: ITerminalEditorService, terminalGroupService: ITerminalGroupService): Promise { if (instance.target === TerminalLocation.Editor) { await terminalEditorService.revealActiveEditor(); From c5622856b69f9980062c2f28e65aeae2f9858fbe Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:12:14 -0700 Subject: [PATCH 03/16] Add registerActiveInstanceAction --- .../contrib/terminal/browser/terminal.ts | 1 + .../terminal/browser/terminalActions.ts | 302 +++++++----------- 2 files changed, 122 insertions(+), 181 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index b1cef6380c7a7..67cc2eebddb61 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -188,6 +188,7 @@ export interface ITerminalService extends ITerminalInstanceHost { moveToTerminalView(source?: ITerminalInstance | URI): Promise; getPrimaryBackend(): ITerminalBackend | undefined; + // TODO: Consider removing this /** * Perform an action with the active terminal instance, if the terminal does * not exist the callback will not be called. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 6a251f04ade17..1b20ba816ee22 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -157,6 +157,21 @@ function registerTerminalAction( }); } +function registerActiveInstanceAction( + options: IAction2Options & { run: (activeInstance: ITerminalInstance, c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } +): void { + const originalRun = options.run; + registerTerminalAction({ + ...options, + run: (c, accessor, args) => { + const activeInstance = c.service.activeInstance; + if (activeInstance) { + return originalRun(activeInstance, c, accessor, args); + } + } + }); +} + interface ITerminalServicesCollection { service: ITerminalService; groupService: ITerminalGroupService; @@ -303,7 +318,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.RunRecentCommand, title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -321,27 +336,23 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib } ], - run: async (c) => { - const instance = c.service.activeInstance; - if (instance) { - await instance.runRecent('command'); - if (instance?.target === TerminalLocation.Editor) { - await c.editorService.revealActiveEditor(); - } else { - await c.groupService.showPanel(false); - } + run: async (activeInstance, c) => { + await activeInstance.runRecent('command'); + if (activeInstance?.target === TerminalLocation.Editor) { + await c.editorService.revealActiveEditor(); + } else { + await c.groupService.showPanel(false); } } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.CopyLastCommandOutput, title: { value: localize('workbench.action.terminal.copyLastCommand', 'Copy Last Command Output'), original: 'Copy Last Command Output' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor) => { + run: async (instance, c, accessor) => { const clipboardService = accessor.get(IClipboardService); - const instance = c.service.activeInstance; - const commands = instance?.capabilities.get(TerminalCapability.CommandDetection)?.commands; + const commands = instance.capabilities.get(TerminalCapability.CommandDetection)?.commands; if (!commands || commands.length === 0) { return; } @@ -356,7 +367,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.GoToRecentDirectory, title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -365,15 +376,12 @@ export function registerTerminalActions() { when: TerminalContextKeys.focus, weight: KeybindingWeight.WorkbenchContrib }, - run: async (c) => { - const instance = c.service.activeInstance; - if (instance) { - await instance.runRecent('cwd'); - if (instance?.target === TerminalLocation.Editor) { - await c.editorService.revealActiveEditor(); - } else { - await c.groupService.showPanel(false); - } + run: async (activeInstance, c) => { + await activeInstance.runRecent('cwd'); + if (activeInstance?.target === TerminalLocation.Editor) { + await c.editorService.revealActiveEditor(); + } else { + await c.groupService.showPanel(false); } } }); @@ -563,7 +571,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollDownLine, title: { value: localize('workbench.action.terminal.scrollDown', "Scroll Down (Line)"), original: 'Scroll Down (Line)' }, keybinding: { @@ -573,12 +581,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.activeInstance?.scrollDownLine(); - } + run: (activeInstance) => activeInstance.scrollDownLine() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollDownPage, title: { value: localize('workbench.action.terminal.scrollDownPage', "Scroll Down (Page)"), original: 'Scroll Down (Page)' }, keybinding: { @@ -588,12 +594,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.activeInstance?.scrollDownPage(); - } + run: (activeInstance) => activeInstance.scrollDownPage() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollToBottom, title: { value: localize('workbench.action.terminal.scrollToBottom', "Scroll to Bottom"), original: 'Scroll to Bottom' }, keybinding: { @@ -603,12 +607,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.activeInstance?.scrollToBottom(); - } + run: (activeInstance) => activeInstance.scrollToBottom() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollUpLine, title: { value: localize('workbench.action.terminal.scrollUp', "Scroll Up (Line)"), original: 'Scroll Up (Line)' }, keybinding: { @@ -618,12 +620,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.activeInstance?.scrollUpLine(); - } + run: (activeInstance) => activeInstance.scrollUpLine() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollUpPage, title: { value: localize('workbench.action.terminal.scrollUpPage', "Scroll Up (Page)"), original: 'Scroll Up (Page)' }, f1: true, @@ -635,12 +635,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - c.service.activeInstance?.scrollUpPage(); - } + run: (activeInstance) => activeInstance.scrollUpPage() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollToTop, title: { value: localize('workbench.action.terminal.scrollToTop', "Scroll to Top"), original: 'Scroll to Top' }, keybinding: { @@ -650,12 +648,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.activeInstance?.scrollToTop(); - } + run: (activeInstance) => activeInstance.scrollToTop() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ClearSelection, title: { value: localize('workbench.action.terminal.clearSelection', "Clear Selection"), original: 'Clear Selection' }, keybinding: { @@ -664,10 +660,9 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - const instance = c.service.activeInstance; - if (instance?.hasSelection()) { - instance.clearSelection(); + run: (activeInstance) => { + if (activeInstance.hasSelection()) { + activeInstance.clearSelection(); } } }); @@ -799,12 +794,10 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.DetachSession, title: { value: localize('workbench.action.terminal.detachSession', "Detach Session"), original: 'Detach Session' }, - run: async (c) => { - c.service.activeInstance?.detachProcessAndDispose(TerminalExitReason.User); - } + run: (activeInstance) => activeInstance.detachProcessAndDispose(TerminalExitReason.User) }); registerTerminalAction({ @@ -861,7 +854,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollToPreviousCommand, title: { value: localize('workbench.action.terminal.scrollToPreviousCommand', "Scroll To Previous Command"), original: 'Scroll To Previous Command' }, keybinding: { @@ -870,15 +863,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - // TODO: Change doWithActiveInstance pattern to use specialized registerTerminalAction - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.scrollToPreviousMark(undefined, undefined, t.capabilities.has(TerminalCapability.CommandDetection)); - }); - } + run: (activeInstance) => activeInstance.xterm?.markTracker.scrollToPreviousMark(undefined, undefined, activeInstance.capabilities.has(TerminalCapability.CommandDetection)) }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ScrollToNextCommand, title: { value: localize('workbench.action.terminal.scrollToNextCommand', "Scroll To Next Command"), original: 'Scroll To Next Command' }, keybinding: { @@ -887,15 +875,13 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.scrollToNextMark(); - t.focus(); - }); + run: (activeInstance) => { + activeInstance.xterm?.markTracker.scrollToNextMark(); + activeInstance.focus(); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectToPreviousCommand, title: { value: localize('workbench.action.terminal.selectToPreviousCommand', "Select To Previous Command"), original: 'Select To Previous Command' }, keybinding: { @@ -904,15 +890,13 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.selectToPreviousMark(); - t.focus(); - }); + run: (activeInstance) => { + activeInstance.xterm?.markTracker.selectToPreviousMark(); + activeInstance.focus(); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectToNextCommand, title: { value: localize('workbench.action.terminal.selectToNextCommand', "Select To Next Command"), original: 'Select To Next Command' }, keybinding: { @@ -921,35 +905,29 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.selectToNextMark(); - t.focus(); - }); + run: (activeInstance) => { + activeInstance.xterm?.markTracker.selectToNextMark(); + activeInstance.focus(); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectToPreviousLine, title: { value: localize('workbench.action.terminal.selectToPreviousLine', "Select To Previous Line"), original: 'Select To Previous Line' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.selectToPreviousLine(); - t.focus(); - }); + run: async (activeInstance) => { + activeInstance.xterm?.markTracker.selectToPreviousLine(); + activeInstance.focus(); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectToNextLine, title: { value: localize('workbench.action.terminal.selectToNextLine', "Select To Next Line"), original: 'Select To Next Line' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - c.service.doWithActiveInstance(t => { - t.xterm?.markTracker.selectToNextLine(); - t.focus(); - }); + run: async (activeInstance) => { + activeInstance.xterm?.markTracker.selectToNextLine(); + activeInstance.focus(); } }); @@ -957,9 +935,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ToggleEscapeSequenceLogging, title: { value: localize('workbench.action.terminal.toggleEscapeSequenceLogging', "Toggle Escape Sequence Logging"), original: 'Toggle Escape Sequence Logging' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - await c.service.toggleEscapeSequenceLogging(); - } + run: (c) => c.service.toggleEscapeSequenceLogging() }); registerTerminalAction({ @@ -1017,7 +993,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.RenameWithArgs, // TODO: Move to terminalStrings title: { value: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), original: 'Rename the Currently Active Terminal' }, @@ -1039,23 +1015,21 @@ export function registerTerminalActions() { }] }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor, args) => { + run: async (activeInstance, c, accessor, args) => { const notificationService = accessor.get(INotificationService); const name = args && typeof args === 'object' && 'name' in args && typeof args.name === 'string' ? args.name : undefined; if (!name) { notificationService.warn(localize('workbench.action.terminal.renameWithArg.noName', "No name argument provided")); return; } - c.service.activeInstance?.rename(name); + activeInstance.rename(name); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.Relaunch, title: { value: localize('workbench.action.terminal.relaunch', "Relaunch Active Terminal"), original: 'Relaunch Active Terminal' }, - run: async (c) => { - c.service.activeInstance?.relaunch(); - } + run: (activeInstance) => activeInstance.relaunch() }); registerTerminalAction({ @@ -1129,13 +1103,11 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.Unsplit, title: terminalStrings.unsplit, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - await c.service.doWithActiveInstance(async t => c.groupService.unsplitInstance(t)); - } + run: (activeInstance, c) => c.groupService.unsplitInstance(activeInstance) }); registerTerminalAction({ @@ -1215,20 +1187,18 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SplitInActiveWorkspace, title: { value: localize('workbench.action.terminal.splitInActiveWorkspace', "Split Terminal (In Active Workspace)"), original: 'Split Terminal (In Active Workspace)' }, - run: async (c) => { - await c.service.doWithActiveInstance(async t => { - const instance = await c.service.createTerminal({ location: { parentTerminal: t } }); - if (instance?.target !== TerminalLocation.Editor) { - await c.groupService.showPanel(true); - } - }); + run: async (instance, c) => { + const newInstance = await c.service.createTerminal({ location: { parentTerminal: instance } }); + if (newInstance?.target !== TerminalLocation.Editor) { + await c.groupService.showPanel(true); + } } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectAll, title: { value: localize('workbench.action.terminal.selectAll', "Select All"), original: 'Select All' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -1243,9 +1213,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: TerminalContextKeys.focus }], - run: (c) => { - c.service.activeInstance?.selectAll(); - } + run: (activeInstance) => activeInstance.selectAll() }); registerTerminalAction({ @@ -1402,7 +1370,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.Clear, title: { value: localize('workbench.action.terminal.clear', "Clear"), original: 'Clear' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -1416,9 +1384,7 @@ export function registerTerminalActions() { // important screen reader keybindings such as cmd+k, cmd+i to show the hover when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()), }], - run: async (c) => { - c.service.doWithActiveInstance(t => t.clearBuffer()); - } + run: (activeInstance) => activeInstance.clearBuffer() }); registerTerminalAction({ @@ -1446,16 +1412,14 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SetDimensions, title: { value: localize('workbench.action.terminal.setFixedDimensions', "Set Fixed Dimensions"), original: 'Set Fixed Dimensions' }, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), - run: async (c) => { - await c.service.doWithActiveInstance(t => t.setFixedDimensions()); - } + run: (activeInstance) => activeInstance.setFixedDimensions() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SizeToContentWidth, title: { value: localize('workbench.action.terminal.sizeToContentWidth', "Toggle Size to Content Width"), original: 'Toggle Size to Content Width' }, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), @@ -1464,9 +1428,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: TerminalContextKeys.focus }, - run: async (c) => { - await c.service.doWithActiveInstance(t => t.toggleSizeToContentWidth()); - } + run: (instancactiveInstance) => instancactiveInstance.toggleSizeToContentWidth() }); registerTerminalAction({ @@ -1489,7 +1451,7 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectPrevSuggestion, title: { value: localize('workbench.action.terminal.selectPrevSuggestion', "Select the Previous Suggestion"), original: 'Select the Previous Suggestion' }, f1: false, @@ -1499,12 +1461,10 @@ export function registerTerminalActions() { primary: KeyCode.UpArrow, weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - c.service.doWithActiveInstance(t => t.selectPreviousSuggestion()); - } + run: (activeInstance) => activeInstance.selectPreviousSuggestion() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectPrevPageSuggestion, title: { value: localize('workbench.action.terminal.selectPrevPageSuggestion', "Select the Previous Page Suggestion"), original: 'Select the Previous Page Suggestion' }, f1: false, @@ -1514,12 +1474,10 @@ export function registerTerminalActions() { primary: KeyCode.PageUp, weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - c.service.doWithActiveInstance(t => t.selectPreviousPageSuggestion()); - } + run: (activeInstance) => activeInstance.selectPreviousPageSuggestion() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectNextSuggestion, title: { value: localize('workbench.action.terminal.selectNextSuggestion', "Select the Next Suggestion"), original: 'Select the Next Suggestion' }, f1: false, @@ -1529,12 +1487,10 @@ export function registerTerminalActions() { primary: KeyCode.DownArrow, weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - c.service.doWithActiveInstance(t => t.selectNextSuggestion()); - } + run: (insactiveInstanceance) => insactiveInstanceance.selectNextSuggestion() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.SelectNextPageSuggestion, title: { value: localize('workbench.action.terminal.selectNextPageSuggestion', "Select the Next Page Suggestion"), original: 'Select the Next Page Suggestion' }, f1: false, @@ -1544,12 +1500,10 @@ export function registerTerminalActions() { primary: KeyCode.PageDown, weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - c.service.doWithActiveInstance(t => t.selectNextPageSuggestion()); - } + run: (activeInstance) => activeInstance.selectNextPageSuggestion() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.AcceptSelectedSuggestion, title: { value: localize('workbench.action.terminal.acceptSelectedSuggestion', "Accept Selected Suggestion"), original: 'Accept Selected Suggestion' }, f1: false, @@ -1560,12 +1514,10 @@ export function registerTerminalActions() { // Enter is bound to other workbench keybindings that this needs to beat weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - await c.service.activeInstance?.acceptSelectedSuggestion(); - } + run: (activeInstance) => activeInstance.acceptSelectedSuggestion() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.HideSuggestWidget, title: { value: localize('workbench.action.terminal.hideSuggestWidget', "Hide Suggest Widget"), original: 'Hide Suggest Widget' }, f1: false, @@ -1575,12 +1527,10 @@ export function registerTerminalActions() { // Escape is bound to other workbench keybindings that this needs to beat weight: KeybindingWeight.WorkbenchContrib + 1 }, - run: async (c) => { - c.service.activeInstance?.hideSuggestWidget(); - } + run: (activeInstance) => activeInstance.hideSuggestWidget() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.ShowQuickFixes, title: { value: localize('workbench.action.terminal.showQuickFixes', "Show Terminal Quick Fixes"), original: 'Show Terminal Quick Fixes' }, precondition: TerminalContextKeys.focus, @@ -1588,14 +1538,12 @@ export function registerTerminalActions() { primary: KeyMod.CtrlCmd | KeyCode.Period, weight: KeybindingWeight.WorkbenchContrib }, - run: async (c) => { - c.service.activeInstance?.quickFix?.showMenu(); - } + run: (activeInstance) => activeInstance.quickFix?.showMenu() }); // Some commands depend on platform features if (BrowserFeatures.clipboard.writeText) { - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.CopySelection, title: { value: localize('workbench.action.terminal.copySelection', "Copy Selection"), original: 'Copy Selection' }, // TODO: Why is copy still showing up when text isn't selected? @@ -1606,12 +1554,10 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) }], - run: async (c) => { - await c.service.activeInstance?.copySelection(); - } + run: (activeInstance) => activeInstance.copySelection() }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.CopyAndClearSelection, title: { value: localize('workbench.action.terminal.copyAndClearSelection', "Copy and Clear Selection"), original: 'Copy and Clear Selection' }, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), @@ -1620,27 +1566,24 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(TerminalContextKeys.textSelected, TerminalContextKeys.focus) }], - run: async (c) => { - const instance = c.service.activeInstance; - await instance?.copySelection(); - instance?.clearSelection(); + run: async (activeInstance) => { + await activeInstance.copySelection(); + activeInstance.clearSelection(); } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.CopySelectionAsHtml, title: { value: localize('workbench.action.terminal.copySelectionAsHtml', "Copy Selection as HTML"), original: 'Copy Selection as HTML' }, f1: true, category, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.textSelected), - run: async (c) => { - await c.service.activeInstance?.copySelection(true); - } + run: (activeInstance) => activeInstance.copySelection(true) }); } if (BrowserFeatures.clipboard.readText) { - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.Paste, title: { value: localize('workbench.action.terminal.paste', "Paste into Active Terminal"), original: 'Paste into Active Terminal' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -1651,14 +1594,12 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: TerminalContextKeys.focus }], - run: async (c) => { - await c.service.activeInstance?.paste(); - } + run: (activeInstance) => activeInstance.paste() }); } if (BrowserFeatures.clipboard.readText && isLinux) { - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.PasteSelection, title: { value: localize('workbench.action.terminal.pasteSelection', "Paste Selection into Active Terminal"), original: 'Paste Selection into Active Terminal' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), @@ -1667,9 +1608,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: TerminalContextKeys.focus }], - run: async (c) => { - await c.service.activeInstance?.pasteSelection(); - } + run: (activeInstance) => activeInstance.pasteSelection() }); } @@ -1866,6 +1805,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { } // TODO: Work with terminal service collection +// TODO: Improve name to include resource usage function getActiveInstance(accessor: ServicesAccessor, resource: unknown): ITerminalInstance | undefined { const terminalService = accessor.get(ITerminalService); const castedResource = URI.isUri(resource) ? resource : undefined; From e6de0c77f678a325daee60a265eae50946615514 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:14:03 -0700 Subject: [PATCH 04/16] Return disposable --- .../workbench/contrib/terminal/browser/terminalActions.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 1b20ba816ee22..37bee55c7b462 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -137,7 +137,7 @@ export class TerminalLaunchHelpAction extends Action { */ function registerTerminalAction( options: IAction2Options & { run: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } -): void { +): IDisposable { // Set defaults options.f1 = options.f1 ?? true; options.category = options.category ?? category; @@ -147,7 +147,7 @@ function registerTerminalAction( const strictOptions: IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } = options; delete (strictOptions as IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise })['run']; // Register - registerAction2(class extends Action2 { + return registerAction2(class extends Action2 { constructor() { super(strictOptions as IAction2Options); } @@ -159,9 +159,9 @@ function registerTerminalAction( function registerActiveInstanceAction( options: IAction2Options & { run: (activeInstance: ITerminalInstance, c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } -): void { +): IDisposable { const originalRun = options.run; - registerTerminalAction({ + return registerTerminalAction({ ...options, run: (c, accessor, args) => { const activeInstance = c.service.activeInstance; From cf72e215f97c4dad5b147f6d633ea86b49446966 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:23:34 -0700 Subject: [PATCH 05/16] Improve some arg casting --- .../terminal/browser/terminalActions.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 37bee55c7b462..2ffb8c4fa6d3f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -99,9 +99,10 @@ export async function getCwdForSplit(configHelper: ITerminalConfigHelper, instan } } -export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: { text?: string } | undefined) => { +export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: unknown) => { accessor.get(ITerminalService).doWithActiveInstance(async t => { - if (!args?.text) { + const text = toOptionalString(args && typeof args === 'object' && 'text' in args ? args.text : undefined); + if (!text) { return; } const configurationResolverService = accessor.get(IConfigurationResolverService); @@ -109,7 +110,7 @@ export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: { const historyService = accessor.get(IHistoryService); const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(t.isRemote ? Schemas.vscodeRemote : Schemas.file); const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; - const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, args.text); + const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, text); t.sendText(resolvedText, false); }); }; @@ -262,10 +263,7 @@ export function registerTerminalActions() { id: TerminalCommandId.MoveToTerminalPanel, title: terminalStrings.moveToTerminalPanel, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive), - run: async (c, _, args: unknown) => { - const resource = URI.isUri(args) ? args : undefined; - await c.service.moveToTerminalView(resource); - } + run: (c, _, args) => c.service.moveToTerminalView(toOptionalUri(args)) }); registerTerminalAction({ @@ -955,11 +953,7 @@ export function registerTerminalActions() { } }] }, - run: async (c, accessor, args) => { - // TODO: Come up with a nicer way to parse args - const sequence = args && typeof args === 'object' && 'text' in args ? args as { text?: string } : undefined; - terminalSendSequenceCommand(accessor, sequence); - } + run: (c, accessor, args) => terminalSendSequenceCommand(accessor, args) }); registerTerminalAction({ @@ -1617,9 +1611,8 @@ export function registerTerminalActions() { title: { value: localize('workbench.action.terminal.switchTerminal', "Switch Terminal"), original: 'Switch Terminal' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), run: async (c, accessor, args) => { - // TODO: Improve cast - const item = args as string | undefined; - if (!item || !item.split) { + const item = toOptionalString(args); + if (!item) { return; } if (item === switchTerminalActionViewItemSeparator) { @@ -1808,8 +1801,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { // TODO: Improve name to include resource usage function getActiveInstance(accessor: ServicesAccessor, resource: unknown): ITerminalInstance | undefined { const terminalService = accessor.get(ITerminalService); - const castedResource = URI.isUri(resource) ? resource : undefined; - const instance = terminalService.getInstanceFromResource(castedResource) || terminalService.activeInstance; + const instance = terminalService.getInstanceFromResource(toOptionalUri(resource)) || terminalService.activeInstance; return instance; } @@ -1901,3 +1893,11 @@ async function revealActiveTerminal(instance: ITerminalInstance, terminalEditorS await terminalGroupService.showPanel(); } } + +function toOptionalUri(obj: unknown): URI | undefined { + return URI.isUri(obj) ? obj : undefined; +} + +function toOptionalString(obj: unknown): string | undefined { + return typeof obj === 'string' ? obj : undefined; +} From c460749cccf036377c4477887843e10d55d39df1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:23:55 -0700 Subject: [PATCH 06/16] Hide send sequence from command palette It takes args and won't work without them --- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 2ffb8c4fa6d3f..31b495f285249 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -940,6 +940,7 @@ export function registerTerminalActions() { id: TerminalCommandId.SendSequence, // TODO: Pull into terminalStrings title: { value: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), original: 'Send Custom Sequence To Terminal' }, + f1: false, description: { description: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), args: [{ From 75d09d08cde906bbb56795b20e3a64bdd04e5465 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:40:59 -0700 Subject: [PATCH 07/16] Improve arg safety --- .../contrib/terminal/browser/terminalActions.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 31b495f285249..9c6c50bd17095 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -10,7 +10,7 @@ import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Schemas } from 'vs/base/common/network'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { withNullAsUndefined } from 'vs/base/common/types'; +import { withNullAsUndefined, isObject } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EndOfLinePreference } from 'vs/editor/common/model'; @@ -101,7 +101,7 @@ export async function getCwdForSplit(configHelper: ITerminalConfigHelper, instan export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: unknown) => { accessor.get(ITerminalService).doWithActiveInstance(async t => { - const text = toOptionalString(args && typeof args === 'object' && 'text' in args ? args.text : undefined); + const text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined; if (!text) { return; } @@ -216,7 +216,7 @@ export function registerTerminalActions() { id: TerminalCommandId.CreateTerminalEditor, title: { value: localize('workbench.action.terminal.createTerminalEditor', "Create New Terminal in Editor Area"), original: 'Create New Terminal in Editor Area' }, run: async (c, _, args) => { - const options = (typeof args === 'object' && args && 'location' in args) ? args as ICreateTerminalOptions : { location: TerminalLocation.Editor }; + const options = (isObject(args) && 'location' in args) ? args as ICreateTerminalOptions : { location: TerminalLocation.Editor }; const instance = await c.service.createTerminal(options); instance.focusWhenReady(); } @@ -978,7 +978,7 @@ export function registerTerminalActions() { }] }, run: async (c, _, args) => { - const cwd = args && typeof args === 'object' && 'cwd' in args && typeof args.cwd === 'string' ? args.cwd : undefined; + const cwd = isObject(args) && 'cwd' in args ? toOptionalString(args.cwd) : undefined; const instance = await c.service.createTerminal({ cwd }); if (!instance) { return; @@ -1012,7 +1012,7 @@ export function registerTerminalActions() { precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), run: async (activeInstance, c, accessor, args) => { const notificationService = accessor.get(INotificationService); - const name = args && typeof args === 'object' && 'name' in args && typeof args.name === 'string' ? args.name : undefined; + const name = isObject(args) && 'name' in args ? toOptionalString(args.name) : undefined; if (!name) { notificationService.warn(localize('workbench.action.terminal.renameWithArg.noName', "No name argument provided")); return; @@ -1052,8 +1052,7 @@ export function registerTerminalActions() { }] }, run: async (c, accessor, args) => { - // TODO: Validate arg shape - const optionsOrProfile = args as ICreateTerminalOptions | ITerminalProfile | undefined; + const optionsOrProfile = isObject(args) ? args as ICreateTerminalOptions | ITerminalProfile : undefined; const commandService = accessor.get(ICommandService); const workspaceContextService = accessor.get(IWorkspaceContextService); const options = convertOptionsOrProfileToOptions(optionsOrProfile); @@ -1232,8 +1231,7 @@ export function registerTerminalActions() { }] }, run: async (c, accessor, args) => { - // TODO: Improve cast - let eventOrOptions = args as MouseEvent | ICreateTerminalOptions | undefined; + let eventOrOptions = isObject(args) ? args as MouseEvent | ICreateTerminalOptions : undefined; const workspaceContextService = accessor.get(IWorkspaceContextService); const commandService = accessor.get(ICommandService); const folders = workspaceContextService.getWorkspace().folders; From e3cc111ba1a20d3b157f8a18c8e2b71af3520782 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:44:06 -0700 Subject: [PATCH 08/16] Remove braces from single line run functions --- .../terminal/browser/terminalActions.ts | 84 +++++-------------- 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 9c6c50bd17095..ef22a5a3ce05f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -237,9 +237,7 @@ export function registerTerminalActions() { id: TerminalCommandId.MoveToEditor, title: terminalStrings.moveToEditor, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive.toNegated(), TerminalContextKeys.viewShowing), - run: (c) => { - c.service.doWithActiveInstance(instance => c.service.moveToEditor(instance)); - } + run: (c) => c.service.doWithActiveInstance(instance => c.service.moveToEditor(instance)) }); registerTerminalAction({ @@ -271,9 +269,7 @@ export function registerTerminalActions() { title: { value: localize('workbench.action.terminal.showTabs', "Show Tabs"), original: 'Show Tabs' }, f1: false, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.showTabs(); - } + run: (c) => c.groupService.showTabs() }); registerTerminalAction({ @@ -394,9 +390,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.activeGroup?.resizePane(Direction.Left); - } + run: (c) => c.groupService.activeGroup?.resizePane(Direction.Left) }); registerTerminalAction({ @@ -409,9 +403,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.activeGroup?.resizePane(Direction.Right); - } + run: (c) => c.groupService.activeGroup?.resizePane(Direction.Right) }); registerTerminalAction({ @@ -423,9 +415,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.activeGroup?.resizePane(Direction.Up); - } + run: (c) => c.groupService.activeGroup?.resizePane(Direction.Up) }); registerTerminalAction({ @@ -437,9 +427,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.activeGroup?.resizePane(Direction.Down); - } + run: (c) => c.groupService.activeGroup?.resizePane(Direction.Down) }); registerTerminalAction({ @@ -465,9 +453,7 @@ export function registerTerminalActions() { when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus), }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c) => { - c.groupService.focusTabs(); - } + run: (c) => c.groupService.focusTabs() }); registerTerminalAction({ @@ -669,9 +655,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ChangeIcon, title: terminalStrings.changeIcon, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor, args: unknown) => { - await getActiveInstance(accessor, args)?.changeIcon(); - } + run: (c, accessor, args: unknown) => getActiveInstance(accessor, args)?.changeIcon() }); registerTerminalAction({ @@ -679,9 +663,7 @@ export function registerTerminalActions() { title: terminalStrings.changeIcon, f1: false, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - await c.groupService.activeInstance?.changeIcon(); - } + run: (c) => c.groupService.activeInstance?.changeIcon() }); registerTerminalAction({ @@ -689,18 +671,14 @@ export function registerTerminalActions() { title: terminalStrings.changeIcon, f1: false, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), - run: async (c, accessor) => { - await getSelectedInstances(accessor)?.[0].changeIcon(); - } + run: (c, accessor) => getSelectedInstances(accessor)?.[0].changeIcon() }); registerTerminalAction({ id: TerminalCommandId.ChangeColor, title: terminalStrings.changeColor, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor, args) => { - await getActiveInstance(accessor, args)?.changeColor(); - } + run: (c, accessor, args) => getActiveInstance(accessor, args)?.changeColor() }); registerTerminalAction({ @@ -708,9 +686,7 @@ export function registerTerminalActions() { title: terminalStrings.changeColor, f1: false, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c) => { - await c.groupService.activeInstance?.changeColor(); - } + run: (c) => c.groupService.activeInstance?.changeColor() }); registerTerminalAction({ @@ -718,18 +694,14 @@ export function registerTerminalActions() { title: terminalStrings.changeColor, f1: false, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.tabsSingularSelection), - run: async (c, accessor) => { - await getSelectedInstances(accessor)?.[0].changeColor(); - } + run: (c, accessor) => getSelectedInstances(accessor)?.[0].changeColor() }); registerTerminalAction({ id: TerminalCommandId.Rename, title: terminalStrings.rename, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor, args) => { - await renameWithQuickPick(accessor, args); - } + run: (c, accessor, args) => renameWithQuickPick(accessor, args) }); registerTerminalAction({ @@ -737,9 +709,7 @@ export function registerTerminalActions() { title: terminalStrings.rename, f1: false, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor) => { - await renameWithQuickPick(accessor); - } + run: (c, accessor) => renameWithQuickPick(accessor) }); // TODO: Use terminal service collection, move to bottom @@ -847,9 +817,7 @@ export function registerTerminalActions() { id: TerminalCommandId.QuickOpenTerm, title: { value: localize('quickAccessTerminal', "Switch Active Terminal"), original: 'Switch Active Terminal' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, accessor) => { - accessor.get(IQuickInputService).quickAccess.show(TerminalQuickAccessProvider.PREFIX); - } + run: (c, accessor) => accessor.get(IQuickInputService).quickAccess.show(TerminalQuickAccessProvider.PREFIX) }); registerActiveInstanceAction({ @@ -1311,9 +1279,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(TerminalContextKeys.focus, ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeTerminal), TerminalContextKeys.editorFocus) }, - run: async (c, accessor) => { - await accessor.get(ICommandService).executeCommand(CLOSE_EDITOR_COMMAND_ID); - } + run: (c, accessor) => accessor.get(ICommandService).executeCommand(CLOSE_EDITOR_COMMAND_ID) }); registerTerminalAction({ @@ -1357,10 +1323,7 @@ export function registerTerminalActions() { weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.or(TerminalContextKeys.tabsFocus, TerminalContextKeys.focus) }, - run: async (c) => { - // TODO: Remove braces for single line run functions - c.groupService.focusHover(); - } + run: (c) => c.groupService.focusHover() }); registerActiveInstanceAction({ @@ -1383,17 +1346,14 @@ export function registerTerminalActions() { registerTerminalAction({ id: TerminalCommandId.SelectDefaultProfile, title: { value: localize('workbench.action.terminal.selectDefaultShell', "Select Default Profile"), original: 'Select Default Profile' }, - run: async (c) => { - await c.service.showProfileQuickPick('setDefault'); - } + run: (c) => c.service.showProfileQuickPick('setDefault') }); registerTerminalAction({ id: TerminalCommandId.CreateWithProfileButton, title: TerminalCommandId.CreateWithProfileButton, f1: false, - run: async (c) => { - } + run: (c) => { } }); registerTerminalAction({ @@ -1429,9 +1389,7 @@ export function registerTerminalActions() { title: terminalStrings.toggleSizeToContentWidth, f1: false, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.focus), - run: async (c, accessor) => { - await getSelectedInstances(accessor)?.[0].toggleSizeToContentWidth(); - } + run: (c, accessor) => getSelectedInstances(accessor)?.[0].toggleSizeToContentWidth() }); registerTerminalAction({ From 3689f68fcca02cebce9dbf8c35ba0379be1eec39 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:46:18 -0700 Subject: [PATCH 09/16] Allow returning Promise --- .../contrib/terminal/browser/terminalActions.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index ef22a5a3ce05f..0bb82e30421fd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -137,7 +137,7 @@ export class TerminalLaunchHelpAction extends Action { * - `precondition`: TerminalContextKeys.processSupported */ function registerTerminalAction( - options: IAction2Options & { run: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } + options: IAction2Options & { run: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } ): IDisposable { // Set defaults options.f1 = options.f1 ?? true; @@ -145,8 +145,8 @@ function registerTerminalAction( options.precondition = options.precondition ?? TerminalContextKeys.processSupported; // Remove run function from options so it's not passed through to registerAction2 const runFunc = options.run; - const strictOptions: IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } = options; - delete (strictOptions as IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise })['run']; + const strictOptions: IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } = options; + delete (strictOptions as IAction2Options & { run?: (c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise })['run']; // Register return registerAction2(class extends Action2 { constructor() { @@ -159,7 +159,7 @@ function registerTerminalAction( } function registerActiveInstanceAction( - options: IAction2Options & { run: (activeInstance: ITerminalInstance, c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } + options: IAction2Options & { run: (activeInstance: ITerminalInstance, c: ITerminalServicesCollection, accessor: ServicesAccessor, args?: unknown) => void | Promise } ): IDisposable { const originalRun = options.run; return registerTerminalAction({ @@ -1360,9 +1360,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ConfigureTerminalSettings, title: { value: localize('workbench.action.terminal.openSettings', "Configure Terminal Settings"), original: 'Configure Terminal Settings' }, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: async (c, accessor) => { - await accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: '@feature:terminal' }); - } + run: (c, accessor) => accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: '@feature:terminal' }) }); registerActiveInstanceAction({ From dd0b53560ae9d11c2c55bb5f119079c50a1ef9d2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:48:45 -0700 Subject: [PATCH 10/16] Improve arg handling more --- .../contrib/terminal/browser/terminalActions.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 0bb82e30421fd..b5d533d43857e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -10,7 +10,7 @@ import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Schemas } from 'vs/base/common/network'; import { isLinux, isWindows } from 'vs/base/common/platform'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { withNullAsUndefined, isObject } from 'vs/base/common/types'; +import { withNullAsUndefined, isObject, isString } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EndOfLinePreference } from 'vs/editor/common/model'; @@ -355,7 +355,7 @@ export function registerTerminalActions() { return; } const output = command.getOutput(); - if (output && typeof output === 'string') { + if (isString(output)) { await clipboardService.writeText(output); } } @@ -1648,7 +1648,7 @@ export function validateTerminalName(name: string): { content: string; severity: } function convertOptionsOrProfileToOptions(optionsOrProfile?: ICreateTerminalOptions | ITerminalProfile): ICreateTerminalOptions | undefined { - if (typeof optionsOrProfile === 'object' && 'profileName' in optionsOrProfile) { + if (isObject(optionsOrProfile) && 'profileName' in optionsOrProfile) { return { config: optionsOrProfile as ITerminalProfile, location: (optionsOrProfile as ICreateTerminalOptions).location }; } return optionsOrProfile; @@ -1701,7 +1701,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { let instance: ITerminalInstance | undefined; let cwd: string | URI | undefined; - if (typeof eventOrOptionsOrProfile === 'object' && eventOrOptionsOrProfile && 'profileName' in eventOrOptionsOrProfile) { + if (isObject(eventOrOptionsOrProfile) && eventOrOptionsOrProfile && 'profileName' in eventOrOptionsOrProfile) { const config = terminalProfileService.availableProfiles.find(profile => profile.profileName === eventOrOptionsOrProfile.profileName); if (!config) { throw new Error(`Could not find terminal profile "${eventOrOptionsOrProfile.profileName}"`); @@ -1803,7 +1803,7 @@ async function pickTerminalCwd(accessor: ServicesAccessor, cancel?: Cancellation async function resolveWorkspaceFolderCwd(folder: IWorkspaceFolder, configurationService: IConfigurationService, configurationResolverService: IConfigurationResolverService): Promise { const cwdConfig = configurationService.getValue(TerminalSettingId.Cwd, { resource: folder.uri }); - if (typeof cwdConfig !== 'string' || cwdConfig.length === 0) { + if (!isString(cwdConfig) || cwdConfig.length === 0) { return { folder, cwd: folder.uri, isAbsolute: false, isOverridden: false }; } @@ -1854,5 +1854,5 @@ function toOptionalUri(obj: unknown): URI | undefined { } function toOptionalString(obj: unknown): string | undefined { - return typeof obj === 'string' ? obj : undefined; + return isString(obj) ? obj : undefined; } From 5d64e26617664c053358e05578457781fdd0abe4 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:51:25 -0700 Subject: [PATCH 11/16] Use terminal service collection in 2 helpers --- .../terminal/browser/terminalActions.ts | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index b5d533d43857e..42f41dd147cc8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -655,7 +655,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ChangeIcon, title: terminalStrings.changeIcon, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, accessor, args: unknown) => getActiveInstance(accessor, args)?.changeIcon() + run: (c, _, args: unknown) => getActiveInstance(c, args)?.changeIcon() }); registerTerminalAction({ @@ -678,7 +678,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ChangeColor, title: terminalStrings.changeColor, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, accessor, args) => getActiveInstance(accessor, args)?.changeColor() + run: (c, _, args) => getActiveInstance(c, args)?.changeColor() }); registerTerminalAction({ @@ -701,7 +701,7 @@ export function registerTerminalActions() { id: TerminalCommandId.Rename, title: terminalStrings.rename, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, accessor, args) => renameWithQuickPick(accessor, args) + run: (c, accessor, args) => renameWithQuickPick(c, accessor, args) }); registerTerminalAction({ @@ -709,21 +709,9 @@ export function registerTerminalActions() { title: terminalStrings.rename, f1: false, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, accessor) => renameWithQuickPick(accessor) + run: (c, accessor) => renameWithQuickPick(c, accessor) }); - // TODO: Use terminal service collection, move to bottom - async function renameWithQuickPick(accessor: ServicesAccessor, resource?: unknown) { - const instance = getActiveInstance(accessor, resource); - if (instance) { - const title = await accessor.get(IQuickInputService).input({ - value: instance.title, - prompt: localize('workbench.action.terminal.rename.prompt', "Enter terminal name"), - }); - instance.rename(title); - } - } - registerTerminalAction({ id: TerminalCommandId.RenameInstance, title: terminalStrings.rename, @@ -1752,12 +1740,9 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { }); } -// TODO: Work with terminal service collection // TODO: Improve name to include resource usage -function getActiveInstance(accessor: ServicesAccessor, resource: unknown): ITerminalInstance | undefined { - const terminalService = accessor.get(ITerminalService); - const instance = terminalService.getInstanceFromResource(toOptionalUri(resource)) || terminalService.activeInstance; - return instance; +function getActiveInstance(c: ITerminalServicesCollection, resource: unknown): ITerminalInstance | undefined { + return c.service.getInstanceFromResource(toOptionalUri(resource)) || c.service.activeInstance; } async function pickTerminalCwd(accessor: ServicesAccessor, cancel?: CancellationToken): Promise { @@ -1849,6 +1834,17 @@ async function revealActiveTerminal(instance: ITerminalInstance, terminalEditorS } } +async function renameWithQuickPick(c: ITerminalServicesCollection, accessor: ServicesAccessor, resource?: unknown) { + const instance = getActiveInstance(c, resource); + if (instance) { + const title = await accessor.get(IQuickInputService).input({ + value: instance.title, + prompt: localize('workbench.action.terminal.rename.prompt', "Enter terminal name"), + }); + instance.rename(title); + } +} + function toOptionalUri(obj: unknown): URI | undefined { return URI.isUri(obj) ? obj : undefined; } From 69c42e81211e93ffd049328d47e75cb5b5e22b70 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:03:51 -0700 Subject: [PATCH 12/16] Move some strings to terminalStrings --- .../terminal/browser/terminalActions.ts | 42 +++++-------------- .../terminal/common/terminalStrings.ts | 12 ++++++ 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 42f41dd147cc8..0fe588a12606f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -894,18 +894,20 @@ export function registerTerminalActions() { registerTerminalAction({ id: TerminalCommandId.SendSequence, - // TODO: Pull into terminalStrings - title: { value: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), original: 'Send Custom Sequence To Terminal' }, + title: terminalStrings.sendSequence, f1: false, description: { - description: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), + description: terminalStrings.sendSequence.value, args: [{ name: 'args', schema: { type: 'object', required: ['text'], properties: { - text: { type: 'string' } + text: { + description: localize('sendSequence', "The sequence of text to send to the terminal"), + type: 'string' + } }, } }] @@ -915,10 +917,9 @@ export function registerTerminalActions() { registerTerminalAction({ id: TerminalCommandId.NewWithCwd, - // TODO: Pull into terminalStrings - title: { value: localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"), original: 'Create New Terminal Starting in a Custom Working Directory' }, + title: terminalStrings.newWithCwd, description: { - description: localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"), + description: terminalStrings.newWithCwd.value, args: [{ name: 'args', schema: { @@ -946,10 +947,9 @@ export function registerTerminalActions() { registerActiveInstanceAction({ id: TerminalCommandId.RenameWithArgs, - // TODO: Move to terminalStrings - title: { value: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), original: 'Rename the Currently Active Terminal' }, + title: terminalStrings.renameWithArgs, description: { - description: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), + description: terminalStrings.renameWithArgs.value, args: [{ name: 'args', schema: { @@ -997,16 +997,6 @@ export function registerTerminalActions() { when: TerminalContextKeys.focus }, icon: Codicon.splitHorizontal, - description: { - // TODO: This is meant to be a localized string? Is this used anywhere? - description: 'workbench.action.terminal.split', - args: [{ - name: 'profile', - schema: { - type: 'object' - } - }] - }, run: async (c, accessor, args) => { const optionsOrProfile = isObject(args) ? args as ICreateTerminalOptions | ITerminalProfile : undefined; const commandService = accessor.get(ICommandService); @@ -1176,16 +1166,6 @@ export function registerTerminalActions() { mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.Backquote }, weight: KeybindingWeight.WorkbenchContrib }, - description: { - // TODO: This is meant to be localized? - description: 'workbench.action.terminal.new', - args: [{ - name: 'eventOrOptions', - schema: { - type: 'object' - } - }] - }, run: async (c, accessor, args) => { let eventOrOptions = isObject(args) ? args as MouseEvent | ICreateTerminalOptions : undefined; const workspaceContextService = accessor.get(IWorkspaceContextService); @@ -1657,7 +1637,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { category, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.webExtensionContributedProfile), description: { - description: 'workbench.action.terminal.newWithProfile', + description: TerminalCommandId.NewWithProfile, args: [{ name: 'args', schema: { diff --git a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts index 0b35e3124de1c..75e281c9f2df3 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalStrings.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalStrings.ts @@ -64,4 +64,16 @@ export const terminalStrings = { value: localize('workbench.action.terminal.focusHover', "Focus Hover"), original: 'Focus Hover' }, + sendSequence: { + value: localize('workbench.action.terminal.sendSequence', "Send Custom Sequence To Terminal"), + original: 'Send Custom Sequence To Terminal' + }, + newWithCwd: { + value: localize('workbench.action.terminal.newWithCwd', "Create New Terminal Starting in a Custom Working Directory"), + original: 'Create New Terminal Starting in a Custom Working Directory' + }, + renameWithArgs: { + value: localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal"), + original: 'Rename the Currently Active Terminal' + } }; From 0a22950db441046dfaa7b9f155c8a4626480a585 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:07:55 -0700 Subject: [PATCH 13/16] Improve async handling of SplitInstance, make faster --- .../contrib/terminal/browser/terminalActions.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 0fe588a12606f..7518360400a3c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -1031,14 +1031,14 @@ export function registerTerminalActions() { run: async (c, accessor) => { const instances = getSelectedInstances(accessor); if (instances) { + const promises: Promise[] = []; for (const t of instances) { - c.service.setActiveInstance(t); - // TODO: This should await??? - c.service.doWithActiveInstance(async instance => { - await c.service.createTerminal({ location: { parentTerminal: instance } }); + promises.push((async () => { + await c.service.createTerminal({ location: { parentTerminal: t } }); await c.groupService.showPanel(true); - }); + })()); } + await Promise.all(promises); } } }); From 3abc175317e9aad28198b425fc7a5f432e58aad2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:10:34 -0700 Subject: [PATCH 14/16] Use ITerminalServicesCollection in remaining places --- .../terminal/browser/terminalActions.ts | 55 ++++++++----------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 7518360400a3c..2c097c67d3fce 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -511,7 +511,7 @@ export function registerTerminalActions() { text = editor.getModel().getValueInRange(selection, endOfLinePreference); } instance.sendText(text, true, true); - await revealActiveTerminal(instance, c.editorService, c.groupService); + await revealActiveTerminal(instance, c); } }); @@ -535,7 +535,7 @@ export function registerTerminalActions() { if (instance?.xterm?.isStdinDisabled || instance?.shellLaunchConfig.type === 'Task') { instance = await c.service.createTerminal(); c.service.setActiveInstance(instance); - await revealActiveTerminal(instance, c.editorService, c.groupService); + await revealActiveTerminal(instance, c); } const isRemote = instance ? instance.isRemote : (workbenchEnvironmentService.remoteAuthority ? true : false); @@ -655,7 +655,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ChangeIcon, title: terminalStrings.changeIcon, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, _, args: unknown) => getActiveInstance(c, args)?.changeIcon() + run: (c, _, args: unknown) => getResourceOrActiveInstance(c, args)?.changeIcon() }); registerTerminalAction({ @@ -678,7 +678,7 @@ export function registerTerminalActions() { id: TerminalCommandId.ChangeColor, title: terminalStrings.changeColor, precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), - run: (c, _, args) => getActiveInstance(c, args)?.changeColor() + run: (c, _, args) => getResourceOrActiveInstance(c, args)?.changeColor() }); registerTerminalAction({ @@ -796,7 +796,7 @@ export function registerTerminalActions() { config: { attachPersistentProcess: selected.term } }); c.service.setActiveInstance(instance); - await focusActiveTerminal(instance, c.editorService, c.groupService); + await focusActiveTerminal(instance, c); } } }); @@ -941,7 +941,7 @@ export function registerTerminalActions() { return; } c.service.setActiveInstance(instance); - await focusActiveTerminal(instance, c.editorService, c.groupService); + await focusActiveTerminal(instance, c); } }); @@ -1011,7 +1011,7 @@ export function registerTerminalActions() { return; } const instance = await c.service.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); - await focusActiveTerminal(instance, c.editorService, c.groupService); + await focusActiveTerminal(instance, c); } }); @@ -1194,7 +1194,7 @@ export function registerTerminalActions() { instance = await c.service.createTerminal(eventOrOptions); } c.service.setActiveInstance(instance); - await focusActiveTerminal(instance, c.editorService, c.groupService); + await focusActiveTerminal(instance, c); } else { if (c.profileService.contributedProfiles.length > 0) { commandService.executeCommand(TerminalCommandId.NewWithProfile); @@ -1579,7 +1579,6 @@ interface IRemoteTerminalPick extends IQuickPickItem { term: IRemoteTerminalAttachTarget; } -// TODO: Change to work with terminal service collection function getSelectedInstances(accessor: ServicesAccessor): ITerminalInstance[] | undefined { const listService = accessor.get(IListService); const terminalService = accessor.get(ITerminalService); @@ -1657,10 +1656,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { }); } async run(accessor: ServicesAccessor, eventOrOptionsOrProfile: MouseEvent | ICreateTerminalOptions | ITerminalProfile | { profileName: string } | undefined, profile?: ITerminalProfile) { - const terminalService = accessor.get(ITerminalService); - const terminalProfileService = accessor.get(ITerminalProfileService); - const terminalEditorService = accessor.get(ITerminalEditorService); - const terminalGroupService = accessor.get(ITerminalGroupService); + const c = getTerminalServices(accessor); const workspaceContextService = accessor.get(IWorkspaceContextService); const commandService = accessor.get(ICommandService); @@ -1670,7 +1666,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { let cwd: string | URI | undefined; if (isObject(eventOrOptionsOrProfile) && eventOrOptionsOrProfile && 'profileName' in eventOrOptionsOrProfile) { - const config = terminalProfileService.availableProfiles.find(profile => profile.profileName === eventOrOptionsOrProfile.profileName); + const config = c.profileService.availableProfiles.find(profile => profile.profileName === eventOrOptionsOrProfile.profileName); if (!config) { throw new Error(`Could not find terminal profile "${eventOrOptionsOrProfile.profileName}"`); } @@ -1684,9 +1680,9 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { // split terminal if (event && (event.altKey || event.ctrlKey)) { - const parentTerminal = terminalService.activeInstance; + const parentTerminal = c.service.activeInstance; if (parentTerminal) { - await terminalService.createTerminal({ location: { parentTerminal }, config: options?.config }); + await c.service.createTerminal({ location: { parentTerminal }, config: options?.config }); return; } } @@ -1707,21 +1703,20 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { if (options) { options.cwd = cwd; - instance = await terminalService.createTerminal(options); + instance = await c.service.createTerminal(options); } else { - instance = await terminalService.showProfileQuickPick('createInstance', cwd); + instance = await c.service.showProfileQuickPick('createInstance', cwd); } if (instance) { - terminalService.setActiveInstance(instance); - await focusActiveTerminal(instance, terminalEditorService, terminalGroupService); + c.service.setActiveInstance(instance); + await focusActiveTerminal(instance, c); } } }); } -// TODO: Improve name to include resource usage -function getActiveInstance(c: ITerminalServicesCollection, resource: unknown): ITerminalInstance | undefined { +function getResourceOrActiveInstance(c: ITerminalServicesCollection, resource: unknown): ITerminalInstance | undefined { return c.service.getInstanceFromResource(toOptionalUri(resource)) || c.service.activeInstance; } @@ -1795,27 +1790,25 @@ export function shrinkWorkspaceFolderCwdPairs(pairs: WorkspaceFolderCwdPair[]): return selectedPairsInOrder; } -// TODO: Work with terminal service collection -async function focusActiveTerminal(instance: ITerminalInstance, terminalEditorService: ITerminalEditorService, terminalGroupService: ITerminalGroupService): Promise { +async function focusActiveTerminal(instance: ITerminalInstance, c: ITerminalServicesCollection): Promise { if (instance.target === TerminalLocation.Editor) { - await terminalEditorService.revealActiveEditor(); + await c.editorService.revealActiveEditor(); await instance.focusWhenReady(true); } else { - await terminalGroupService.showPanel(true); + await c.groupService.showPanel(true); } } -// TODO: Work with terminal service collection -async function revealActiveTerminal(instance: ITerminalInstance, terminalEditorService: ITerminalEditorService, terminalGroupService: ITerminalGroupService): Promise { +async function revealActiveTerminal(instance: ITerminalInstance, c: ITerminalServicesCollection): Promise { if (instance.target === TerminalLocation.Editor) { - await terminalEditorService.revealActiveEditor(); + await c.editorService.revealActiveEditor(); } else { - await terminalGroupService.showPanel(); + await c.groupService.showPanel(); } } async function renameWithQuickPick(c: ITerminalServicesCollection, accessor: ServicesAccessor, resource?: unknown) { - const instance = getActiveInstance(c, resource); + const instance = getResourceOrActiveInstance(c, resource); if (instance) { const title = await accessor.get(IQuickInputService).input({ value: instance.title, From 8b5cb0baab7576dffb0fd81a1b28721196a4f295 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:22:23 -0700 Subject: [PATCH 15/16] Remove todo --- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 2c097c67d3fce..3c6c1dbd90cc0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -1208,7 +1208,6 @@ export function registerTerminalActions() { registerTerminalAction({ id: TerminalCommandId.Kill, title: { value: localize('workbench.action.terminal.kill', "Kill the Active Terminal Instance"), original: 'Kill the Active Terminal Instance' }, - // TODO: Define preconditions at top of file precondition: ContextKeyExpr.or(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.isOpen), icon: killTerminalIcon, run: async (c) => { From e7234138332e26c914004472a11680e1b38a3f6f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:25:29 -0700 Subject: [PATCH 16/16] Remove ITerminalInstance.doWithActiveInstance --- .../contrib/terminal/browser/terminal.ts | 8 -------- .../contrib/terminal/browser/terminalActions.ts | 15 ++++++++------- .../contrib/terminal/browser/terminalService.ts | 7 ------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 67cc2eebddb61..0e291ac804199 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -188,14 +188,6 @@ export interface ITerminalService extends ITerminalInstanceHost { moveToTerminalView(source?: ITerminalInstance | URI): Promise; getPrimaryBackend(): ITerminalBackend | undefined; - // TODO: Consider removing this - /** - * Perform an action with the active terminal instance, if the terminal does - * not exist the callback will not be called. - * @param callback The callback that fires with the active terminal - */ - doWithActiveInstance(callback: (terminal: ITerminalInstance) => T): T | void; - /** * Fire the onActiveTabChanged event, this will trigger the terminal dropdown to be updated, * among other things. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 3c6c1dbd90cc0..cd20df52c390c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -99,8 +99,9 @@ export async function getCwdForSplit(configHelper: ITerminalConfigHelper, instan } } -export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: unknown) => { - accessor.get(ITerminalService).doWithActiveInstance(async t => { +export const terminalSendSequenceCommand = async (accessor: ServicesAccessor, args: unknown) => { + const instance = accessor.get(ITerminalService).activeInstance; + if (instance) { const text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined; if (!text) { return; @@ -108,11 +109,11 @@ export const terminalSendSequenceCommand = (accessor: ServicesAccessor, args: un const configurationResolverService = accessor.get(IConfigurationResolverService); const workspaceContextService = accessor.get(IWorkspaceContextService); const historyService = accessor.get(IHistoryService); - const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(t.isRemote ? Schemas.vscodeRemote : Schemas.file); + const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(instance.isRemote ? Schemas.vscodeRemote : Schemas.file); const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined; const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, text); - t.sendText(resolvedText, false); - }); + instance.sendText(resolvedText, false); + } }; export class TerminalLaunchHelpAction extends Action { @@ -233,11 +234,11 @@ export function registerTerminalActions() { } }); - registerTerminalAction({ + registerActiveInstanceAction({ id: TerminalCommandId.MoveToEditor, title: terminalStrings.moveToEditor, precondition: ContextKeyExpr.and(ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), TerminalContextKeys.terminalEditorActive.toNegated(), TerminalContextKeys.viewShowing), - run: (c) => c.service.doWithActiveInstance(instance => c.service.moveToEditor(instance)) + run: (activeInstance, c) => c.service.moveToEditor(activeInstance) }); registerTerminalAction({ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 02ba3e9630985..fb68458f088bc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -681,13 +681,6 @@ export class TerminalService implements ITerminalService { this._onDidChangeActiveGroup.fire(this._terminalGroupService.activeGroup); } - doWithActiveInstance(callback: (terminal: ITerminalInstance) => T): T | void { - const instance = this.activeInstance; - if (instance) { - return callback(instance); - } - } - getInstanceFromId(terminalId: number): ITerminalInstance | undefined { let bgIndex = -1; this._backgroundedTerminalInstances.forEach((terminalInstance, i) => {