This commit is contained in:
meganrogge 2021-08-02 09:01:35 -07:00
parent 97faef955a
commit 2769f4c94f
No known key found for this signature in database
GPG key ID: 3155C8B2F0428C81
3 changed files with 119 additions and 187 deletions

View file

@ -5,35 +5,33 @@
import * as dom from 'vs/base/browser/dom';
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IAction, Separator, SubmenuAction } from 'vs/base/common/actions';
import { IAction } from 'vs/base/common/actions';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Codicon } from 'vs/base/common/codicons';
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
import { localize } from 'vs/nls';
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
import { IMenu, IMenuActionOptions, IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IEditorOptions } from 'vs/platform/editor/common/editor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ICreateTerminalOptions, ITerminalProfile, TerminalLocation } from 'vs/platform/terminal/common/terminal';
import { TerminalLocation } from 'vs/platform/terminal/common/terminal';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { IEditorOpenContext } from 'vs/workbench/common/editor';
import { ITerminalEditorService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';
import { TerminalTabContextMenuGroup } from 'vs/workbench/contrib/terminal/browser/terminalMenus';
import { getTerminalActionBarArgs } from 'vs/workbench/contrib/terminal/browser/terminalMenus';
import { ITerminalProfileResolverService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints';
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { isLinux, isMacintosh } from 'vs/base/common/platform';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { openContextMenu } from 'vs/workbench/contrib/terminal/browser/terminalContextMenu';
import { ICommandService } from 'vs/platform/commands/common/commands';
const findWidgetSelector = '.simple-find-part-wrapper';
@ -68,7 +66,8 @@ export class TerminalEditor extends EditorPane {
@ITerminalContributionService private readonly _terminalContributionService: ITerminalContributionService,
@ITerminalService private readonly _terminalService: ITerminalService,
@IInstantiationService instantiationService: IInstantiationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@ICommandService private readonly _commandService: ICommandService,
@IMenuService menuService: IMenuService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
@ -77,8 +76,8 @@ export class TerminalEditor extends EditorPane {
super(TerminalEditor.ID, telemetryService, themeService, storageService);
this._findState = new FindReplaceState();
this._findWidget = instantiationService.createInstance(TerminalFindWidget, this._findState);
this._dropdownMenu = this._register(menuService.createMenu(MenuId.TerminalNewDropdownContext, contextKeyService));
this._instanceMenu = this._register(menuService.createMenu(MenuId.TerminalInstanceContext, contextKeyService));
this._dropdownMenu = this._register(menuService.createMenu(MenuId.TerminalNewDropdownContext, _contextKeyService));
this._instanceMenu = this._register(menuService.createMenu(MenuId.TerminalInstanceContext, _contextKeyService));
}
override async setInput(newInput: TerminalEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken) {
@ -202,7 +201,7 @@ export class TerminalEditor extends EditorPane {
override getActionViewItem(action: IAction): IActionViewItem | undefined {
switch (action.id) {
case TerminalCommandId.CreateWithProfileButton: {
const actions = this._getTabActionBarArgs(this._terminalService.availableProfiles);
const actions = getTerminalActionBarArgs(TerminalLocation.Editor, this._terminalService.availableProfiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu);
const button = this._instantiationService.createInstance(DropdownWithPrimaryActionViewItem, actions.primaryAction, actions.dropdownAction, actions.dropdownMenuActions, actions.className, this._contextMenuService);
return button;
}
@ -210,92 +209,14 @@ export class TerminalEditor extends EditorPane {
return super.getActionViewItem(action);
}
private _getTabActionBarArgs(profiles: ITerminalProfile[]): {
primaryAction: MenuItemAction,
dropdownAction: IAction,
dropdownMenuActions: IAction[],
className: string,
dropdownIcon?: string
} {
const dropdownActions: IAction[] = [];
const submenuActions: IAction[] = [];
private _getDefaultProfileName(): string {
let defaultProfileName;
try {
defaultProfileName = this._terminalService.getDefaultProfileName();
} catch (e) {
defaultProfileName = this._terminalProfileResolverService.defaultProfileName;
}
for (const p of profiles) {
const isDefault = p.profileName === defaultProfileName;
const options: IMenuActionOptions = {
arg: {
config: p,
target: TerminalLocation.Editor
} as ICreateTerminalOptions,
shouldForwardArgs: true
};
if (isDefault) {
dropdownActions.unshift(this._instantiationService.createInstance(MenuItemAction, { id: TerminalCommandId.NewWithProfile, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options));
submenuActions.unshift(this._instantiationService.createInstance(MenuItemAction, { id: TerminalCommandId.Split, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options));
} else {
dropdownActions.push(this._instantiationService.createInstance(MenuItemAction, { id: TerminalCommandId.NewWithProfile, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options));
submenuActions.push(this._instantiationService.createInstance(MenuItemAction, { id: TerminalCommandId.Split, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options));
}
}
for (const contributed of this._terminalContributionService.terminalProfiles) {
const isDefault = contributed.title === defaultProfileName;
const title = isDefault ? localize('defaultTerminalProfile', "{0} (Default)", contributed.title.replace(/[\n\r\t]/g, '')) : contributed.title.replace(/[\n\r\t]/g, '');
dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => this._terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
target: TerminalLocation.Editor
})));
submenuActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => this._terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
forceSplit: true,
target: TerminalLocation.Editor
})));
}
if (dropdownActions.length > 0) {
dropdownActions.push(new SubmenuAction('split.profile', 'Split...', submenuActions));
dropdownActions.push(new Separator());
}
for (const [, configureActions] of this._dropdownMenu.getActions()) {
for (const action of configureActions) {
// make sure the action is a MenuItemAction
if ('alt' in action) {
dropdownActions.push(action);
}
}
}
const primaryAction = this._instantiationService.createInstance(
MenuItemAction,
{
id: TerminalCommandId.CreateTerminalEditor,
title: localize('terminal.new', "New Terminal"),
icon: Codicon.plus
},
{
id: 'workbench.action.splitEditor',
title: terminalStrings.split.value,
icon: Codicon.splitHorizontal
},
undefined);
const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true);
return { primaryAction, dropdownAction, dropdownMenuActions: dropdownActions, className: 'terminal-tab-actions' };
return defaultProfileName!;
}
focusFindWidget() {

View file

@ -3,13 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/actions';
import { Codicon } from 'vs/base/common/codicons';
import { Schemas } from 'vs/base/common/network';
import { localize } from 'vs/nls';
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { ContextKeyAndExpr, ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { TerminalSettingId } from 'vs/platform/terminal/common/terminal';
import { MenuRegistry, MenuId, IMenuActionOptions, MenuItemAction, IMenu } from 'vs/platform/actions/common/actions';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyAndExpr, ContextKeyEqualsExpr, ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICreateTerminalOptions, IExtensionTerminalProfile, ITerminalProfile, TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
import { ResourceContextKey } from 'vs/workbench/common/resources';
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalCommandId, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalContextKeys, TerminalContextKeyStrings } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
@ -566,3 +570,89 @@ export function setupTerminalMenus(): void {
when: ResourceContextKey.Scheme.isEqualTo(Schemas.vscodeTerminal)
});
}
export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITerminalProfile[], defaultProfileName: string, contributedProfiles: readonly IExtensionTerminalProfile[], instantiationService: IInstantiationService, terminalService: ITerminalService, contextKeyService: IContextKeyService, commandService: ICommandService, dropdownMenu: IMenu): {
primaryAction: MenuItemAction,
dropdownAction: IAction,
dropdownMenuActions: IAction[],
className: string,
dropdownIcon?: string
} {
const dropdownActions: IAction[] = [];
const submenuActions: IAction[] = [];
for (const p of profiles) {
const isDefault = p.profileName === defaultProfileName;
const options: IMenuActionOptions = {
arg: {
config: p,
target
} as ICreateTerminalOptions,
shouldForwardArgs: true
};
if (isDefault) {
dropdownActions.unshift(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService));
submenuActions.unshift(new MenuItemAction({ id: TerminalCommandId.Split, title: localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService));
} else {
dropdownActions.push(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService));
submenuActions.push(new MenuItemAction({ id: TerminalCommandId.Split, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, contextKeyService, commandService));
}
}
for (const contributed of contributedProfiles) {
const isDefault = contributed.title === defaultProfileName;
const title = isDefault ? localize('defaultTerminalProfile', "{0} (Default)", contributed.title.replace(/[\n\r\t]/g, '')) : contributed.title.replace(/[\n\r\t]/g, '');
dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
forceSplit: false,
target
})));
submenuActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
forceSplit: true,
target
})));
}
if (dropdownActions.length > 0) {
dropdownActions.push(new SubmenuAction('split.profile', 'Split...', submenuActions));
dropdownActions.push(new Separator());
}
for (const [, configureActions] of dropdownMenu.getActions()) {
for (const action of configureActions) {
// make sure the action is a MenuItemAction
if ('alt' in action) {
dropdownActions.push(action);
}
}
}
const primaryAction = instantiationService.createInstance(
MenuItemAction,
{
id: target === TerminalLocation.TerminalView ? TerminalCommandId.New : TerminalCommandId.CreateTerminalEditor,
title: localize('terminal.new', "New Terminal"),
icon: Codicon.plus
},
{
id: TerminalCommandId.Split,
title: terminalStrings.split.value,
icon: Codicon.splitHorizontal
},
{
shouldForwardArgs: true,
arg: { target } as ICreateTerminalOptions,
});
const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true);
return { primaryAction, dropdownAction, dropdownMenuActions: dropdownActions, className: 'terminal-tab-actions' };
}

View file

@ -5,7 +5,7 @@
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { Action, IAction, Separator, SubmenuAction } from 'vs/base/common/actions';
import { Action, IAction } from 'vs/base/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@ -21,7 +21,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND, EDITOR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
import { IMenu, IMenuActionOptions, IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { IMenu, IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ITerminalProfileResolverService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalSettingId, ITerminalProfile, TerminalLocation, ICreateTerminalOptions } from 'vs/platform/terminal/common/terminal';
import { ActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
@ -36,7 +36,6 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { getColorForSeverity } from 'vs/workbench/contrib/terminal/browser/terminalStatusList';
import { createAndFillInContextMenuActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { TerminalTabContextMenuGroup } from 'vs/workbench/contrib/terminal/browser/terminalMenus';
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
@ -45,6 +44,7 @@ import { getColorClass, getUriClasses } from 'vs/workbench/contrib/terminal/brow
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { withNullAsUndefined } from 'vs/base/common/types';
import { DataTransfers } from 'vs/base/browser/dnd';
import { getTerminalActionBarArgs } from 'vs/workbench/contrib/terminal/browser/terminalMenus';
export class TerminalViewPane extends ViewPane {
private _actions: IAction[] | undefined;
@ -203,7 +203,8 @@ export class TerminalViewPane extends ViewPane {
if (this._tabButtons) {
this._tabButtons.dispose();
}
const actions = this._getTabActionBarArgs(this._terminalService.availableProfiles);
const actions = getTerminalActionBarArgs(TerminalLocation.TerminalView, this._terminalService.availableProfiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu);
this._tabButtons = new DropdownWithPrimaryActionViewItem(actions.primaryAction, actions.dropdownAction, actions.dropdownMenuActions, actions.className, this._contextMenuService, this._keybindingService, this._notificationService, this._contextKeyService);
this._updateTabActionBar(this._terminalService.availableProfiles);
@ -213,103 +214,23 @@ export class TerminalViewPane extends ViewPane {
return super.getActionViewItem(action);
}
private _getKeybindingLabel(action: IAction): string | undefined {
return withNullAsUndefined(this._keybindingService.lookupKeybinding(action.id)?.getLabel());
}
private _updateTabActionBar(profiles: ITerminalProfile[]): void {
const actions = this._getTabActionBarArgs(profiles);
this._tabButtons?.update(actions.dropdownAction, actions.dropdownMenuActions);
}
private _getTabActionBarArgs(profiles: ITerminalProfile[]): {
primaryAction: MenuItemAction,
dropdownAction: IAction,
dropdownMenuActions: IAction[],
className: string,
dropdownIcon?: string
} {
const dropdownActions: IAction[] = [];
const submenuActions: IAction[] = [];
private _getDefaultProfileName(): string {
let defaultProfileName;
try {
defaultProfileName = this._terminalService.getDefaultProfileName();
} catch (e) {
defaultProfileName = this._terminalProfileResolverService.defaultProfileName;
}
for (const p of profiles) {
const isDefault = p.profileName === defaultProfileName;
const options: IMenuActionOptions = {
arg: {
config: p,
target: TerminalLocation.TerminalView
} as ICreateTerminalOptions,
shouldForwardArgs: true
};
if (isDefault) {
dropdownActions.unshift(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: nls.localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, this._contextKeyService, this._commandService));
submenuActions.unshift(new MenuItemAction({ id: TerminalCommandId.Split, title: nls.localize('defaultTerminalProfile', "{0} (Default)", p.profileName), category: TerminalTabContextMenuGroup.Profile }, undefined, options, this._contextKeyService, this._commandService));
} else {
dropdownActions.push(new MenuItemAction({ id: TerminalCommandId.NewWithProfile, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, this._contextKeyService, this._commandService));
submenuActions.push(new MenuItemAction({ id: TerminalCommandId.Split, title: p.profileName.replace(/[\n\r\t]/g, ''), category: TerminalTabContextMenuGroup.Profile }, undefined, options, this._contextKeyService, this._commandService));
}
}
return defaultProfileName!;
}
for (const contributed of this._terminalContributionService.terminalProfiles) {
const isDefault = contributed.title === defaultProfileName;
const title = isDefault ? nls.localize('defaultTerminalProfile', "{0} (Default)", contributed.title.replace(/[\n\r\t]/g, '')) : contributed.title.replace(/[\n\r\t]/g, '');
dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => this._terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
forceSplit: false
})));
submenuActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => this._terminalService.createTerminal({
config: {
extensionIdentifier: contributed.extensionIdentifier,
id: contributed.id,
title
},
forceSplit: true
})));
}
private _getKeybindingLabel(action: IAction): string | undefined {
return withNullAsUndefined(this._keybindingService.lookupKeybinding(action.id)?.getLabel());
}
if (dropdownActions.length > 0) {
dropdownActions.push(new SubmenuAction('split.profile', 'Split...', submenuActions));
dropdownActions.push(new Separator());
}
for (const [, configureActions] of this._dropdownMenu.getActions()) {
for (const action of configureActions) {
// make sure the action is a MenuItemAction
if ('alt' in action) {
dropdownActions.push(action);
}
}
}
const primaryAction = this._instantiationService.createInstance(
MenuItemAction,
{
id: TerminalCommandId.New,
title: nls.localize('terminal.new', "New Terminal"),
icon: Codicon.plus
},
{
id: TerminalCommandId.Split,
title: terminalStrings.split.value,
icon: Codicon.splitHorizontal
},
{
shouldForwardArgs: true,
arg: { target: TerminalLocation.TerminalView } as ICreateTerminalOptions,
});
const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true);
return { primaryAction, dropdownAction, dropdownMenuActions: dropdownActions, className: 'terminal-tab-actions' };
private _updateTabActionBar(profiles: ITerminalProfile[]): void {
const actions = getTerminalActionBarArgs(TerminalLocation.TerminalView, profiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu);
this._tabButtons?.update(actions.dropdownAction, actions.dropdownMenuActions);
}
override focus() {