Merge pull request #99543 from microsoft/tyriar/99542
Change Open in Terminal context menu title dynamically based on settings
This commit is contained in:
commit
fecb7dd86f
|
@ -5,16 +5,11 @@
|
|||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IExternalTerminalConfiguration, IExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { MenuId, MenuRegistry, IMenuItem } from 'vs/platform/actions/common/actions';
|
||||
import { ITerminalService as IIntegratedTerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { ResourceContextKey } from 'vs/workbench/common/resources';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files';
|
||||
|
@ -25,9 +20,13 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
|||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExplorerService } from 'vs/workbench/contrib/files/common/files';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isWeb, isWindows } from 'vs/base/common/platform';
|
||||
import { dirname, basename } from 'vs/base/common/path';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
const OPEN_IN_TERMINAL_COMMAND_ID = 'openInTerminal';
|
||||
CommandsRegistry.registerCommand({
|
||||
|
@ -62,7 +61,7 @@ CommandsRegistry.registerCommand({
|
|||
authority: resource.authority,
|
||||
fragment: resource.fragment,
|
||||
query: resource.query,
|
||||
path: paths.dirname(resource.path)
|
||||
path: dirname(resource.path)
|
||||
});
|
||||
}).forEach(cwd => {
|
||||
if (opened[cwd.path]) {
|
||||
|
@ -70,13 +69,13 @@ CommandsRegistry.registerCommand({
|
|||
}
|
||||
opened[cwd.path] = true;
|
||||
const instance = integratedTerminalService.createTerminal({ cwd });
|
||||
if (instance && (resources.length === 1 || !resource || cwd.path === resource.path || cwd.path === paths.dirname(resource.path))) {
|
||||
if (instance && (resources.length === 1 || !resource || cwd.path === resource.path || cwd.path === dirname(resource.path))) {
|
||||
integratedTerminalService.setActiveInstance(instance);
|
||||
integratedTerminalService.showPanel(true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
distinct(targets.map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath))).forEach(cwd => {
|
||||
distinct(targets.map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : dirname(stat!.resource.fsPath))).forEach(cwd => {
|
||||
terminalService!.openTerminal(cwd);
|
||||
});
|
||||
}
|
||||
|
@ -84,67 +83,56 @@ CommandsRegistry.registerCommand({
|
|||
}
|
||||
});
|
||||
|
||||
if (!isWeb) {
|
||||
const OPEN_NATIVE_CONSOLE_COMMAND_ID = 'workbench.action.terminal.openNativeConsole';
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: OPEN_NATIVE_CONSOLE_COMMAND_ID,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C,
|
||||
when: KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
handler: async (accessor) => {
|
||||
const historyService = accessor.get(IHistoryService);
|
||||
// Open external terminal in local workspaces
|
||||
const terminalService = accessor.get(IExternalTerminalService);
|
||||
const root = historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
if (root) {
|
||||
terminalService.openTerminal(root.fsPath);
|
||||
} else {
|
||||
// Opens current file's folder, if no folder is open in editor
|
||||
const activeFile = historyService.getLastActiveFile(Schemas.file);
|
||||
if (activeFile) {
|
||||
terminalService.openTerminal(paths.dirname(activeFile.fsPath));
|
||||
} else {
|
||||
const pathService = accessor.get(IPathService);
|
||||
const userHome = await pathService.userHome;
|
||||
terminalService.openTerminal(userHome.fsPath);
|
||||
}
|
||||
export class ExternalTerminalContribution extends Disposable implements IWorkbenchContribution {
|
||||
private _openInTerminalMenuItem: IMenuItem;
|
||||
|
||||
constructor(
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._openInTerminalMenuItem = {
|
||||
group: 'navigation',
|
||||
order: 30,
|
||||
command: {
|
||||
id: OPEN_IN_TERMINAL_COMMAND_ID,
|
||||
title: nls.localize('scopedConsoleAction', "Open in Terminal")
|
||||
},
|
||||
when: ContextKeyExpr.or(ResourceContextKey.Scheme.isEqualTo(Schemas.file), ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeRemote))
|
||||
};
|
||||
MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, this._openInTerminalMenuItem);
|
||||
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, this._openInTerminalMenuItem);
|
||||
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('terminal.explorerKind') || e.affectsConfiguration('terminal.external')) {
|
||||
this._refreshOpenInTerminalMenuItemTitle();
|
||||
}
|
||||
});
|
||||
this._refreshOpenInTerminalMenuItemTitle();
|
||||
}
|
||||
|
||||
private _refreshOpenInTerminalMenuItemTitle(): void {
|
||||
if (isWeb) {
|
||||
this._openInTerminalMenuItem.command.title = nls.localize('scopedConsoleAction.integrated', "Open in Integrated Terminal");
|
||||
return;
|
||||
}
|
||||
|
||||
const config = this._configurationService.getValue<IExternalTerminalConfiguration>().terminal;
|
||||
if (config.explorerKind === 'integrated') {
|
||||
this._openInTerminalMenuItem.command.title = nls.localize('scopedConsoleAction.integrated', "Open in Integrated Terminal");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWindows && config.external.windowsExec) {
|
||||
const file = basename(config.external.windowsExec);
|
||||
if (file === 'wt' || file === 'wt.exe') {
|
||||
this._openInTerminalMenuItem.command.title = nls.localize('scopedConsoleAction.wt', "Open in Windows Terminal");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: OPEN_NATIVE_CONSOLE_COMMAND_ID,
|
||||
title: { value: nls.localize('globalConsoleAction', "Open New External Terminal"), original: 'Open New External Terminal' }
|
||||
}
|
||||
});
|
||||
this._openInTerminalMenuItem.command.title = nls.localize('scopedConsoleAction.external', "Open in External Terminal");
|
||||
}
|
||||
}
|
||||
|
||||
const openConsoleCommand = {
|
||||
id: OPEN_IN_TERMINAL_COMMAND_ID,
|
||||
title: nls.localize('scopedConsoleAction', "Open in Terminal")
|
||||
};
|
||||
MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {
|
||||
group: 'navigation',
|
||||
order: 30,
|
||||
command: openConsoleCommand,
|
||||
when: ResourceContextKey.Scheme.isEqualTo(Schemas.file)
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, {
|
||||
group: 'navigation',
|
||||
order: 30,
|
||||
command: openConsoleCommand,
|
||||
when: ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeRemote)
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
||||
group: 'navigation',
|
||||
order: 30,
|
||||
command: openConsoleCommand,
|
||||
when: ResourceContextKey.Scheme.isEqualTo(Schemas.file)
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
|
||||
group: 'navigation',
|
||||
order: 30,
|
||||
command: openConsoleCommand,
|
||||
when: ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeRemote)
|
||||
});
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(ExternalTerminalContribution, LifecyclePhase.Restored);
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as paths from 'vs/base/common/path';
|
||||
import { IExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
import { WindowsExternalTerminalService, MacExternalTerminalService, LinuxExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
|
||||
import { IConfigurationRegistry, Extensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
|
||||
import { DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminal';
|
||||
|
||||
const OPEN_NATIVE_CONSOLE_COMMAND_ID = 'workbench.action.terminal.openNativeConsole';
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: OPEN_NATIVE_CONSOLE_COMMAND_ID,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C,
|
||||
when: KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
handler: async (accessor) => {
|
||||
const historyService = accessor.get(IHistoryService);
|
||||
// Open external terminal in local workspaces
|
||||
const terminalService = accessor.get(IExternalTerminalService);
|
||||
const root = historyService.getLastActiveWorkspaceRoot(Schemas.file);
|
||||
if (root) {
|
||||
terminalService.openTerminal(root.fsPath);
|
||||
} else {
|
||||
// Opens current file's folder, if no folder is open in editor
|
||||
const activeFile = historyService.getLastActiveFile(Schemas.file);
|
||||
if (activeFile) {
|
||||
terminalService.openTerminal(paths.dirname(activeFile.fsPath));
|
||||
} else {
|
||||
const pathService = accessor.get(IPathService);
|
||||
const userHome = await pathService.userHome;
|
||||
terminalService.openTerminal(userHome.fsPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: OPEN_NATIVE_CONSOLE_COMMAND_ID,
|
||||
title: { value: nls.localize('globalConsoleAction', "Open New External Terminal"), original: 'Open New External Terminal' }
|
||||
}
|
||||
});
|
||||
|
||||
if (isWindows) {
|
||||
registerSingleton(IExternalTerminalService, WindowsExternalTerminalService, true);
|
||||
} else if (isMacintosh) {
|
||||
registerSingleton(IExternalTerminalService, MacExternalTerminalService, true);
|
||||
} else if (isLinux) {
|
||||
registerSingleton(IExternalTerminalService, LinuxExternalTerminalService, true);
|
||||
}
|
||||
|
||||
LinuxExternalTerminalService.getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
|
||||
let configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
id: 'externalTerminal',
|
||||
order: 100,
|
||||
title: nls.localize('terminalConfigurationTitle', "External Terminal"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'terminal.explorerKind': {
|
||||
type: 'string',
|
||||
enum: [
|
||||
'integrated',
|
||||
'external'
|
||||
],
|
||||
enumDescriptions: [
|
||||
nls.localize('terminal.explorerKind.integrated', "Use VS Code's integrated terminal."),
|
||||
nls.localize('terminal.explorerKind.external', "Use the configured external terminal.")
|
||||
],
|
||||
description: nls.localize('explorer.openInTerminalKind', "Customizes what kind of terminal to launch."),
|
||||
default: 'integrated'
|
||||
},
|
||||
'terminal.external.windowsExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.windowsExec', "Customizes which terminal to run on Windows."),
|
||||
default: WindowsExternalTerminalService.getDefaultTerminalWindows(),
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
},
|
||||
'terminal.external.osxExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.osxExec', "Customizes which terminal application to run on macOS."),
|
||||
default: DEFAULT_TERMINAL_OSX,
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
},
|
||||
'terminal.external.linuxExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.linuxExec', "Customizes which terminal to run on Linux."),
|
||||
default: defaultTerminalLinux,
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const DEFAULT_TERMINAL_OSX = 'Terminal.app';
|
|
@ -4,7 +4,8 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { deepEqual, equal } from 'assert';
|
||||
import { WindowsExternalTerminalService, LinuxExternalTerminalService, MacExternalTerminalService, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
|
||||
import { WindowsExternalTerminalService, LinuxExternalTerminalService, MacExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
|
||||
import { DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminal';
|
||||
|
||||
suite('ExternalTerminalService', () => {
|
||||
let mockOnExit: Function;
|
||||
|
|
|
@ -13,14 +13,10 @@ import { assign } from 'vs/base/common/objects';
|
|||
import { IExternalTerminalService, IExternalTerminalConfiguration, IExternalTerminalSettings } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { IConfigurationRegistry, Extensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
import { DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminal';
|
||||
|
||||
const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console");
|
||||
export const DEFAULT_TERMINAL_OSX = 'Terminal.app';
|
||||
|
||||
export class WindowsExternalTerminalService implements IExternalTerminalService {
|
||||
public _serviceBrand: undefined;
|
||||
|
@ -358,54 +354,3 @@ function quote(args: string[]): string {
|
|||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (env.isWindows) {
|
||||
registerSingleton(IExternalTerminalService, WindowsExternalTerminalService, true);
|
||||
} else if (env.isMacintosh) {
|
||||
registerSingleton(IExternalTerminalService, MacExternalTerminalService, true);
|
||||
} else if (env.isLinux) {
|
||||
registerSingleton(IExternalTerminalService, LinuxExternalTerminalService, true);
|
||||
}
|
||||
|
||||
LinuxExternalTerminalService.getDefaultTerminalLinuxReady().then(defaultTerminalLinux => {
|
||||
let configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
id: 'externalTerminal',
|
||||
order: 100,
|
||||
title: nls.localize('terminalConfigurationTitle', "External Terminal"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'terminal.explorerKind': {
|
||||
type: 'string',
|
||||
enum: [
|
||||
'integrated',
|
||||
'external'
|
||||
],
|
||||
enumDescriptions: [
|
||||
nls.localize('terminal.explorerKind.integrated', "Use VS Code's integrated terminal."),
|
||||
nls.localize('terminal.explorerKind.external', "Use the configured external terminal.")
|
||||
],
|
||||
description: nls.localize('explorer.openInTerminalKind', "Customizes what kind of terminal to launch."),
|
||||
default: 'integrated'
|
||||
},
|
||||
'terminal.external.windowsExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.windowsExec', "Customizes which terminal to run on Windows."),
|
||||
default: WindowsExternalTerminalService.getDefaultTerminalWindows(),
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
},
|
||||
'terminal.external.osxExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.osxExec', "Customizes which terminal application to run on macOS."),
|
||||
default: DEFAULT_TERMINAL_OSX,
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
},
|
||||
'terminal.external.linuxExec': {
|
||||
type: 'string',
|
||||
description: nls.localize('terminal.external.linuxExec', "Customizes which terminal to run on Linux."),
|
||||
default: defaultTerminalLinux,
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -109,8 +109,8 @@ import 'vs/workbench/contrib/remote/electron-browser/remote.contribution';
|
|||
// CodeEditor Contributions
|
||||
import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution';
|
||||
|
||||
// Execution
|
||||
import 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
|
||||
// External Terminal
|
||||
import 'vs/workbench/contrib/externalTerminal/node/externalTerminal.contribution';
|
||||
|
||||
// Performance
|
||||
import 'vs/workbench/contrib/performance/electron-browser/performance.contribution';
|
||||
|
|
Loading…
Reference in a new issue