Skip to content

Commit 7e09a61

Browse files
committed
Add new terminal window to + menu, create 'new' section
Fixes microsoft#259417
1 parent 98db55e commit 7e09a61

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

src/vs/workbench/contrib/terminal/browser/terminal.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ export interface ITerminalService extends ITerminalInstanceHost {
287287
*/
288288
createTerminal(options?: ICreateTerminalOptions): Promise<ITerminalInstance>;
289289

290+
/**
291+
* Creates and focuses a terminal.
292+
* @param options The options to create the terminal with, when not specified the default
293+
* profile will be used at the default target.
294+
*/
295+
createAndFocusTerminal(options?: ICreateTerminalOptions): Promise<ITerminalInstance>;
296+
290297
/**
291298
* Creates a detached xterm instance which is not attached to the DOM or
292299
* tracked as a terminal instance.

src/vs/workbench/contrib/terminal/browser/terminalMenus.ts

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ICreateTerminalOptions, ITerminalLocationOptions, ITerminalService } fr
1616
import { TerminalCommandId, TERMINAL_VIEW_ID } from '../common/terminal.js';
1717
import { TerminalContextKeys, TerminalContextKeyStrings } from '../common/terminalContextKey.js';
1818
import { terminalStrings } from '../common/terminalStrings.js';
19-
import { ACTIVE_GROUP, SIDE_GROUP } from '../../../services/editor/common/editorService.js';
19+
import { ACTIVE_GROUP, AUX_WINDOW_GROUP, SIDE_GROUP } from '../../../services/editor/common/editorService.js';
2020
import { DisposableStore } from '../../../../base/common/lifecycle.js';
2121

2222
const enum ContextMenuGroup {
@@ -686,39 +686,45 @@ export function getTerminalActionBarArgs(location: ITerminalLocationOptions, pro
686686
className: string;
687687
dropdownIcon?: string;
688688
} {
689-
let dropdownActions: IAction[] = [];
690-
let submenuActions: IAction[] = [];
691-
profiles = profiles.filter(e => !e.isAutoDetected);
689+
const dropdownActions: IAction[] = [];
690+
const submenuActions: IAction[] = [];
692691
const splitLocation = (location === TerminalLocation.Editor || (typeof location === 'object' && 'viewColumn' in location && location.viewColumn === ACTIVE_GROUP)) ? { viewColumn: SIDE_GROUP } : { splitActiveTerminal: true };
692+
693+
dropdownActions.push(disposableStore.add(new Action(TerminalCommandId.New, terminalStrings.newInView, undefined, true, () => terminalService.createAndFocusTerminal())));
694+
dropdownActions.push(disposableStore.add(new Action(TerminalCommandId.NewInNewWindow, terminalStrings.newInNewWindow.short, undefined, true, () => terminalService.createAndFocusTerminal({
695+
location: { viewColumn: AUX_WINDOW_GROUP }
696+
}))));
697+
dropdownActions.push(disposableStore.add(new Action(TerminalCommandId.Split, terminalStrings.split.value, undefined, true, () => terminalService.createAndFocusTerminal({
698+
location: splitLocation
699+
}))));
700+
dropdownActions.push(new Separator());
701+
702+
profiles = profiles.filter(e => !e.isAutoDetected);
693703
for (const p of profiles) {
694704
const isDefault = p.profileName === defaultProfileName;
695705
const options: ICreateTerminalOptions = { config: p, location };
696706
const splitOptions: ICreateTerminalOptions = { config: p, location: splitLocation };
697707
const sanitizedProfileName = p.profileName.replace(/[\n\r\t]/g, '');
698708
dropdownActions.push(disposableStore.add(new Action(TerminalCommandId.NewWithProfile, isDefault ? localize('defaultTerminalProfile', "{0} (Default)", sanitizedProfileName) : sanitizedProfileName, undefined, true, async () => {
699-
const instance = await terminalService.createTerminal(options);
700-
terminalService.setActiveInstance(instance);
701-
await terminalService.focusActiveInstance();
709+
await terminalService.createAndFocusTerminal(options);
702710
})));
703711
submenuActions.push(disposableStore.add(new Action(TerminalCommandId.Split, isDefault ? localize('defaultTerminalProfile', "{0} (Default)", sanitizedProfileName) : sanitizedProfileName, undefined, true, async () => {
704-
const instance = await terminalService.createTerminal(splitOptions);
705-
terminalService.setActiveInstance(instance);
706-
await terminalService.focusActiveInstance();
712+
await terminalService.createAndFocusTerminal(splitOptions);
707713
})));
708714
}
709715

710716
for (const contributed of contributedProfiles) {
711717
const isDefault = contributed.title === defaultProfileName;
712718
const title = isDefault ? localize('defaultTerminalProfile', "{0} (Default)", contributed.title.replace(/[\n\r\t]/g, '')) : contributed.title.replace(/[\n\r\t]/g, '');
713-
dropdownActions.push(disposableStore.add(new Action('contributed', title, undefined, true, () => terminalService.createTerminal({
719+
dropdownActions.push(disposableStore.add(new Action('contributed', title, undefined, true, () => terminalService.createAndFocusTerminal({
714720
config: {
715721
extensionIdentifier: contributed.extensionIdentifier,
716722
id: contributed.id,
717723
title
718724
},
719725
location
720726
}))));
721-
submenuActions.push(disposableStore.add(new Action('contributed-split', title, undefined, true, () => terminalService.createTerminal({
727+
submenuActions.push(disposableStore.add(new Action('contributed-split', title, undefined, true, () => terminalService.createAndFocusTerminal({
722728
config: {
723729
extensionIdentifier: contributed.extensionIdentifier,
724730
id: contributed.id,
@@ -728,25 +734,13 @@ export function getTerminalActionBarArgs(location: ITerminalLocationOptions, pro
728734
}))));
729735
}
730736

731-
const defaultProfileAction = dropdownActions.find(d => d.label.endsWith('(Default)'));
732-
if (defaultProfileAction) {
733-
dropdownActions = dropdownActions.filter(d => d !== defaultProfileAction).sort((a, b) => a.label.localeCompare(b.label));
734-
dropdownActions.unshift(defaultProfileAction);
735-
}
736-
737737
if (dropdownActions.length > 0) {
738-
dropdownActions.push(new SubmenuAction('split.profile', localize('splitTerminal', 'Split Terminal'), submenuActions));
738+
dropdownActions.push(new SubmenuAction('split.profile', localize('split.profile', 'Split Terminal with Profile'), submenuActions));
739739
dropdownActions.push(new Separator());
740740
}
741741
const actions = dropdownMenu.getActions();
742742
dropdownActions.push(...Separator.join(...actions.map(a => a[1])));
743743

744-
const defaultSubmenuProfileAction = submenuActions.find(d => d.label.endsWith('(Default)'));
745-
if (defaultSubmenuProfileAction) {
746-
submenuActions = submenuActions.filter(d => d !== defaultSubmenuProfileAction).sort((a, b) => a.label.localeCompare(b.label));
747-
submenuActions.unshift(defaultSubmenuProfileAction);
748-
}
749-
750744
const dropdownAction = disposableStore.add(new Action('refresh profiles', localize('launchProfile', 'Launch Profile...'), 'codicon-chevron-down', true));
751745
return { dropdownAction, dropdownMenuActions: dropdownActions, className: `terminal-tab-actions-${terminalService.resolveLocation(location)}` };
752746
}

src/vs/workbench/contrib/terminal/browser/terminalService.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,13 @@ export class TerminalService extends Disposable implements ITerminalService {
10361036
return instance;
10371037
}
10381038

1039+
async createAndFocusTerminal(options?: ICreateTerminalOptions): Promise<ITerminalInstance> {
1040+
const instance = await this.createTerminal(options);
1041+
this.setActiveInstance(instance);
1042+
await instance.focusWhenReady();
1043+
return instance;
1044+
}
1045+
10391046
private async _getContributedProfile(shellLaunchConfig: IShellLaunchConfig, options?: ICreateTerminalOptions): Promise<IExtensionTerminalProfile | undefined> {
10401047
if (options?.config && 'extensionIdentifier' in options.config) {
10411048
return options.config;

src/vs/workbench/contrib/terminal/common/terminalStrings.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { localize, localize2 } from '../../../../nls.js';
1111
export const terminalStrings = {
1212
terminal: localize('terminal', "Terminal"),
1313
new: localize('terminal.new', "New Terminal"),
14+
newInView: localize('terminal.newInView', "New in Terminal View"),
1415
doNotShowAgain: localize('doNotShowAgain', 'Do Not Show Again'),
1516
currentSessionCategory: localize('currentSessionCategory', 'current session'),
1617
previousSessionCategory: localize('previousSessionCategory', 'previous session'),
@@ -25,7 +26,10 @@ export const terminalStrings = {
2526
},
2627
moveToEditor: localize2('moveToEditor', "Move Terminal into Editor Area"),
2728
moveIntoNewWindow: localize2('moveIntoNewWindow', "Move Terminal into New Window"),
28-
newInNewWindow: localize2('newInNewWindow', "New Terminal in New Window"),
29+
newInNewWindow: {
30+
...localize2('newInNewWindow', "New Terminal in New Window"),
31+
short: localize('newInNewWindow.short', "New in New Window")
32+
},
2933
moveToTerminalPanel: localize2('workbench.action.terminal.moveToTerminalPanel', "Move Terminal into Panel"),
3034
changeIcon: localize2('workbench.action.terminal.changeIcon', "Change Icon..."),
3135
changeColor: localize2('workbench.action.terminal.changeColor', "Change Color..."),

0 commit comments

Comments
 (0)