Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -64,7 +64,15 @@ export class CommandTrackerAddon implements ICommandTracker, ITerminalAddon {
}
let markerIndex;
if (this._currentMarker === Boundary.Bottom) {
const currentLineY = Math.min(this._getLine(this._terminal, this._currentMarker), this._terminal.buffer.baseY);
const viewportY = this._terminal.buffer.viewportY;
if (!retainSelection && currentLineY !== viewportY) {
// The user has scrolled, find the line based on the current scroll position. This only
// works when not retaining selection
const markersBelowViewport = this._terminal.markers.filter(e => e.line >= viewportY).length;
// -1 will scroll to the top
markerIndex = this._terminal.markers.length - markersBelowViewport - 1;
} else if (this._currentMarker === Boundary.Bottom) {
markerIndex = this._terminal.markers.length - 1;
} else if (this._currentMarker === Boundary.Top) {
markerIndex = -1;
@@ -95,7 +103,15 @@ export class CommandTrackerAddon implements ICommandTracker, ITerminalAddon {
}
let markerIndex;
if (this._currentMarker === Boundary.Bottom) {
const currentLineY = Math.min(this._getLine(this._terminal, this._currentMarker), this._terminal.buffer.baseY);
const viewportY = this._terminal.buffer.viewportY;
if (!retainSelection && currentLineY !== viewportY) {
// The user has scrolled, find the line based on the current scroll position. This only
// works when not retaining selection
const markersAboveViewport = this._terminal.markers.filter(e => e.line <= viewportY).length;
// markers.length will scroll to the bottom
markerIndex = markersAboveViewport;
} else if (this._currentMarker === Boundary.Bottom) {
markerIndex = this._terminal.markers.length;
} else if (this._currentMarker === Boundary.Top) {
markerIndex = 0;

View File

@@ -38,4 +38,4 @@
.monaco-workbench .panel.integrated-terminal .xterm .xterm-viewport::-webkit-scrollbar-thumb:window-inactive {
background-color: inherit;
}
}

View File

@@ -10,6 +10,7 @@
flex-direction: column;
background-color: transparent!important;
user-select: initial;
-webkit-user-select: initial;
position: relative;
}
@@ -104,6 +105,7 @@
bottom: 0;
left: 0;
user-select: none;
-webkit-user-select: none;
}
.monaco-workbench .panel.integrated-terminal .monaco-split-view2.vertical .split-view-view:not(:last-child) .xterm {
/* When vertical and NOT the bottom terminal, align to the top instead to prevent the output jumping around erratically */
@@ -149,6 +151,11 @@
cursor: -webkit-image-set(url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAL0lEQVQoz2NgCD3x//9/BhBYBWdhgFVAiVW4JBFKGIa4AqD0//9D3pt4I4tAdAMAHTQ/j5Zom30AAAAASUVORK5CYII=') 1x, url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVRIx2NgYGBY/R8I/vx5eelX3n82IJ9FxGf6tksvf/8FiTMQAcAGQMDvSwu09abffY8QYSAScNk45G198eX//yev73/4///701eh//kZSARckrNBRvz//+8+6ZohwCzjGNjdgQxkAg7B9WADeBjIBqtJCbhRA0YNoIkBSNmaPEMoNmA0FkYNoFKhapJ6FGyAH3nauaSmPfwI0v/3OukVi0CIZ+F25KrtYcx/CTIy0e+rC7R1Z4KMICVTQQ14feVXIbR695u14+Ir4gwAAD49E54wc1kWAAAAAElFTkSuQmCC') 2x) 5 8, text;
}
/* Override default xterm style to make !important so it takes precedence over custom mac cursor */
.xterm.xterm-cursor-pointer {
cursor: pointer!important;
}
.monaco-workbench .quick-open-terminal-configure {
background-image: url('configure-light.svg');
}

View File

@@ -43,7 +43,6 @@
font-feature-settings: "liga" 0;
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}

View File

@@ -20,7 +20,7 @@ import * as panel from 'vs/workbench/browser/panel';
import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { Extensions as QuickOpenExtensions, IQuickOpenRegistry, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen';
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
import { ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SendSequenceTerminalCommand, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand, NavigationModeFocusPreviousTerminalAction, NavigationModeFocusNextTerminalAction, NavigationModeExitTerminalAction, ManageWorkspaceShellPermissionsTerminalCommand, CreateNewWithCwdTerminalCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions';
import { ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SendSequenceTerminalCommand, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand, NavigationModeFocusPreviousTerminalAction, NavigationModeFocusNextTerminalAction, NavigationModeExitTerminalAction, ManageWorkspaceShellPermissionsTerminalCommand, CreateNewWithCwdTerminalCommand, RenameWithArgTerminalCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions';
import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel';
import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen';
import { KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminal';
@@ -35,6 +35,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { registerShellConfiguration } from 'vs/workbench/contrib/terminal/common/terminalShellConfig';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
registerSingleton(ITerminalService, TerminalService, true);
@@ -47,7 +48,7 @@ const quickOpenRegistry = (Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Q
const inTerminalsPicker = 'inTerminalPicker';
quickOpenRegistry.registerQuickOpenHandler(
new QuickOpenHandlerDescriptor(
QuickOpenHandlerDescriptor.create(
TerminalPickerHandler,
TerminalPickerHandler.ID,
TERMINAL_PICKER_PREFIX,
@@ -168,6 +169,11 @@ configurationRegistry.registerConfiguration({
type: 'number',
default: DEFAULT_LINE_HEIGHT
},
'terminal.integrated.minimumContrastRatio': {
description: nls.localize('terminal.integrated.minimumContrastRatio', "When set the foreground color of each cell will change to try meet the contrast ratio specified. Example values:\n\n- 1: The default, do nothing.\n- 4.5: Minimum for WCAG AA compliance.\n- 7: Minimum for WCAG AAA compliance.\n- 21: White on black or black on white."),
type: 'number',
default: 1
},
'terminal.integrated.fontWeight': {
type: 'string',
enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
@@ -208,11 +214,12 @@ configurationRegistry.registerConfiguration({
},
'terminal.integrated.rendererType': {
type: 'string',
enum: ['auto', 'canvas', 'dom'],
enum: ['auto', 'canvas', 'dom', 'experimentalWebgl'],
enumDescriptions: [
nls.localize('terminal.integrated.rendererType.auto', "Let Azure Data Studio guess which renderer to use."),// {{SQL CARBON EDIT}} Change product name to ADS
nls.localize('terminal.integrated.rendererType.canvas', "Use the standard GPU/canvas-based renderer"),
nls.localize('terminal.integrated.rendererType.dom', "Use the fallback DOM-based renderer.")
nls.localize('terminal.integrated.rendererType.auto', "Let Azure Data Studio which renderer to use."), // {{SQL CARBON EDIT}} Change product name to ADS
nls.localize('terminal.integrated.rendererType.canvas', "Use the standard GPU/canvas-based renderer."),
nls.localize('terminal.integrated.rendererType.dom', "Use the fallback DOM-based renderer."),
nls.localize('terminal.integrated.rendererType.experimentalWebgl', "Use the experimental webgl-based renderer. Note that this has some [known issues](https://github.com/xtermjs/xterm.js/issues?q=is%3Aopen+is%3Aissue+label%3Aarea%2Faddon%2Fwebgl) and this will only be enabled for new terminals (not hot swappable like the other renderers).")
],
default: 'auto',
description: nls.localize('terminal.integrated.rendererType', "Controls how the terminal is rendered.")
@@ -326,11 +333,11 @@ configurationRegistry.registerConfiguration({
});
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenTermAction, QuickOpenTermAction.ID, QuickOpenTermAction.LABEL), 'Terminal: Switch Active Terminal', nls.localize('terminal', "Terminal"));
registry.registerWorkbenchAction(SyncActionDescriptor.create(QuickOpenTermAction, QuickOpenTermAction.ID, QuickOpenTermAction.LABEL), 'Terminal: Switch Active Terminal', nls.localize('terminal', "Terminal"));
const actionBarRegistry = Registry.as<IActionBarRegistry>(ActionBarExtensions.Actionbar);
actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionTermContributor);
(<panel.PanelRegistry>Registry.as(panel.Extensions.Panels)).registerPanel(new panel.PanelDescriptor(
(<panel.PanelRegistry>Registry.as(panel.Extensions.Panels)).registerPanel(panel.PanelDescriptor.create(
TerminalPanel,
TERMINAL_PANEL_ID,
nls.localize('terminal', "Terminal"),
@@ -343,28 +350,20 @@ Registry.as<panel.PanelRegistry>(panel.Extensions.Panels).setDefaultPanelId(TERM
// On mac cmd+` is reserved to cycle between windows, that's why the keybindings use WinCtrl
const category = TERMINAL_ACTION_CATEGORY;
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_C,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS)), 'Terminal: Copy Selection', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK,
mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_BACKTICK }
}), 'Terminal: Create New Integrated Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearSelectionTerminalAction, ClearSelectionTerminalAction.ID, ClearSelectionTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ClearSelectionTerminalAction, ClearSelectionTerminalAction.ID, ClearSelectionTerminalAction.LABEL, {
primary: KeyCode.Escape,
linux: { primary: KeyCode.Escape }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE)), 'Terminal: Clear Selection', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewInActiveWorkspaceTerminalAction, CreateNewInActiveWorkspaceTerminalAction.ID, CreateNewInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (In Active Workspace)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusActiveTerminalAction, FocusActiveTerminalAction.ID, FocusActiveTerminalAction.LABEL), 'Terminal: Focus Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextTerminalAction, FocusNextTerminalAction.ID, FocusNextTerminalAction.LABEL), 'Terminal: Focus Next Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), 'Terminal: Focus Previous Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_V,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(CreateNewInActiveWorkspaceTerminalAction, CreateNewInActiveWorkspaceTerminalAction.ID, CreateNewInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (In Active Workspace)', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusActiveTerminalAction, FocusActiveTerminalAction.ID, FocusActiveTerminalAction.LABEL), 'Terminal: Focus Terminal', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusNextTerminalAction, FocusNextTerminalAction.ID, FocusNextTerminalAction.LABEL), 'Terminal: Focus Next Terminal', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), 'Terminal: Focus Previous Terminal', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, {
// Don't use ctrl+a by default as that would override the common go to start
// of prompt shell binding
primary: 0,
@@ -373,82 +372,82 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTermina
// makes it easier for users to see how it works though.
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_A }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select All', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), 'Terminal: Run Selected Text In Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunActiveFileInTerminalAction, RunActiveFileInTerminalAction.ID, RunActiveFileInTerminalAction.LABEL), 'Terminal: Run Active File In Active Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), 'Terminal: Run Selected Text In Active Terminal', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(RunActiveFileInTerminalAction, RunActiveFileInTerminalAction.ID, RunActiveFileInTerminalAction.LABEL), 'Terminal: Run Active File In Active Terminal', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.US_BACKTICK,
mac: { primary: KeyMod.WinCtrl | KeyCode.US_BACKTICK }
}), 'View: Toggle Integrated Terminal', nls.localize('viewCategory', "View"));
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownTerminalAction, ScrollDownTerminalAction.ID, ScrollDownTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollDownTerminalAction, ScrollDownTerminalAction.ID, ScrollDownTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Line)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownPageTerminalAction, ScrollDownPageTerminalAction.ID, ScrollDownPageTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollDownPageTerminalAction, ScrollDownPageTerminalAction.ID, ScrollDownPageTerminalAction.LABEL, {
primary: KeyMod.Shift | KeyCode.PageDown,
mac: { primary: KeyCode.PageDown }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Page)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToBottomTerminalAction, ScrollToBottomTerminalAction.ID, ScrollToBottomTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollToBottomTerminalAction, ScrollToBottomTerminalAction.ID, ScrollToBottomTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.End,
linux: { primary: KeyMod.Shift | KeyCode.End }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Bottom', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpTerminalAction, ScrollUpTerminalAction.ID, ScrollUpTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollUpTerminalAction, ScrollUpTerminalAction.ID, ScrollUpTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow },
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Line)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpPageTerminalAction, ScrollUpPageTerminalAction.ID, ScrollUpPageTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollUpPageTerminalAction, ScrollUpPageTerminalAction.ID, ScrollUpPageTerminalAction.LABEL, {
primary: KeyMod.Shift | KeyCode.PageUp,
mac: { primary: KeyCode.PageUp }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Page)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToTopTerminalAction, ScrollToTopTerminalAction.ID, ScrollToTopTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollToTopTerminalAction, ScrollToTopTerminalAction.ID, ScrollToTopTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.Home,
linux: { primary: KeyMod.Shift | KeyCode.Home }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Top', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAction, ClearTerminalAction.ID, ClearTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ClearTerminalAction, ClearTerminalAction.ID, ClearTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ManageWorkspaceShellPermissionsTerminalCommand, ManageWorkspaceShellPermissionsTerminalCommand.ID, ManageWorkspaceShellPermissionsTerminalCommand.LABEL), 'Terminal: Manage Workspace Shell Permissions', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ManageWorkspaceShellPermissionsTerminalCommand, ManageWorkspaceShellPermissionsTerminalCommand.ID, ManageWorkspaceShellPermissionsTerminalCommand.LABEL), 'Terminal: Manage Workspace Shell Permissions', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_F
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Find Widget', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_F
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Focus Find Widget', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, {
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape]
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE)), 'Terminal: Hide Find Widget', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordLeftTerminalAction, DeleteWordLeftTerminalAction.ID, DeleteWordLeftTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(DeleteWordLeftTerminalAction, DeleteWordLeftTerminalAction.ID, DeleteWordLeftTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.Backspace,
mac: { primary: KeyMod.Alt | KeyCode.Backspace }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Left', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordRightTerminalAction, DeleteWordRightTerminalAction.ID, DeleteWordRightTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(DeleteWordRightTerminalAction, DeleteWordRightTerminalAction.ID, DeleteWordRightTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.Delete,
mac: { primary: KeyMod.Alt | KeyCode.Delete }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Right', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteToLineStartTerminalAction, DeleteToLineStartTerminalAction.ID, DeleteToLineStartTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(DeleteToLineStartTerminalAction, DeleteToLineStartTerminalAction.ID, DeleteToLineStartTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete To Line Start', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineStartTerminalAction, MoveToLineStartTerminalAction.ID, MoveToLineStartTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(MoveToLineStartTerminalAction, MoveToLineStartTerminalAction.ID, MoveToLineStartTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.LeftArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line Start', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineEndTerminalAction, MoveToLineEndTerminalAction.ID, MoveToLineEndTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(MoveToLineEndTerminalAction, MoveToLineEndTerminalAction.ID, MoveToLineEndTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.RightArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line End', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitTerminalAction, SplitTerminalAction.ID, SplitTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SplitTerminalAction, SplitTerminalAction.ID, SplitTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_5,
mac: {
primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH,
secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_5]
}
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Split Terminal', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitInActiveWorkspaceTerminalAction, SplitInActiveWorkspaceTerminalAction.ID, SplitInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Split Terminal (In Active Workspace)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousPaneTerminalAction, FocusPreviousPaneTerminalAction.ID, FocusPreviousPaneTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SplitInActiveWorkspaceTerminalAction, SplitInActiveWorkspaceTerminalAction.ID, SplitInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Split Terminal (In Active Workspace)', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusPreviousPaneTerminalAction, FocusPreviousPaneTerminalAction.ID, FocusPreviousPaneTerminalAction.LABEL, {
primary: KeyMod.Alt | KeyCode.LeftArrow,
secondary: [KeyMod.Alt | KeyCode.UpArrow],
mac: {
@@ -456,7 +455,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousPan
secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.UpArrow]
}
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Previous Pane', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextPaneTerminalAction, FocusNextPaneTerminalAction.ID, FocusNextPaneTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FocusNextPaneTerminalAction, FocusNextPaneTerminalAction.ID, FocusNextPaneTerminalAction.LABEL, {
primary: KeyMod.Alt | KeyCode.RightArrow,
secondary: [KeyMod.Alt | KeyCode.DownArrow],
mac: {
@@ -464,101 +463,116 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextPaneTer
secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.DownArrow]
}
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Next Pane', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneLeftTerminalAction, ResizePaneLeftTerminalAction.ID, ResizePaneLeftTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ResizePaneLeftTerminalAction, ResizePaneLeftTerminalAction.ID, ResizePaneLeftTerminalAction.LABEL, {
primary: 0,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow },
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Left', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneRightTerminalAction, ResizePaneRightTerminalAction.ID, ResizePaneRightTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ResizePaneRightTerminalAction, ResizePaneRightTerminalAction.ID, ResizePaneRightTerminalAction.LABEL, {
primary: 0,
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow },
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Right', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneUpTerminalAction, ResizePaneUpTerminalAction.ID, ResizePaneUpTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ResizePaneUpTerminalAction, ResizePaneUpTerminalAction.ID, ResizePaneUpTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Up', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneDownTerminalAction, ResizePaneDownTerminalAction.ID, ResizePaneDownTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ResizePaneDownTerminalAction, ResizePaneDownTerminalAction.ID, ResizePaneDownTerminalAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Down', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.UpArrow }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate())), 'Terminal: Scroll To Previous Command', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToNextCommandAction, ScrollToNextCommandAction.ID, ScrollToNextCommandAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ScrollToNextCommandAction, ScrollToNextCommandAction.ID, ScrollToNextCommandAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyCode.DownArrow }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate())), 'Terminal: Scroll To Next Command', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousCommandAction, SelectToPreviousCommandAction.ID, SelectToPreviousCommandAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectToPreviousCommandAction, SelectToPreviousCommandAction.ID, SelectToPreviousCommandAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Previous Command', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextCommandAction, SelectToNextCommandAction.ID, SelectToNextCommandAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectToNextCommandAction, SelectToNextCommandAction.ID, SelectToNextCommandAction.LABEL, {
primary: 0,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Next Command', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NavigationModeExitTerminalAction, NavigationModeExitTerminalAction.ID, NavigationModeExitTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NavigationModeExitTerminalAction, NavigationModeExitTerminalAction.ID, NavigationModeExitTerminalAction.LABEL, {
primary: KeyCode.Escape
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED)), 'Terminal: Exit Navigation Mode', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NavigationModeFocusPreviousTerminalAction, NavigationModeFocusPreviousTerminalAction.ID, NavigationModeFocusPreviousTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NavigationModeFocusPreviousTerminalAction, NavigationModeFocusPreviousTerminalAction.ID, NavigationModeFocusPreviousTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.UpArrow
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED)), 'Terminal: Focus Previous Line (Navigation Mode)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NavigationModeFocusPreviousTerminalAction, NavigationModeFocusPreviousTerminalAction.ID, NavigationModeFocusPreviousTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NavigationModeFocusPreviousTerminalAction, NavigationModeFocusPreviousTerminalAction.ID, NavigationModeFocusPreviousTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.UpArrow
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED)), 'Terminal: Focus Previous Line (Navigation Mode)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NavigationModeFocusNextTerminalAction, NavigationModeFocusNextTerminalAction.ID, NavigationModeFocusNextTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NavigationModeFocusNextTerminalAction, NavigationModeFocusNextTerminalAction.ID, NavigationModeFocusNextTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.DownArrow
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED)), 'Terminal: Focus Next Line (Navigation Mode)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NavigationModeFocusNextTerminalAction, NavigationModeFocusNextTerminalAction.ID, NavigationModeFocusNextTerminalAction.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(NavigationModeFocusNextTerminalAction, NavigationModeFocusNextTerminalAction.ID, NavigationModeFocusNextTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.DownArrow
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED)), 'Terminal: Focus Next Line (Navigation Mode)', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousLineAction, SelectToPreviousLineAction.ID, SelectToPreviousLineAction.LABEL), 'Terminal: Select To Previous Line', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextLineAction, SelectToNextLineAction.ID, SelectToNextLineAction.LABEL), 'Terminal: Select To Next Line', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleEscapeSequenceLoggingAction, ToggleEscapeSequenceLoggingAction.ID, ToggleEscapeSequenceLoggingAction.LABEL), 'Terminal: Toggle Escape Sequence Logging', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID, ToggleRegexCommand.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectToPreviousLineAction, SelectToPreviousLineAction.ID, SelectToPreviousLineAction.LABEL), 'Terminal: Select To Previous Line', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(SelectToNextLineAction, SelectToNextLineAction.ID, SelectToNextLineAction.LABEL), 'Terminal: Select To Next Line', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleEscapeSequenceLoggingAction, ToggleEscapeSequenceLoggingAction.ID, ToggleEscapeSequenceLoggingAction.LABEL), 'Terminal: Toggle Escape Sequence Logging', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleRegexCommand, ToggleRegexCommand.ID, ToggleRegexCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_R,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R }
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using regex');
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID_TERMINAL_FOCUS, ToggleRegexCommand.LABEL, {
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using regex', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleRegexCommand, ToggleRegexCommand.ID, ToggleRegexCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_R,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find using regex', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID, ToggleWholeWordCommand.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleWholeWordCommand, ToggleWholeWordCommand.ID, ToggleWholeWordCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_W,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W }
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using whole word');
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID_TERMINAL_FOCUS, ToggleWholeWordCommand.LABEL, {
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using whole word', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleWholeWordCommand, ToggleWholeWordCommand.ID, ToggleWholeWordCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_W,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find using whole word', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID, ToggleCaseSensitiveCommand.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID, ToggleCaseSensitiveCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_C,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C }
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using case sensitive');
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID_TERMINAL_FOCUS, ToggleCaseSensitiveCommand.LABEL, {
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find using case sensitive', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID, ToggleCaseSensitiveCommand.LABEL, {
primary: KeyMod.Alt | KeyCode.KEY_C,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find using case sensitive', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID_TERMINAL_FOCUS, FindNext.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FindNext, FindNext.ID, FindNext.LABEL, {
primary: KeyCode.F3,
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3] }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find next', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID, FindNext.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FindNext, FindNext.ID, FindNext.LABEL, {
primary: KeyCode.F3,
secondary: [KeyMod.Shift | KeyCode.Enter],
mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3, KeyMod.Shift | KeyCode.Enter] }
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find next');
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID_TERMINAL_FOCUS, FindPrevious.LABEL, {
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find next', category);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FindPrevious, FindPrevious.ID, FindPrevious.LABEL, {
primary: KeyMod.Shift | KeyCode.F3,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3] },
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find previous', category);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID, FindPrevious.LABEL, {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(FindPrevious, FindPrevious.ID, FindPrevious.LABEL, {
primary: KeyMod.Shift | KeyCode.F3,
secondary: [KeyCode.Enter],
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3, KeyCode.Enter] },
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find previous');
}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find previous', category);
// Commands might be affected by Web restrictons
if (BrowserFeatures.clipboard.writeText) {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_C,
win: { primary: KeyMod.CtrlCmd | KeyCode.KEY_C, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C] },
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }
}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS)), 'Terminal: Copy Selection', category);
}
if (BrowserFeatures.clipboard.readText) {
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.KEY_V,
win: { primary: KeyMod.CtrlCmd | KeyCode.KEY_V, secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V] },
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category);
}
(new SendSequenceTerminalCommand({
id: SendSequenceTerminalCommand.ID,
precondition: undefined,
@@ -576,6 +590,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, Fi
}]
}
})).register();
(new CreateNewWithCwdTerminalCommand({
id: CreateNewWithCwdTerminalCommand.ID,
precondition: undefined,
@@ -597,6 +612,28 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, Fi
}
})).register();
(new RenameWithArgTerminalCommand({
id: RenameWithArgTerminalCommand.ID,
precondition: undefined,
description: {
description: RenameWithArgTerminalCommand.LABEL,
args: [{
name: 'args',
schema: {
type: 'object',
required: ['name'],
properties: {
name: {
description: RenameWithArgTerminalCommand.NAME_ARG_LABEL,
type: 'string',
minLength: 1
}
}
}
}]
}
})).register();
setupTerminalCommands();
setupTerminalMenu();

View File

@@ -6,6 +6,7 @@
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
import { IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig, IDefaultShellAndArgsRequest, ISpawnExtHostProcessRequest, IStartExtensionTerminalRequest, IAvailableShellsRequest, ITerminalProcessExtHostProxy, ICommandTracker, INavigationMode, TitleEventSource, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IProcessEnvironment, Platform } from 'vs/base/common/platform';
@@ -31,6 +32,7 @@ export interface ITerminalInstanceService {
getXtermConstructor(): Promise<typeof XTermTerminal>;
getXtermWebLinksConstructor(): Promise<typeof XTermWebLinksAddon>;
getXtermSearchConstructor(): Promise<typeof XTermSearchAddon>;
getXtermWebglConstructor(): Promise<typeof XTermWebglAddon>;
createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper;
createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess;
@@ -141,7 +143,7 @@ export interface ITerminalService {
* @param path The path to be escaped and formatted.
* @returns An escaped version of the path to be execuded in the terminal.
*/
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise<string>;
preparePathForTerminalAsync(path: string, executable: string | undefined, title: string, shellType: TerminalShellType): Promise<string>;
extHostReady(remoteAuthority: string): void;
requestSpawnExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void;
@@ -167,6 +169,14 @@ export interface ISearchOptions {
incremental?: boolean;
}
export enum WindowsShellType {
CommandPrompt,
PowerShell,
Wsl,
GitBash
}
export type TerminalShellType = WindowsShellType | undefined;
export interface ITerminalInstance {
/**
* The ID of the terminal instance, this is an arbitrary number only used to identify the
@@ -228,6 +238,8 @@ export interface ITerminalInstance {
*/
onExit: Event<number | undefined>;
readonly exitCode: number | undefined;
processReady: Promise<void>;
/**
@@ -236,6 +248,11 @@ export interface ITerminalInstance {
*/
readonly title: string;
/**
* The shell type of the terminal.
*/
readonly shellType: TerminalShellType;
/**
* The focus state of the terminal before exiting.
*/
@@ -431,6 +448,11 @@ export interface ITerminalInstance {
*/
setTitle(title: string, eventSource: TitleEventSource): void;
/**
* Sets the shell type of the terminal instance.
*/
setShellType(shellType: TerminalShellType): void;
waitForTitle(): Promise<string>;
setDimensions(dimensions: ITerminalDimensions): void;

View File

@@ -305,17 +305,7 @@ export class CreateNewWithCwdTerminalCommand extends Command {
public runCommand(accessor: ServicesAccessor, args: { cwd: string } | undefined): Promise<void> {
const terminalService = accessor.get(ITerminalService);
const configurationResolverService = accessor.get(IConfigurationResolverService);
const workspaceContextService = accessor.get(IWorkspaceContextService);
const historyService = accessor.get(IHistoryService);
const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(Schemas.file);
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? withNullAsUndefined(workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri)) : undefined;
let cwd: string | undefined;
if (args && args.cwd) {
cwd = configurationResolverService.resolve(lastActiveWorkspaceRoot, args.cwd);
}
const instance = terminalService.createTerminal({ cwd });
const instance = terminalService.createTerminal({ cwd: args?.cwd });
if (!instance) {
return Promise.resolve(undefined);
}
@@ -722,7 +712,7 @@ export class RunActiveFileInTerminalAction extends Action {
return Promise.resolve(undefined);
}
return this.terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title).then(path => {
return this.terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title, instance.shellType).then(path => {
instance.sendText(path, true);
return this.terminalService.showPanel();
});
@@ -1065,6 +1055,31 @@ export class RenameTerminalAction extends Action {
});
}
}
export class RenameWithArgTerminalCommand extends Command {
public static readonly ID = TERMINAL_COMMAND_ID.RENAME_WITH_ARG;
public static readonly LABEL = nls.localize('workbench.action.terminal.renameWithArg', "Rename the Currently Active Terminal");
public static readonly NAME_ARG_LABEL = nls.localize('workbench.action.terminal.renameWithArg.name', "The new name for the terminal");
public runCommand(
accessor: ServicesAccessor,
args?: { name?: string }
): void {
const notificationService = accessor.get(INotificationService);
const terminalInstance = accessor.get(ITerminalService).getActiveInstance();
if (!terminalInstance) {
notificationService.warn(nls.localize('workbench.action.terminal.renameWithArg.noTerminal', "No active terminal to rename"));
return;
}
if (!args || !args.name) {
notificationService.warn(nls.localize('workbench.action.terminal.renameWithArg.noName', "No name argument provided"));
return;
}
terminalInstance.setTitle(args.name, TitleEventSource.Api);
}
}
export class FocusTerminalFindWidgetAction extends Action {
@@ -1328,7 +1343,6 @@ abstract class ToggleFindOptionCommand extends Action {
export class ToggleRegexCommand extends ToggleFindOptionCommand {
public static readonly ID = TERMINAL_COMMAND_ID.TOGGLE_FIND_REGEX;
public static readonly ID_TERMINAL_FOCUS = TERMINAL_COMMAND_ID.TOGGLE_FIND_REGEX_TERMINAL_FOCUS;
public static readonly LABEL = nls.localize('workbench.action.terminal.toggleFindRegex', "Toggle find using regex");
protected runInner(state: FindReplaceState): void {
@@ -1338,7 +1352,6 @@ export class ToggleRegexCommand extends ToggleFindOptionCommand {
export class ToggleWholeWordCommand extends ToggleFindOptionCommand {
public static readonly ID = TERMINAL_COMMAND_ID.TOGGLE_FIND_WHOLE_WORD;
public static readonly ID_TERMINAL_FOCUS = TERMINAL_COMMAND_ID.TOGGLE_FIND_WHOLE_WORD_TERMINAL_FOCUS;
public static readonly LABEL = nls.localize('workbench.action.terminal.toggleFindWholeWord', "Toggle find using whole word");
protected runInner(state: FindReplaceState): void {
@@ -1348,7 +1361,6 @@ export class ToggleWholeWordCommand extends ToggleFindOptionCommand {
export class ToggleCaseSensitiveCommand extends ToggleFindOptionCommand {
public static readonly ID = TERMINAL_COMMAND_ID.TOGGLE_FIND_CASE_SENSITIVE;
public static readonly ID_TERMINAL_FOCUS = TERMINAL_COMMAND_ID.TOGGLE_FIND_CASE_SENSITIVE_TERMINAL_FOCUS;
public static readonly LABEL = nls.localize('workbench.action.terminal.toggleFindCaseSensitive', "Toggle find using case sensitive");
protected runInner(state: FindReplaceState): void {
@@ -1358,7 +1370,6 @@ export class ToggleCaseSensitiveCommand extends ToggleFindOptionCommand {
export class FindNext extends Action {
public static readonly ID = TERMINAL_COMMAND_ID.FIND_NEXT;
public static readonly ID_TERMINAL_FOCUS = TERMINAL_COMMAND_ID.FIND_NEXT_TERMINAL_FOCUS;
public static readonly LABEL = nls.localize('workbench.action.terminal.findNext', "Find next");
constructor(
@@ -1376,7 +1387,6 @@ export class FindNext extends Action {
export class FindPrevious extends Action {
public static readonly ID = TERMINAL_COMMAND_ID.FIND_PREVIOUS;
public static readonly ID_TERMINAL_FOCUS = TERMINAL_COMMAND_ID.FIND_PREVIOUS_TERMINAL_FOCUS;
public static readonly LABEL = nls.localize('workbench.action.terminal.findPrevious', "Find previous");
constructor(

View File

@@ -31,7 +31,7 @@ import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/term
import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { ITerminalInstanceService, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalInstanceService, ITerminalInstance, TerminalShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
import { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm';
import { SearchAddon, ISearchOptions } from 'xterm-addon-search';
@@ -54,11 +54,11 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [
TERMINAL_COMMAND_ID.DELETE_WORD_RIGHT,
TERMINAL_COMMAND_ID.FIND_WIDGET_FOCUS,
TERMINAL_COMMAND_ID.FIND_WIDGET_HIDE,
TERMINAL_COMMAND_ID.FIND_NEXT_TERMINAL_FOCUS,
TERMINAL_COMMAND_ID.FIND_PREVIOUS_TERMINAL_FOCUS,
TERMINAL_COMMAND_ID.TOGGLE_FIND_REGEX_TERMINAL_FOCUS,
TERMINAL_COMMAND_ID.TOGGLE_FIND_WHOLE_WORD_TERMINAL_FOCUS,
TERMINAL_COMMAND_ID.TOGGLE_FIND_CASE_SENSITIVE_TERMINAL_FOCUS,
TERMINAL_COMMAND_ID.FIND_NEXT,
TERMINAL_COMMAND_ID.FIND_PREVIOUS,
TERMINAL_COMMAND_ID.TOGGLE_FIND_REGEX,
TERMINAL_COMMAND_ID.TOGGLE_FIND_WHOLE_WORD,
TERMINAL_COMMAND_ID.TOGGLE_FIND_CASE_SENSITIVE,
TERMINAL_COMMAND_ID.FOCUS_NEXT_PANE,
TERMINAL_COMMAND_ID.FOCUS_NEXT,
TERMINAL_COMMAND_ID.FOCUS_PREVIOUS_PANE,
@@ -181,7 +181,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private _hadFocusOnExit: boolean;
private _isVisible: boolean;
private _isDisposed: boolean;
private _exitCode: number | undefined;
private _skipTerminalCommands: string[];
private _shellType: TerminalShellType;
private _title: string = '';
private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined;
private _xterm: XTermTerminal | undefined;
@@ -226,10 +228,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// TODO: How does this work with detached processes?
// TODO: Should this be an event as it can fire twice?
public get processReady(): Promise<void> { return this._processManager.ptyProcessReady; }
public get exitCode(): number | undefined { return this._exitCode; }
public get title(): string { return this._title; }
public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; }
public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; }
public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; }
public get shellType(): TerminalShellType { return this._shellType; }
public get commandTracker(): CommandTrackerAddon | undefined { return this._commandTrackerAddon; }
public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; }
@@ -305,7 +309,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
});
this.addDisposable(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('terminal.integrated')) {
if (e.affectsConfiguration('terminal.integrated') || e.affectsConfiguration('editor.fastScrollSensitivity') || e.affectsConfiguration('editor.mouseWheelScrollSensitivity')) {
this.updateConfig();
// HACK: Trigger another async layout to ensure xterm's CharMeasure is ready to use,
// this hack can be removed when https://github.com/xtermjs/xterm.js/issues/702 is
@@ -365,12 +369,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// when window.devicePixelRatio changes.
const scaledWidthAvailable = dimension.width * window.devicePixelRatio;
let scaledCharWidth: number;
if (this._configHelper.config.rendererType === 'dom') {
scaledCharWidth = font.charWidth * window.devicePixelRatio;
} else {
scaledCharWidth = Math.floor(font.charWidth * window.devicePixelRatio) + font.letterSpacing;
}
const scaledCharWidth = font.charWidth * window.devicePixelRatio + font.letterSpacing;
const newCols = Math.max(Math.floor(scaledWidthAvailable / scaledCharWidth), 1);
const scaledHeightAvailable = dimension.height * window.devicePixelRatio;
@@ -421,7 +420,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
const bottom = parseInt(wrapperElementStyle.bottom!.split('px')[0], 10);
const innerWidth = width - marginLeft - marginRight;
const innerHeight = height - bottom;
const innerHeight = height - bottom - 1;
TerminalInstance._lastKnownCanvasDimensions = new dom.Dimension(innerWidth, innerHeight);
return TerminalInstance._lastKnownCanvasDimensions;
@@ -448,7 +447,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
const Terminal = await this._getXtermConstructor();
const font = this._configHelper.getFont(undefined, true);
const config = this._configHelper.config;
const fastScrollSensitivity = this._configurationService.getValue<IEditorOptions>('editor.fastScrollSensitivity').fastScrollSensitivity;
const editorOptions = this._configurationService.getValue<IEditorOptions>('editor');
const xterm = new Terminal({
scrollback: config.scrollback,
theme: this._getXtermTheme(),
@@ -459,14 +459,16 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
fontSize: font.fontSize,
letterSpacing: font.letterSpacing,
lineHeight: font.lineHeight,
minimumContrastRatio: config.minimumContrastRatio,
bellStyle: config.enableBell ? 'sound' : 'none',
macOptionIsMeta: config.macOptionIsMeta,
macOptionClickForcesSelection: config.macOptionClickForcesSelection,
rightClickSelectsWord: config.rightClickBehavior === 'selectWord',
fastScrollModifier: 'alt',
fastScrollSensitivity,
// TODO: Guess whether to use canvas or dom better
rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType
fastScrollSensitivity: editorOptions.fastScrollSensitivity,
scrollSensitivity: editorOptions.mouseWheelScrollSensitivity,
rendererType: config.rendererType === 'auto' || config.rendererType === 'experimentalWebgl' ? 'canvas' : config.rendererType,
wordSeparator: ' ()[]{}\',:;"`'
});
this._xterm = xterm;
this._xtermCore = (xterm as any)._core as XTermCore;
@@ -484,7 +486,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._processManager.onProcessData(data => this._onProcessData(data));
this._xterm.onData(data => this._processManager.write(data));
// TODO: How does the cwd work on detached processes?
this.processReady.then(async () => {
if (this._linkHandler) {
this._linkHandler.processCwd = await this._processManager.getInitialCwd();
@@ -524,9 +525,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
throw new Error('The terminal instance has not been attached to a container yet');
}
if (this._wrapperElement.parentNode) {
this._wrapperElement.parentNode.removeChild(this._wrapperElement);
}
this._wrapperElement.parentNode?.removeChild(this._wrapperElement);
this._container = container;
this._container.appendChild(this._wrapperElement);
}
@@ -544,9 +543,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
// The container changed, reattach
if (this._container) {
this._container.removeChild(this._wrapperElement);
}
this._container?.removeChild(this._wrapperElement);
this._container = container;
this._container.appendChild(this._wrapperElement);
}
@@ -568,6 +565,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._wrapperElement.appendChild(this._xtermElement);
this._container.appendChild(this._wrapperElement);
xterm.open(this._xtermElement);
if (this._configHelper.config.rendererType === 'experimentalWebgl') {
this._terminalInstanceService.getXtermWebglConstructor().then(Addon => {
xterm.loadAddon(new Addon());
});
}
if (!xterm.element || !xterm.textarea) {
throw new Error('xterm elements not set after open');
@@ -584,7 +586,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
// within commandsToSkipShell
const standardKeyboardEvent = new StandardKeyboardEvent(event);
const resolveResult = this._keybindingService.softDispatch(standardKeyboardEvent, standardKeyboardEvent.target);
const allowChords = resolveResult && resolveResult.enterChord && this._configHelper.config.allowChords;
// Respect chords if the allowChords setting is set and it's not Escape. Escape is
// handled specially for Zen Mode's Escape, Escape chord, plus it's important in
// terminals generally
const allowChords = resolveResult && resolveResult.enterChord && this._configHelper.config.allowChords && event.key !== 'Escape';
if (allowChords || resolveResult && this._skipTerminalCommands.some(k => k === resolveResult.commandId)) {
event.preventDefault();
return false;
@@ -594,6 +599,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
if (TabFocus.getTabFocusMode() && event.keyCode === 9) {
return false;
}
// Always have alt+F4 skip the terminal on Windows and allow it to be handled by the
// system
if (platform.isWindows && event.altKey && event.key === 'F4' && !event.ctrlKey) {
@@ -652,11 +658,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
const widgetManager = new TerminalWidgetManager(this._wrapperElement);
this._widgetManager = widgetManager;
this._processManager.onProcessReady(() => {
if (this._linkHandler) {
this._linkHandler.setWidgetManager(widgetManager);
}
});
this._processManager.onProcessReady(() => this._linkHandler?.setWidgetManager(widgetManager));
const computedStyle = window.getComputedStyle(this._container);
const width = parseInt(computedStyle.getPropertyValue('width').replace('px', ''), 10);
@@ -751,19 +753,13 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
public clearSelection(): void {
if (!this._xterm) {
return;
}
this._xterm.clearSelection();
this._xterm?.clearSelection();
}
public selectAll(): void {
if (!this._xterm) {
return;
}
// Focus here to ensure the terminal context key is set
this._xterm.focus();
this._xterm.selectAll();
this._xterm?.focus();
this._xterm?.selectAll();
}
public findNext(term: string, searchOptions: ISearchOptions): boolean {
@@ -924,45 +920,31 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
public scrollDownLine(): void {
if (this._xterm) {
this._xterm.scrollLines(1);
}
this._xterm?.scrollLines(1);
}
public scrollDownPage(): void {
if (this._xterm) {
this._xterm.scrollPages(1);
}
this._xterm?.scrollPages(1);
}
public scrollToBottom(): void {
if (this._xterm) {
this._xterm.scrollToBottom();
}
this._xterm?.scrollToBottom();
}
public scrollUpLine(): void {
if (this._xterm) {
this._xterm.scrollLines(-1);
}
this._xterm?.scrollLines(-1);
}
public scrollUpPage(): void {
if (this._xterm) {
this._xterm.scrollPages(-1);
}
this._xterm?.scrollPages(-1);
}
public scrollToTop(): void {
if (this._xterm) {
this._xterm.scrollToTop();
}
this._xterm?.scrollToTop();
}
public clear(): void {
if (this._xterm) {
this._xterm.clear();
}
this._xterm?.clear();
}
private _refreshSelectionContextKey() {
@@ -1019,12 +1001,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
private _onProcessData(data: string): void {
if (this._widgetManager) {
this._widgetManager.closeMessage();
}
if (this._xterm) {
this._xterm.write(data);
}
this._widgetManager?.closeMessage();
this._xterm?.write(data);
}
/**
@@ -1041,6 +1019,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._logService.debug(`Terminal process exit (id: ${this.id}) with code ${exitCode}`);
this._exitCode = exitCode;
this._isExiting = true;
let exitCodeMessage: string | undefined;
@@ -1130,10 +1109,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
public reuseTerminal(shell: IShellLaunchConfig): void {
// Unsubscribe any key listener we may have.
if (this._pressAnyKeyToCloseListener) {
this._pressAnyKeyToCloseListener.dispose();
this._pressAnyKeyToCloseListener = undefined;
}
this._pressAnyKeyToCloseListener?.dispose();
this._pressAnyKeyToCloseListener = undefined;
// Kill and clear up the process, making the process manager ready for a new process
this._processManager.dispose();
@@ -1243,11 +1220,18 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._setCommandsToSkipShell(config.commandsToSkipShell);
this._setEnableBell(config.enableBell);
this._safeSetOption('scrollback', config.scrollback);
this._safeSetOption('minimumContrastRatio', config.minimumContrastRatio);
this._safeSetOption('macOptionIsMeta', config.macOptionIsMeta);
this._safeSetOption('macOptionClickForcesSelection', config.macOptionClickForcesSelection);
this._safeSetOption('rightClickSelectsWord', config.rightClickBehavior === 'selectWord');
this._safeSetOption('rendererType', config.rendererType === 'auto' ? 'canvas' : config.rendererType);
this._safeSetOption('fastScrollSensitivity', this._configurationService.getValue<IEditorOptions>('editor.fastScrollSensitivity').fastScrollSensitivity);
if (config.rendererType !== 'experimentalWebgl') {
// Never set webgl as it's an addon not a rendererType
this._safeSetOption('rendererType', config.rendererType === 'auto' ? 'canvas' : config.rendererType);
}
const editorOptions = this._configurationService.getValue<IEditorOptions>('editor');
this._safeSetOption('fastScrollSensitivity', editorOptions.fastScrollSensitivity);
this._safeSetOption('scrollSensitivity', editorOptions.mouseWheelScrollSensitivity);
}
public updateAccessibilitySupport(): void {
@@ -1256,10 +1240,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._navigationModeAddon = new NavigationModeAddon(this._terminalA11yTreeFocusContextKey);
this._xterm!.loadAddon(this._navigationModeAddon);
} else {
if (this._navigationModeAddon) {
this._navigationModeAddon.dispose();
this._navigationModeAddon = undefined;
}
this._navigationModeAddon?.dispose();
this._navigationModeAddon = undefined;
}
this._xterm!.setOption('screenReaderMode', isEnabled);
}
@@ -1375,6 +1357,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._processManager.ptyProcessReady.then(() => this._processManager.setDimensions(cols, rows));
}
public setShellType(shellType: TerminalShellType) {
this._shellType = shellType;
}
public setTitle(title: string | undefined, eventSource: TitleEventSource): void {
if (!title) {
return;

View File

@@ -8,6 +8,7 @@ import { IWindowsShellHelper, ITerminalChildProcess, IDefaultShellAndArgsRequest
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { Emitter, Event } from 'vs/base/common/event';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
@@ -15,6 +16,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
let Terminal: typeof XTermTerminal;
let WebLinksAddon: typeof XTermWebLinksAddon;
let SearchAddon: typeof XTermSearchAddon;
let WebglAddon: typeof XTermWebglAddon;
export class TerminalInstanceService implements ITerminalInstanceService {
public _serviceBrand: undefined;
@@ -43,6 +45,13 @@ export class TerminalInstanceService implements ITerminalInstanceService {
return SearchAddon;
}
public async getXtermWebglConstructor(): Promise<typeof XTermWebglAddon> {
if (!WebglAddon) {
WebglAddon = (await import('xterm-addon-webgl')).WebglAddon;
}
return WebglAddon;
}
public createWindowsShellHelper(): IWindowsShellHelper {
throw new Error('Not implemented');
}

View File

@@ -7,13 +7,13 @@ import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
import { TerminalWidgetManager, WidgetVerticalAlignment } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalProcessManager, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal';
import { ITextEditorSelection } from 'vs/platform/editor/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IFileService } from 'vs/platform/files/common/files';
import { Terminal, ILinkMatcherOptions } from 'xterm';
import { Terminal, ILinkMatcherOptions, IViewportRange } from 'xterm';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
import { posix, win32 } from 'vs/base/common/path';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
@@ -71,7 +71,7 @@ export class TerminalLinkHandler {
private _processCwd: string | undefined;
private _gitDiffPreImagePattern: RegExp;
private _gitDiffPostImagePattern: RegExp;
private readonly _tooltipCallback: (event: MouseEvent, uri: string) => boolean | void;
private readonly _tooltipCallback: (event: MouseEvent, uri: string, location: IViewportRange) => boolean | void;
private readonly _leaveCallback: () => void;
constructor(
@@ -89,15 +89,42 @@ export class TerminalLinkHandler {
// Matches '+++ b/src/file1', capturing 'src/file1' in group 1
this._gitDiffPostImagePattern = /^\+\+\+ b\/(\S*)/;
this._tooltipCallback = (e: MouseEvent) => {
this._tooltipCallback = (e: MouseEvent, uri: string, location: IViewportRange) => {
if (!this._widgetManager) {
return;
}
// Get the row bottom up
let offsetRow = this._xterm.rows - location.start.y;
let verticalAlignment = WidgetVerticalAlignment.Bottom;
// Show the tooltip on the top of the next row to avoid obscuring the first row
if (location.start.y <= 0) {
offsetRow = this._xterm.rows - 1;
verticalAlignment = WidgetVerticalAlignment.Top;
// The start of the wrapped line is above the viewport, move to start of the line
if (location.start.y < 0) {
location.start.x = 0;
}
}
if (this._configHelper.config.rendererType === 'dom') {
const target = (e.target as HTMLElement);
this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString());
const font = this._configHelper.getFont();
const charWidth = font.charWidth;
const charHeight = font.charHeight;
const leftPosition = location.start.x * (charWidth! + (font.letterSpacing / window.devicePixelRatio));
const bottomPosition = offsetRow * (Math.ceil(charHeight! * window.devicePixelRatio) * font.lineHeight) / window.devicePixelRatio;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
} else {
this._widgetManager.showMessage(e.offsetX, e.offsetY, this._getLinkHoverString());
const target = (e.target as HTMLElement);
const colWidth = target.offsetWidth / this._xterm.cols;
const rowHeight = target.offsetHeight / this._xterm.rows;
const leftPosition = location.start.x * colWidth;
const bottomPosition = offsetRow * rowHeight;
this._widgetManager.showMessage(leftPosition, bottomPosition, this._getLinkHoverString(), verticalAlignment);
}
};
this._leaveCallback = () => {
@@ -239,8 +266,7 @@ export class TerminalLinkHandler {
}
private _handleHypertextLink(url: string): void {
const uri = URI.parse(url);
this._openerService.open(uri, { allowTunneling: !!(this._processManager && this._processManager.remoteAuthority) });
this._openerService.open(url, { allowTunneling: !!(this._processManager && this._processManager.remoteAuthority) });
}
private _isLinkActivationModifierDown(event: MouseEvent): boolean {

View File

@@ -15,7 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal';
import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';
import { editorHoverBackground, editorHoverBorder, editorForeground } from 'vs/platform/theme/common/colorRegistry';
import { editorHoverBackground, editorHoverBorder, editorHoverForeground } from 'vs/platform/theme/common/colorRegistry';
import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionViewItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
import { Panel } from 'vs/workbench/browser/panel';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
@@ -26,6 +26,7 @@ import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notif
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { assertIsDefined } from 'vs/base/common/types';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
const FIND_FOCUS_CLASS = 'find-focused';
@@ -141,13 +142,22 @@ export class TerminalPanel extends Panel {
private _getContextMenuActions(): IAction[] {
if (!this._contextMenuActions || !this._copyContextMenuAction) {
this._copyContextMenuAction = this._instantiationService.createInstance(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.SHORT_LABEL);
const clipboardActions = [];
if (BrowserFeatures.clipboard.writeText) {
clipboardActions.push(this._copyContextMenuAction);
}
if (BrowserFeatures.clipboard.readText) {
clipboardActions.push(this._instantiationService.createInstance(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.SHORT_LABEL));
}
clipboardActions.push(this._instantiationService.createInstance(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL));
this._contextMenuActions = [
this._instantiationService.createInstance(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.SHORT_LABEL),
this._instantiationService.createInstance(SplitTerminalAction, SplitTerminalAction.ID, SplitTerminalAction.SHORT_LABEL),
new Separator(),
this._copyContextMenuAction,
this._instantiationService.createInstance(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.SHORT_LABEL),
this._instantiationService.createInstance(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL),
...clipboardActions,
new Separator(),
this._instantiationService.createInstance(ClearTerminalAction, ClearTerminalAction.ID, ClearTerminalAction.LABEL),
new Separator(),
@@ -252,9 +262,9 @@ export class TerminalPanel extends Panel {
getActions: () => this._getContextMenuActions(),
getActionsContext: () => this._parentDomElement
});
} else {
event.stopImmediatePropagation();
}
event.preventDefault();
event.stopImmediatePropagation();
this._cancelContextMenu = false;
}));
this._register(dom.addDisposableListener(document, 'keydown', (event: KeyboardEvent) => {
@@ -291,7 +301,7 @@ export class TerminalPanel extends Panel {
const terminal = this._terminalService.getActiveInstance();
if (terminal) {
return this._terminalService.preparePathForTerminalAsync(path, terminal.shellLaunchConfig.executable, terminal.title).then(preparedPath => {
return this._terminalService.preparePathForTerminalAsync(path, terminal.shellLaunchConfig.executable, terminal.title, terminal.shellType).then(preparedPath => {
terminal.sendText(preparedPath, false);
});
}
@@ -337,7 +347,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
if (hoverBorder) {
collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-message-widget { border: 1px solid ${hoverBorder}; }`);
}
const hoverForeground = theme.getColor(editorForeground);
const hoverForeground = theme.getColor(editorHoverForeground);
if (hoverForeground) {
collector.addRule(`.monaco-workbench .panel.integrated-terminal .terminal-message-widget { color: ${hoverForeground}; }`);
}

View File

@@ -17,8 +17,8 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
private readonly _onProcessData = this._register(new Emitter<string>());
public readonly onProcessData: Event<string> = this._onProcessData.event;
private readonly _onProcessExit = this._register(new Emitter<number>());
public readonly onProcessExit: Event<number> = this._onProcessExit.event;
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
public readonly onProcessExit: Event<number | undefined> = this._onProcessExit.event;
private readonly _onProcessReady = this._register(new Emitter<{ pid: number, cwd: string }>());
public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; }
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
@@ -87,7 +87,7 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal
this._onProcessReady.fire({ pid, cwd });
}
public emitExit(exitCode: number): void {
public emitExit(exitCode: number | undefined): void {
this._onProcessExit.fire(exitCode);
this.dispose();
}

View File

@@ -67,8 +67,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
public get onProcessData(): Event<string> { return this._onProcessData.event; }
private readonly _onProcessTitle = this._register(new Emitter<string>());
public get onProcessTitle(): Event<string> { return this._onProcessTitle.event; }
private readonly _onProcessExit = this._register(new Emitter<number>());
public get onProcessExit(): Event<number> { return this._onProcessExit.event; }
private readonly _onProcessExit = this._register(new Emitter<number | undefined>());
public get onProcessExit(): Event<number | undefined> { return this._onProcessExit.event; }
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensions | undefined>());
public get onProcessOverrideDimensions(): Event<ITerminalDimensions | undefined> { return this._onProcessOverrideDimensions.event; }
private readonly _onProcessOverrideShellLaunchConfig = this._register(new Emitter<IShellLaunchConfig>());
@@ -285,7 +285,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
return Promise.resolve(this._latency);
}
private _onExit(exitCode: number): void {
private _onExit(exitCode: number | undefined): void {
this._process = null;
// If the process is marked as launching then mark the process as killed

View File

@@ -88,7 +88,7 @@ export class TerminalPickerHandler extends QuickOpenHandler {
const normalizedSearchValueLowercase = stripWildcards(searchValue).toLowerCase();
const terminalEntries: QuickOpenEntry[] = this.getTerminals();
terminalEntries.push(new CreateTerminal(nls.localize("workbench.action.terminal.newplus", "$(plus) Create New Integrated Terminal"), this.commandService));
terminalEntries.push(new CreateTerminal('$(plus) ' + nls.localize("workbench.action.terminal.newplus", "Create New Integrated Terminal"), this.commandService));
const entries = terminalEntries.filter(e => {
if (!searchValue) {
@@ -113,7 +113,7 @@ export class TerminalPickerHandler extends QuickOpenHandler {
}
private getTerminals(): TerminalEntry[] {
return this.terminalService.terminalTabs.reduce((terminals, tab, tabIndex) => {
return this.terminalService.terminalTabs.reduce((terminals: TerminalEntry[], tab, tabIndex) => {
const terminalsInTab = tab.terminalInstances.map((terminal, terminalIndex) => {
const label = `${tabIndex + 1}.${terminalIndex + 1}: ${terminal.title}`;
return new TerminalEntry(terminal, label, this.terminalService);

View File

@@ -16,7 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
import { ITerminalService, ITerminalInstance, ITerminalTab } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalService, ITerminalInstance, ITerminalTab, TerminalShellType, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput';
@@ -504,7 +504,7 @@ export class TerminalService implements ITerminalService {
});
}
public preparePathForTerminalAsync(originalPath: string, executable: string, title: string): Promise<string> {
public preparePathForTerminalAsync(originalPath: string, executable: string, title: string, shellType: TerminalShellType): Promise<string> {
return new Promise<string>(c => {
if (!executable) {
c(originalPath);
@@ -527,18 +527,41 @@ export class TerminalService implements ITerminalService {
if (isWindows) {
// 17063 is the build number where wsl path was introduced.
// Update Windows uriPath to be executed in WSL.
const lowerExecutable = executable.toLowerCase();
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063 &&
(lowerExecutable.indexOf('wsl') !== -1 || (lowerExecutable.indexOf('bash.exe') !== -1 && lowerExecutable.toLowerCase().indexOf('git') === -1))) {
c(this._terminalNativeService.getWslPath(originalPath));
return;
} else if (hasSpace) {
c('"' + originalPath + '"');
if (shellType !== undefined) {
if (shellType === WindowsShellType.GitBash) {
c(originalPath.replace(/\\/g, '/'));
return;
}
else if (shellType === WindowsShellType.Wsl) {
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063) {
c(this._terminalNativeService.getWslPath(originalPath));
} else {
c(originalPath.replace(/\\/g, '/'));
}
return;
}
if (hasSpace) {
c('"' + originalPath + '"');
} else {
c(originalPath);
}
} else {
c(originalPath);
const lowerExecutable = executable.toLowerCase();
if (this._terminalNativeService.getWindowsBuildNumber() >= 17063 &&
(lowerExecutable.indexOf('wsl') !== -1 || (lowerExecutable.indexOf('bash.exe') !== -1 && lowerExecutable.toLowerCase().indexOf('git') === -1))) {
c(this._terminalNativeService.getWslPath(originalPath));
return;
} else if (hasSpace) {
c('"' + originalPath + '"');
} else {
c(originalPath);
}
}
return;
}
c(escapeNonWindowsPath(originalPath));
});
}

View File

@@ -5,6 +5,11 @@
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
export enum WidgetVerticalAlignment {
Bottom,
Top
}
const WIDGET_HEIGHT = 29;
export class TerminalWidgetManager implements IDisposable {
@@ -43,13 +48,13 @@ export class TerminalWidgetManager implements IDisposable {
mutationObserver.observe(this._xtermViewport, { attributes: true, attributeFilter: ['style'] });
}
public showMessage(left: number, top: number, text: string): void {
public showMessage(left: number, y: number, text: string, verticalAlignment: WidgetVerticalAlignment = WidgetVerticalAlignment.Bottom): void {
if (!this._container) {
return;
}
dispose(this._messageWidget);
this._messageListeners.clear();
this._messageWidget = new MessageWidget(this._container, left, top, text);
this._messageWidget = new MessageWidget(this._container, left, y, text, verticalAlignment);
}
public closeMessage(): void {
@@ -71,9 +76,10 @@ class MessageWidget {
private _domNode: HTMLDivElement;
public get left(): number { return this._left; }
public get top(): number { return this._top; }
public get y(): number { return this._y; }
public get text(): string { return this._text; }
public get domNode(): HTMLElement { return this._domNode; }
public get verticalAlignment(): WidgetVerticalAlignment { return this._verticalAlignment; }
public static fadeOut(messageWidget: MessageWidget): IDisposable {
let handle: any;
@@ -91,13 +97,22 @@ class MessageWidget {
constructor(
private _container: HTMLElement,
private _left: number,
private _top: number,
private _text: string
private _y: number,
private _text: string,
private _verticalAlignment: WidgetVerticalAlignment
) {
this._domNode = document.createElement('div');
this._domNode.style.position = 'absolute';
this._domNode.style.left = `${_left}px`;
this._domNode.style.bottom = `${_container.offsetHeight - Math.max(_top, WIDGET_HEIGHT)}px`;
if (this.verticalAlignment === WidgetVerticalAlignment.Top) {
// Y position is to the top of the widget
this._domNode.style.bottom = `${Math.max(_y, WIDGET_HEIGHT) - WIDGET_HEIGHT}px`;
} else {
// Y position is to the bottom of the widget
this._domNode.style.bottom = `${Math.min(_y, _container.offsetHeight - WIDGET_HEIGHT)}px`;
}
this._domNode.classList.add('terminal-message-widget', 'fadeIn');
this._domNode.textContent = _text;
this._container.appendChild(this._domNode);

View File

@@ -87,7 +87,7 @@ export interface ITerminalConfiguration {
};
macOptionIsMeta: boolean;
macOptionClickForcesSelection: boolean;
rendererType: 'auto' | 'canvas' | 'dom';
rendererType: 'auto' | 'canvas' | 'dom' | 'experimentalWebgl';
rightClickBehavior: 'default' | 'copyPaste' | 'paste' | 'selectWord';
cursorBlinking: boolean;
cursorStyle: string;
@@ -95,6 +95,7 @@ export interface ITerminalConfiguration {
fontFamily: string;
fontWeight: FontWeight;
fontWeightBold: FontWeight;
minimumContrastRatio: number;
// fontLigatures: boolean;
fontSize: number;
letterSpacing: number;
@@ -113,7 +114,6 @@ export interface ITerminalConfiguration {
windows: { [key: string]: string };
};
showExitAlert: boolean;
experimentalBufferImpl: 'JsArray' | 'TypedArray';
splitCwd: 'workspaceRoot' | 'initial' | 'inherited';
windowsEnableConpty: boolean;
experimentalRefreshOnResume: boolean;
@@ -286,7 +286,7 @@ export interface ITerminalProcessManager extends IDisposable {
readonly onBeforeProcessData: Event<IBeforeProcessDataEvent>;
readonly onProcessData: Event<string>;
readonly onProcessTitle: Event<string>;
readonly onProcessExit: Event<number>;
readonly onProcessExit: Event<number | undefined>;
readonly onProcessOverrideDimensions: Event<ITerminalDimensions | undefined>;
readonly onProcessResolvedShellLaunchConfig: Event<IShellLaunchConfig>;
@@ -325,7 +325,7 @@ export interface ITerminalProcessExtHostProxy extends IDisposable {
emitData(data: string): void;
emitTitle(title: string): void;
emitReady(pid: number, cwd: string): void;
emitExit(exitCode: number): void;
emitExit(exitCode: number | undefined): void;
emitOverrideDimensions(dimensions: ITerminalDimensions | undefined): void;
emitResolvedShellLaunchConfig(shellLaunchConfig: IShellLaunchConfig): void;
emitInitialCwd(initialCwd: string): void;
@@ -389,7 +389,7 @@ export interface IWindowsShellHelper extends IDisposable {
*/
export interface ITerminalChildProcess {
onProcessData: Event<string>;
onProcessExit: Event<number>;
onProcessExit: Event<number | undefined>;
onProcessReady: Event<{ pid: number, cwd: string }>;
onProcessTitleChanged: Event<string>;
onProcessOverrideDimensions?: Event<ITerminalDimensions | undefined>;
@@ -412,9 +412,7 @@ export interface ITerminalChildProcess {
export const enum TERMINAL_COMMAND_ID {
FIND_NEXT = 'workbench.action.terminal.findNext',
FIND_NEXT_TERMINAL_FOCUS = 'workbench.action.terminal.findNextTerminalFocus',
FIND_PREVIOUS = 'workbench.action.terminal.findPrevious',
FIND_PREVIOUS_TERMINAL_FOCUS = 'workbench.action.terminal.findPreviousTerminalFocus',
TOGGLE = 'workbench.action.terminal.toggleTerminal',
KILL = 'workbench.action.terminal.kill',
QUICK_KILL = 'workbench.action.terminal.quickKill',
@@ -455,6 +453,7 @@ export const enum TERMINAL_COMMAND_ID {
CLEAR_SELECTION = 'workbench.action.terminal.clearSelection',
MANAGE_WORKSPACE_SHELL_PERMISSIONS = 'workbench.action.terminal.manageWorkspaceShellPermissions',
RENAME = 'workbench.action.terminal.rename',
RENAME_WITH_ARG = 'workbench.action.terminal.renameWithArg',
FIND_WIDGET_FOCUS = 'workbench.action.terminal.focusFindWidget',
FIND_WIDGET_HIDE = 'workbench.action.terminal.hideFindWidget',
QUICK_OPEN_TERM = 'workbench.action.quickOpenTerm',
@@ -469,9 +468,6 @@ export const enum TERMINAL_COMMAND_ID {
TOGGLE_FIND_REGEX = 'workbench.action.terminal.toggleFindRegex',
TOGGLE_FIND_WHOLE_WORD = 'workbench.action.terminal.toggleFindWholeWord',
TOGGLE_FIND_CASE_SENSITIVE = 'workbench.action.terminal.toggleFindCaseSensitive',
TOGGLE_FIND_REGEX_TERMINAL_FOCUS = 'workbench.action.terminal.toggleFindRegexTerminalFocus',
TOGGLE_FIND_WHOLE_WORD_TERMINAL_FOCUS = 'workbench.action.terminal.toggleFindWholeWordTerminalFocus',
TOGGLE_FIND_CASE_SENSITIVE_TERMINAL_FOCUS = 'workbench.action.terminal.toggleFindCaseSensitiveTerminalFocus',
NAVIGATION_MODE_EXIT = 'workbench.action.terminal.navigationModeExit',
NAVIGATION_MODE_FOCUS_NEXT = 'workbench.action.terminal.navigationModeFocusNext',
NAVIGATION_MODE_FOCUS_PREVIOUS = 'workbench.action.terminal.navigationModeFocusPrevious'

View File

@@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
interface TerminalDataBuffer extends IDisposable {
data: string[];
timeoutId: any;
}
export class TerminalDataBufferer implements IDisposable {
private readonly _terminalBufferMap = new Map<number, TerminalDataBuffer>();
dispose() {
for (const buffer of this._terminalBufferMap.values()) {
buffer.dispose();
}
}
startBuffering(id: number, event: Event<string>, callback: (id: number, data: string) => void, throttleBy: number = 5): IDisposable {
let disposable: IDisposable;
disposable = event((e: string) => {
let buffer = this._terminalBufferMap.get(id);
if (buffer) {
buffer.data.push(e);
return;
}
const timeoutId = setTimeout(() => {
this._terminalBufferMap.delete(id);
callback(id, buffer!.data.join(''));
}, throttleBy);
buffer = {
data: [e],
timeoutId: timeoutId,
dispose: () => {
clearTimeout(timeoutId);
this._terminalBufferMap.delete(id);
disposable.dispose();
}
};
this._terminalBufferMap.set(id, buffer);
});
return disposable;
}
stopBuffering(id: number) {
const buffer = this._terminalBufferMap.get(id);
if (buffer) {
buffer.dispose();
}
}
}

View File

@@ -184,23 +184,16 @@ export function getCwd(
logService?: ILogService
): string {
if (shell.cwd) {
return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
const unresolved = (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
const resolved = _resolveCwd(unresolved, lastActiveWorkspace, configurationResolverService);
return resolved || unresolved;
}
let cwd: string | undefined;
if (!shell.ignoreConfigurationCwd && customCwd) {
if (configurationResolverService) {
try {
customCwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
} catch (e) {
// There was an issue resolving a variable, log the error in the console and
// fallback to the default.
if (logService) {
logService.error('Could not resolve terminal.integrated.cwd', e);
}
customCwd = undefined;
}
customCwd = _resolveCwd(customCwd, lastActiveWorkspace, configurationResolverService, logService);
}
if (customCwd) {
if (path.isAbsolute(customCwd)) {
@@ -219,6 +212,18 @@ export function getCwd(
return _sanitizeCwd(cwd);
}
function _resolveCwd(cwd: string, lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, logService?: ILogService): string | undefined {
if (configurationResolverService) {
try {
return configurationResolverService.resolve(lastActiveWorkspace, cwd);
} catch (e) {
logService?.error('Could not resolve terminal cwd', e);
return undefined;
}
}
return cwd;
}
function _sanitizeCwd(cwd: string): string {
// Make the drive letter uppercase on Windows (see #9448)
if (platform.platform === platform.Platform.Windows && cwd && cwd[1] === ':') {

View File

@@ -13,6 +13,7 @@ import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal';
import { Terminal as XTermTerminal } from 'xterm';
import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links';
import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search';
import { WebglAddon as XTermWebglAddon } from 'xterm-addon-webgl';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
@@ -25,6 +26,7 @@ import { ILogService } from 'vs/platform/log/common/log';
let Terminal: typeof XTermTerminal;
let WebLinksAddon: typeof XTermWebLinksAddon;
let SearchAddon: typeof XTermSearchAddon;
let WebglAddon: typeof XTermWebglAddon;
export class TerminalInstanceService implements ITerminalInstanceService {
public _serviceBrand: undefined;
@@ -61,6 +63,13 @@ export class TerminalInstanceService implements ITerminalInstanceService {
return SearchAddon;
}
public async getXtermWebglConstructor(): Promise<typeof XTermWebglAddon> {
if (!WebglAddon) {
WebglAddon = (await import('xterm-addon-webgl')).WebglAddon;
}
return WebglAddon;
}
public createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper {
return new WindowsShellHelper(shellProcessId, instance, xterm);
}

View File

@@ -69,9 +69,10 @@ export class TerminalNativeService implements ITerminalNativeService {
throw new Error('wslpath does not exist on Windows build < 17063');
}
return new Promise<string>(c => {
execFile('bash.exe', ['-c', 'echo $(wslpath ' + escapeNonWindowsPath(path) + ')'], {}, (error, stdout, stderr) => {
const proc = execFile('bash.exe', ['-c', `wslpath ${escapeNonWindowsPath(path)}`], {}, (error, stdout, stderr) => {
c(escapeNonWindowsPath(stdout.trim()));
});
proc.stdin!.end();
});
}

View File

@@ -15,7 +15,7 @@ import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal
export function registerRemoteContributions() {
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewLocalTerminalAction, CreateNewLocalTerminalAction.ID, CreateNewLocalTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (Local)', TERMINAL_ACTION_CATEGORY);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.create(CreateNewLocalTerminalAction, CreateNewLocalTerminalAction.ID, CreateNewLocalTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (Local)', TERMINAL_ACTION_CATEGORY);
}
export class CreateNewLocalTerminalAction extends Action {

View File

@@ -9,11 +9,12 @@ import { IWindowsShellHelper, TitleEventSource } from 'vs/workbench/contrib/term
import { Terminal as XTermTerminal } from 'xterm';
import * as WindowsProcessTreeType from 'windows-process-tree';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalInstance, TerminalShellType, WindowsShellType } from 'vs/workbench/contrib/terminal/browser/terminal';
const SHELL_EXECUTABLES = [
'cmd.exe',
'powershell.exe',
'pwsh.exe',
'bash.exe',
'wsl.exe',
'ubuntu.exe',
@@ -81,6 +82,7 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
if (platform.isWindows && this._terminalInstance.isTitleSetByProcess) {
this.getShellName().then(title => {
if (!this._isDisposed) {
this._terminalInstance.setShellType(this.getShellType(title));
this._terminalInstance.setTitle(title, TitleEventSource.Process);
}
});
@@ -138,4 +140,26 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
});
return this._currentRequest;
}
public getShellType(executable: string): TerminalShellType {
switch (executable.toLowerCase()) {
case 'cmd.exe':
return WindowsShellType.CommandPrompt;
case 'powershell.exe':
case 'pwsh.exe':
return WindowsShellType.PowerShell;
case 'bash.exe':
return WindowsShellType.GitBash;
case 'wsl.exe':
case 'ubuntu.exe':
case 'ubuntu1804.exe':
case 'kali.exe':
case 'debian.exe':
case 'opensuse-42.exe':
case 'sles-12.exe':
return WindowsShellType.Wsl;
default:
return undefined;
}
}
}

View File

@@ -65,7 +65,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
env,
cols,
rows,
experimentalUseConpty: useConpty,
useConpty,
// This option will force conpty to not redraw the whole viewport on launch
conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText
};
@@ -74,18 +74,21 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
if (!stat.isDirectory()) {
return Promise.reject(SHELL_CWD_INVALID_EXIT_CODE);
}
return undefined;
}, async err => {
if (err && err.code === 'ENOENT') {
// So we can include in the error message the specified CWD
shellLaunchConfig.cwd = cwd;
return Promise.reject(SHELL_CWD_INVALID_EXIT_CODE);
}
return undefined;
});
const executableVerification = stat(shellLaunchConfig.executable!).then(async stat => {
if (!stat.isFile() && !stat.isSymbolicLink()) {
return Promise.reject(stat.isDirectory() ? SHELL_PATH_DIRECTORY_EXIT_CODE : SHELL_PATH_INVALID_EXIT_CODE);
}
return undefined;
}, async (err) => {
if (err && err.code === 'ENOENT') {
let cwd = shellLaunchConfig.cwd instanceof URI ? shellLaunchConfig.cwd.path : shellLaunchConfig.cwd!;
@@ -96,6 +99,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
return Promise.reject(SHELL_PATH_INVALID_EXIT_CODE);
}
}
return undefined;
});
Promise.all([cwdVerification, executableVerification]).then(() => {
@@ -260,7 +264,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
return;
}
this._logService.trace('IPty#pid');
exec('lsof -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => {
exec('lsof -OPl -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => {
if (stdout !== '') {
resolve(stdout.substring(stdout.indexOf('/'), stdout.length - 1));
}

View File

@@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { Emitter } from 'vs/base/common/event';
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
suite('Workbench - TerminalDataBufferer', () => {
let bufferer: TerminalDataBufferer;
setup(async () => {
bufferer = new TerminalDataBufferer();
});
test('start', async () => {
let terminalOnData = new Emitter<string>();
let counter = 0;
let data: string | undefined;
bufferer.startBuffering(1, terminalOnData.event, (id, e) => {
counter++;
data = e;
}, 0);
terminalOnData.fire('1');
terminalOnData.fire('2');
terminalOnData.fire('3');
await wait(0);
terminalOnData.fire('4');
assert.equal(counter, 1);
assert.equal(data, '123');
await wait(0);
assert.equal(counter, 2);
assert.equal(data, '4');
});
test('start 2', async () => {
let terminal1OnData = new Emitter<string>();
let terminal1Counter = 0;
let terminal1Data: string | undefined;
bufferer.startBuffering(1, terminal1OnData.event, (id, e) => {
terminal1Counter++;
terminal1Data = e;
}, 0);
let terminal2OnData = new Emitter<string>();
let terminal2Counter = 0;
let terminal2Data: string | undefined;
bufferer.startBuffering(2, terminal2OnData.event, (id, e) => {
terminal2Counter++;
terminal2Data = e;
}, 0);
terminal1OnData.fire('1');
terminal2OnData.fire('4');
terminal1OnData.fire('2');
terminal2OnData.fire('5');
terminal1OnData.fire('3');
terminal2OnData.fire('6');
terminal2OnData.fire('7');
assert.equal(terminal1Counter, 0);
assert.equal(terminal1Data, undefined);
assert.equal(terminal2Counter, 0);
assert.equal(terminal2Data, undefined);
await wait(0);
assert.equal(terminal1Counter, 1);
assert.equal(terminal1Data, '123');
assert.equal(terminal2Counter, 1);
assert.equal(terminal2Data, '4567');
});
test('stop', async () => {
let terminalOnData = new Emitter<string>();
let counter = 0;
let data: string | undefined;
bufferer.startBuffering(1, terminalOnData.event, (id, e) => {
counter++;
data = e;
}, 0);
terminalOnData.fire('1');
terminalOnData.fire('2');
terminalOnData.fire('3');
bufferer.stopBuffering(1);
await wait(0);
assert.equal(counter, 0);
assert.equal(data, undefined);
});
test('start 2 stop 1', async () => {
let terminal1OnData = new Emitter<string>();
let terminal1Counter = 0;
let terminal1Data: string | undefined;
bufferer.startBuffering(1, terminal1OnData.event, (id, e) => {
terminal1Counter++;
terminal1Data = e;
}, 0);
let terminal2OnData = new Emitter<string>();
let terminal2Counter = 0;
let terminal2Data: string | undefined;
bufferer.startBuffering(2, terminal2OnData.event, (id, e) => {
terminal2Counter++;
terminal2Data = e;
}, 0);
terminal1OnData.fire('1');
terminal2OnData.fire('4');
terminal1OnData.fire('2');
terminal2OnData.fire('5');
terminal1OnData.fire('3');
terminal2OnData.fire('6');
terminal2OnData.fire('7');
assert.equal(terminal1Counter, 0);
assert.equal(terminal1Data, undefined);
assert.equal(terminal2Counter, 0);
assert.equal(terminal2Data, undefined);
bufferer.stopBuffering(1);
await wait(0);
assert.equal(terminal1Counter, 0);
assert.equal(terminal1Data, undefined);
assert.equal(terminal2Counter, 1);
assert.equal(terminal2Data, '4567');
});
test('dispose', async () => {
let terminal1OnData = new Emitter<string>();
let terminal1Counter = 0;
let terminal1Data: string | undefined;
bufferer.startBuffering(1, terminal1OnData.event, (id, e) => {
terminal1Counter++;
terminal1Data = e;
}, 0);
let terminal2OnData = new Emitter<string>();
let terminal2Counter = 0;
let terminal2Data: string | undefined;
bufferer.startBuffering(2, terminal2OnData.event, (id, e) => {
terminal2Counter++;
terminal2Data = e;
}, 0);
terminal1OnData.fire('1');
terminal2OnData.fire('4');
terminal1OnData.fire('2');
terminal2OnData.fire('5');
terminal1OnData.fire('3');
terminal2OnData.fire('6');
terminal2OnData.fire('7');
assert.equal(terminal1Counter, 0);
assert.equal(terminal1Data, undefined);
assert.equal(terminal2Counter, 0);
assert.equal(terminal2Data, undefined);
bufferer.dispose();
await wait(0);
assert.equal(terminal1Counter, 0);
assert.equal(terminal1Data, undefined);
assert.equal(terminal2Counter, 0);
assert.equal(terminal2Data, undefined);
});
});

View File

@@ -19,7 +19,10 @@ function getMockTheme(type: ThemeType): ITheme {
label: '',
type: type,
getColor: (colorId: ColorIdentifier): Color | undefined => themingRegistry.resolveDefaultColor(colorId, theme),
defines: () => true
defines: () => true,
getTokenStyleMetadata: () => undefined,
tokenColorMap: []
};
return theme;
}
@@ -99,4 +102,4 @@ suite('Workbench - TerminalColorRegistry', () => {
'#e5e5e5'
], 'The dark terminal colors should be used when a dark theme is active');
});
});
});

View File

@@ -46,6 +46,9 @@ class MockTerminalInstanceService implements ITerminalInstanceService {
getXtermSearchConstructor(): Promise<any> {
throw new Error('Method not implemented.');
}
getXtermWebglConstructor(): Promise<any> {
throw new Error('Method not implemented.');
}
createWindowsShellHelper(): any {
throw new Error('Method not implemented.');
}