disable decorations (#154430)

This commit is contained in:
Megan Rogge 2022-07-13 10:17:01 -07:00 committed by GitHub
parent a03ebcaa0d
commit ff31a8c6fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 169 additions and 55 deletions

View file

@ -14,6 +14,10 @@
position: relative; position: relative;
} }
.terminal-command-decoration.hide {
visibility: hidden;
}
.monaco-workbench .pane-body.integrated-terminal .terminal-outer-container, .monaco-workbench .pane-body.integrated-terminal .terminal-outer-container,
.monaco-workbench .pane-body.integrated-terminal .terminal-groups-container, .monaco-workbench .pane-body.integrated-terminal .terminal-groups-container,
.monaco-workbench .pane-body.integrated-terminal .terminal-group, .monaco-workbench .pane-body.integrated-terminal .terminal-group,

View file

@ -46,6 +46,7 @@ import { getTerminalActionBarArgs } from 'vs/workbench/contrib/terminal/browser/
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
import { getShellIntegrationTooltip } from 'vs/workbench/contrib/terminal/browser/terminalTooltip'; import { getShellIntegrationTooltip } from 'vs/workbench/contrib/terminal/browser/terminalTooltip';
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
export class TerminalViewPane extends ViewPane { export class TerminalViewPane extends ViewPane {
private _actions: IAction[] | undefined; private _actions: IAction[] | undefined;
@ -65,7 +66,7 @@ export class TerminalViewPane extends ViewPane {
@IKeybindingService keybindingService: IKeybindingService, @IKeybindingService keybindingService: IKeybindingService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService, @IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService, @IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService private readonly _configurationService: IConfigurationService,
@IContextMenuService private readonly _contextMenuService: IContextMenuService, @IContextMenuService private readonly _contextMenuService: IContextMenuService,
@IInstantiationService private readonly _instantiationService: IInstantiationService, @IInstantiationService private readonly _instantiationService: IInstantiationService,
@ITerminalService private readonly _terminalService: ITerminalService, @ITerminalService private readonly _terminalService: ITerminalService,
@ -81,7 +82,7 @@ export class TerminalViewPane extends ViewPane {
@ITerminalProfileResolverService private readonly _terminalProfileResolverService: ITerminalProfileResolverService, @ITerminalProfileResolverService private readonly _terminalProfileResolverService: ITerminalProfileResolverService,
@IThemeService private readonly _themeService: IThemeService @IThemeService private readonly _themeService: IThemeService
) { ) {
super(options, keybindingService, _contextMenuService, configurationService, _contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService, telemetryService); super(options, keybindingService, _contextMenuService, _configurationService, _contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService, telemetryService);
this._register(this._terminalService.onDidRegisterProcessSupport(() => { this._register(this._terminalService.onDidRegisterProcessSupport(() => {
if (this._actions) { if (this._actions) {
for (const action of this._actions) { for (const action of this._actions) {
@ -111,20 +112,34 @@ export class TerminalViewPane extends ViewPane {
this._terminalTabbedView?.rerenderTabs(); this._terminalTabbedView?.rerenderTabs();
} }
})); }));
configurationService.onDidChangeConfiguration(e => { _configurationService.onDidChangeConfiguration(e => {
if ((e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationsEnabled) && !configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled)) || if (e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationsEnabled) || e.affectsConfiguration(TerminalSettingId.ShellIntegrationEnabled)) {
(e.affectsConfiguration(TerminalSettingId.ShellIntegrationEnabled) && !configurationService.getValue(TerminalSettingId.ShellIntegrationEnabled))) { this._updateForShellIntegration();
this._parentDomElement?.classList.remove('shell-integration');
} else if (configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled) && configurationService.getValue(TerminalSettingId.ShellIntegrationEnabled)) {
this._parentDomElement?.classList.add('shell-integration');
} }
}); });
this._register(this._terminalService.onDidCreateInstance((i) => {
i.capabilities.onDidAddCapability(c => {
if (c === TerminalCapability.CommandDetection && !this._gutterDecorationsEnabled()) {
this._parentDomElement?.classList.add('shell-integration');
}
});
}));
this._updateForShellIntegration();
}
if (configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled) && configurationService.getValue(TerminalSettingId.ShellIntegrationEnabled)) { private _updateForShellIntegration() {
if (this._gutterDecorationsEnabled()) {
this._parentDomElement?.classList.add('shell-integration'); this._parentDomElement?.classList.add('shell-integration');
} else {
this._parentDomElement?.classList.remove('shell-integration');
} }
} }
private _gutterDecorationsEnabled(): boolean {
const decorationsEnabled = this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled);
return (decorationsEnabled === 'both' || decorationsEnabled === 'gutter') && this._configurationService.getValue(TerminalSettingId.ShellIntegrationEnabled);
}
override renderBody(container: HTMLElement): void { override renderBody(container: HTMLElement): void {
super.renderBody(container); super.renderBody(container);

View file

@ -28,13 +28,14 @@ import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProc
const enum DecorationSelector { const enum DecorationSelector {
CommandDecoration = 'terminal-command-decoration', CommandDecoration = 'terminal-command-decoration',
Hide = 'hide',
ErrorColor = 'error', ErrorColor = 'error',
DefaultColor = 'default-color', DefaultColor = 'default-color',
Default = 'default', Default = 'default',
Codicon = 'codicon', Codicon = 'codicon',
XtermDecoration = 'xterm-decoration', XtermDecoration = 'xterm-decoration',
OverviewRuler = 'xterm-decoration-overview-ruler', GenericMarkerIcon = 'codicon-circle-small-filled',
GenericMarkerIcon = 'codicon-circle-small-filled' OverviewRuler = '.xterm-decoration-overview-ruler'
} }
const enum DecorationStyles { const enum DecorationStyles {
@ -51,6 +52,8 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
private _contextMenuVisible: boolean = false; private _contextMenuVisible: boolean = false;
private _decorations: Map<number, IDisposableDecoration> = new Map(); private _decorations: Map<number, IDisposableDecoration> = new Map();
private _placeholderDecoration: IDecoration | undefined; private _placeholderDecoration: IDecoration | undefined;
private _showGutterDecorations?: boolean;
private _showOverviewRulerDecorations?: boolean;
private readonly _onDidRequestRunCommand = this._register(new Emitter<{ command: ITerminalCommand; copyAsHtml?: boolean }>()); private readonly _onDidRequestRunCommand = this._register(new Emitter<{ command: ITerminalCommand; copyAsHtml?: boolean }>());
readonly onDidRequestRunCommand = this._onDidRequestRunCommand.event; readonly onDidRequestRunCommand = this._onDidRequestRunCommand.event;
@ -79,9 +82,67 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
this.refreshLayouts(); this.refreshLayouts();
} else if (e.affectsConfiguration('workbench.colorCustomizations')) { } else if (e.affectsConfiguration('workbench.colorCustomizations')) {
this._refreshStyles(true); this._refreshStyles(true);
} else if (e.affectsConfiguration(TerminalSettingId.ShellIntegrationDecorationsEnabled)) {
if (this._commandDetectionListeners) {
dispose(this._commandDetectionListeners);
this._commandDetectionListeners = undefined;
}
this._updateDecorationVisibility();
} }
}); });
this._themeService.onDidColorThemeChange(() => this._refreshStyles(true)); this._themeService.onDidColorThemeChange(() => this._refreshStyles(true));
this._updateDecorationVisibility();
this._register(this._capabilities.onDidAddCapability(c => {
if (c === TerminalCapability.CommandDetection) {
this._addCommandDetectionListeners();
}
}));
this._register(this._capabilities.onDidRemoveCapability(c => {
if (c === TerminalCapability.CommandDetection) {
if (this._commandDetectionListeners) {
dispose(this._commandDetectionListeners);
this._commandDetectionListeners = undefined;
}
}
}));
}
private _updateDecorationVisibility(): void {
const showDecorations = this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationsEnabled);
this._showGutterDecorations = (showDecorations === 'both' || showDecorations === 'gutter');
this._showOverviewRulerDecorations = (showDecorations === 'both' || showDecorations === 'overviewRuler');
this._disposeAllDecorations();
if (this._showGutterDecorations || this._showOverviewRulerDecorations) {
this._attachToCommandCapability();
this._updateGutterDecorationVisibility();
}
const currentCommand = this._capabilities.get(TerminalCapability.CommandDetection)?.executingCommandObject;
if (currentCommand) {
this.registerCommandDecoration(currentCommand, true);
}
}
private _disposeAllDecorations(): void {
this._placeholderDecoration?.dispose();
for (const value of this._decorations.values()) {
value.decoration.dispose();
dispose(value.disposables);
}
}
private _updateGutterDecorationVisibility(): void {
const commandDecorationElements = document.querySelectorAll(DecorationSelector.CommandDecoration);
for (const commandDecorationElement of commandDecorationElements) {
this._updateCommandDecorationVisibility(commandDecorationElement);
}
}
private _updateCommandDecorationVisibility(commandDecorationElement: Element): void {
if (this._showGutterDecorations) {
commandDecorationElement.classList.remove(DecorationSelector.Hide);
} else {
commandDecorationElement.classList.add(DecorationSelector.Hide);
}
} }
public refreshLayouts(): void { public refreshLayouts(): void {
@ -128,31 +189,14 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
public clearDecorations(): void { public clearDecorations(): void {
this._placeholderDecoration?.marker.dispose(); this._placeholderDecoration?.marker.dispose();
this._clearPlaceholder(); this._clearPlaceholder();
for (const value of this._decorations.values()) { this._disposeAllDecorations();
value.decoration.dispose();
dispose(value.disposables);
}
this._decorations.clear(); this._decorations.clear();
} }
private _attachToCommandCapability(): void { private _attachToCommandCapability(): void {
if (this._capabilities.has(TerminalCapability.CommandDetection)) { if (this._capabilities.has(TerminalCapability.CommandDetection)) {
this._addCommandDetectionListeners(); this._addCommandDetectionListeners();
} else {
this._register(this._capabilities.onDidAddCapability(c => {
if (c === TerminalCapability.CommandDetection) {
this._addCommandDetectionListeners();
}
}));
} }
this._register(this._capabilities.onDidRemoveCapability(c => {
if (c === TerminalCapability.CommandDetection) {
if (this._commandDetectionListeners) {
dispose(this._commandDetectionListeners);
this._commandDetectionListeners = undefined;
}
}
}));
} }
private _addCommandDetectionListeners(): void { private _addCommandDetectionListeners(): void {
@ -204,13 +248,12 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
} }
registerCommandDecoration(command: ITerminalCommand, beforeCommandExecution?: boolean): IDecoration | undefined { registerCommandDecoration(command: ITerminalCommand, beforeCommandExecution?: boolean): IDecoration | undefined {
if (!this._terminal || (beforeCommandExecution && command.genericMarkProperties)) { if (!this._terminal || (beforeCommandExecution && command.genericMarkProperties) || (!this._showGutterDecorations && !this._showOverviewRulerDecorations)) {
return undefined; return undefined;
} }
if (!command.marker) { if (!command.marker) {
throw new Error(`cannot add a decoration for a command ${JSON.stringify(command)} with no marker`); throw new Error(`cannot add a decoration for a command ${JSON.stringify(command)} with no marker`);
} }
this._clearPlaceholder(); this._clearPlaceholder();
let color = command.exitCode === undefined ? defaultColor : command.exitCode ? errorColor : successColor; let color = command.exitCode === undefined ? defaultColor : command.exitCode ? errorColor : successColor;
if (color && typeof color !== 'string') { if (color && typeof color !== 'string') {
@ -220,9 +263,9 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
} }
const decoration = this._terminal.registerDecoration({ const decoration = this._terminal.registerDecoration({
marker: command.marker, marker: command.marker,
overviewRulerOptions: beforeCommandExecution overviewRulerOptions: this._showOverviewRulerDecorations ? (beforeCommandExecution
? { color, position: 'left' } ? { color, position: 'left' }
: { color, position: command.exitCode ? 'right' : 'left' } : { color, position: command.exitCode ? 'right' : 'left' }) : undefined
}); });
if (!decoration) { if (!decoration) {
return undefined; return undefined;
@ -287,20 +330,25 @@ export class DecorationAddon extends Disposable implements ITerminalAddon {
element.classList.remove(classes); element.classList.remove(classes);
} }
element.classList.add(DecorationSelector.CommandDecoration, DecorationSelector.Codicon, DecorationSelector.XtermDecoration); element.classList.add(DecorationSelector.CommandDecoration, DecorationSelector.Codicon, DecorationSelector.XtermDecoration);
if (genericMarkProperties) { if (genericMarkProperties) {
element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.GenericMarkerIcon); element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.GenericMarkerIcon);
if (!genericMarkProperties.hoverMessage) { if (!genericMarkProperties.hoverMessage) {
//disable the mouse pointer //disable the mouse pointer
element.classList.add(DecorationSelector.Default); element.classList.add(DecorationSelector.Default);
} }
} else if (exitCode === undefined) {
element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.Default);
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIcon)}`);
} else if (exitCode) {
element.classList.add(DecorationSelector.ErrorColor);
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconError)}`);
} else { } else {
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconSuccess)}`); // command decoration
this._updateCommandDecorationVisibility(element);
if (exitCode === undefined) {
element.classList.add(DecorationSelector.DefaultColor, DecorationSelector.Default);
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIcon)}`);
} else if (exitCode) {
element.classList.add(DecorationSelector.ErrorColor);
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconError)}`);
} else {
element.classList.add(`codicon-${this._configurationService.getValue(TerminalSettingId.ShellIntegrationDecorationIconSuccess)}`);
}
} }
} }

View file

@ -117,17 +117,17 @@ const terminalConfiguration: IConfigurationNode = {
[TerminalSettingId.ShellIntegrationDecorationIconSuccess]: { [TerminalSettingId.ShellIntegrationDecorationIconSuccess]: {
type: 'string', type: 'string',
default: 'primitive-dot', default: 'primitive-dot',
markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconSuccess', "Controls the icon that will be used for each command in terminals with shell integration enabled that do not have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconSuccess', "Controls the icon that will be used for each command in terminals with shell integration enabled that do not have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`')
}, },
[TerminalSettingId.ShellIntegrationDecorationIconError]: { [TerminalSettingId.ShellIntegrationDecorationIconError]: {
type: 'string', type: 'string',
default: 'error-small', default: 'error-small',
markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconError', "Controls the icon that will be used for each command in terminals with shell integration enabled that do have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') markdownDescription: localize('terminal.integrated.shellIntegration.decorationIconError', "Controls the icon that will be used for each command in terminals with shell integration enabled that do have an associated exit code. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`')
}, },
[TerminalSettingId.ShellIntegrationDecorationIcon]: { [TerminalSettingId.ShellIntegrationDecorationIcon]: {
type: 'string', type: 'string',
default: 'circle-outline', default: 'circle-outline',
markdownDescription: localize('terminal.integrated.shellIntegration.decorationIcon', "Controls the icon that will be used for skipped/empty commands. Set to {0} to hide the icon or disable decorations with {1}.", '`\'\'`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`') markdownDescription: localize('terminal.integrated.shellIntegration.decorationIcon', "Controls the icon that will be used for skipped/empty commands. Set to {0} to hide the icon or disable decorations with {1}.", '`\"\"`', '`#terminal.integrated.shellIntegration.decorationsEnabled#`')
}, },
[TerminalSettingId.TabsFocusMode]: { [TerminalSettingId.TabsFocusMode]: {
type: 'string', type: 'string',
@ -546,15 +546,22 @@ const terminalConfiguration: IConfigurationNode = {
}, },
[TerminalSettingId.ShellIntegrationEnabled]: { [TerminalSettingId.ShellIntegrationEnabled]: {
restricted: true, restricted: true,
markdownDescription: localize('terminal.integrated.shellIntegration.enabled', "Enable features like enhanced command tracking and current working directory detection. \n\nShell integration works by injecting the shell with a startup script. The script gives VS Code insight into what is happening within the terminal.\n\nSupported shells:\n\n- Linux/macOS: bash, pwsh, zsh\n - Windows: pwsh\n\nThis setting applies only when terminals are created, so you will need to restart your terminals for it to take effect.\n\n Note that the script injection may not work if you have custom arguments defined in the terminal profile, a [complex bash `PROMPT_COMMAND`](https://code.visualstudio.com/docs/editor/integrated-terminal#_complex-bash-promptcommand), or other unsupported setup."), markdownDescription: localize('terminal.integrated.shellIntegration.enabled', "Determines whether or not shell integration is auto-injected to support features like enhanced command tracking and current working directory detection. \n\nShell integration works by injecting the shell with a startup script. The script gives VS Code insight into what is happening within the terminal.\n\nSupported shells:\n\n- Linux/macOS: bash, pwsh, zsh\n - Windows: pwsh\n\nThis setting applies only when terminals are created, so you will need to restart your terminals for it to take effect.\n\n Note that the script injection may not work if you have custom arguments defined in the terminal profile, a [complex bash `PROMPT_COMMAND`](https://code.visualstudio.com/docs/editor/integrated-terminal#_complex-bash-promptcommand), or other unsupported setup. To disable decorations, see {0}", '`#terminal.integrated.shellIntegrations.decorationsEnabled#`'),
type: 'boolean', type: 'boolean',
default: true default: true
}, },
[TerminalSettingId.ShellIntegrationDecorationsEnabled]: { [TerminalSettingId.ShellIntegrationDecorationsEnabled]: {
restricted: true, restricted: true,
markdownDescription: localize('terminal.integrated.shellIntegration.decorationsEnabled', "When shell integration is enabled, adds a decoration for each command."), markdownDescription: localize('terminal.integrated.shellIntegration.decorationsEnabled', "When shell integration is enabled, adds a decoration for each command."),
type: 'boolean', type: 'string',
default: true enum: ['both', 'gutter', 'overviewRuler', 'never'],
enumDescriptions: [
localize('terminal.integrated.shellIntegration.decorationsEnabled.both', "Show decorations in the gutter (left) and overview ruler (right)"),
localize('terminal.integrated.shellIntegration.decorationsEnabled.gutter', "Show gutter decorations to the left of the terminal"),
localize('terminal.integrated.shellIntegration.decorationsEnabled.overviewRuler', "Show overview ruler decorations to the right of the terminal"),
localize('terminal.integrated.shellIntegration.decorationsEnabled.never', "Do not show decorations"),
],
default: 'both'
}, },
[TerminalSettingId.ShellIntegrationCommandHistory]: { [TerminalSettingId.ShellIntegrationCommandHistory]: {
restricted: true, restricted: true,

View file

@ -37,7 +37,14 @@ suite('DecorationAddon', () => {
const instantiationService = new TestInstantiationService(); const instantiationService = new TestInstantiationService();
const configurationService = new TestConfigurationService({ const configurationService = new TestConfigurationService({
workbench: { workbench: {
hover: { delay: 5 } hover: { delay: 5 },
},
terminal: {
integrated: {
shellIntegration: {
decorationsEnabled: 'both'
}
}
} }
}); });
instantiationService.stub(IThemeService, new TestThemeService()); instantiationService.stub(IThemeService, new TestThemeService());

View file

@ -25,7 +25,8 @@ export enum Selector {
Tabs = '.tabs-list .monaco-list-row', Tabs = '.tabs-list .monaco-list-row',
SplitButton = '.editor .codicon-split-horizontal', SplitButton = '.editor .codicon-split-horizontal',
XtermSplitIndex0 = '#terminal .terminal-groups-container .split-view-view:nth-child(1) .terminal-wrapper', XtermSplitIndex0 = '#terminal .terminal-groups-container .split-view-view:nth-child(1) .terminal-wrapper',
XtermSplitIndex1 = '#terminal .terminal-groups-container .split-view-view:nth-child(2) .terminal-wrapper' XtermSplitIndex1 = '#terminal .terminal-groups-container .split-view-view:nth-child(2) .terminal-wrapper',
Hide = '.hide'
} }
/** /**
@ -226,14 +227,18 @@ export class Terminal {
await this.code.waitForElement(Selector.TerminalView, result => result === undefined); await this.code.waitForElement(Selector.TerminalView, result => result === undefined);
} }
async assertCommandDecorations(expectedCounts?: ICommandDecorationCounts, customConfig?: { updatedIcon: string; count: number }): Promise<void> { async assertCommandDecorations(expectedCounts?: ICommandDecorationCounts, customIcon?: { updatedIcon: string; count: number }, showDecorations?: 'both' | 'gutter' | 'overviewRuler' | 'never'): Promise<void> {
if (expectedCounts) { if (expectedCounts) {
await this.code.waitForElements(Selector.CommandDecorationPlaceholder, true, decorations => decorations && decorations.length === expectedCounts.placeholder); const placeholderSelector = showDecorations === 'overviewRuler' ? `${Selector.CommandDecorationPlaceholder}${Selector.Hide}` : Selector.CommandDecorationPlaceholder;
await this.code.waitForElements(Selector.CommandDecorationSuccess, true, decorations => decorations && decorations.length === expectedCounts.success); await this.code.waitForElements(placeholderSelector, true, decorations => decorations && decorations.length === expectedCounts.placeholder);
await this.code.waitForElements(Selector.CommandDecorationError, true, decorations => decorations && decorations.length === expectedCounts.error); const successSelector = showDecorations === 'overviewRuler' ? `${Selector.CommandDecorationSuccess}${Selector.Hide}` : Selector.CommandDecorationSuccess;
await this.code.waitForElements(successSelector, true, decorations => decorations && decorations.length === expectedCounts.success);
const errorSelector = showDecorations === 'overviewRuler' ? `${Selector.CommandDecorationError}${Selector.Hide}` : Selector.CommandDecorationError;
await this.code.waitForElements(errorSelector, true, decorations => decorations && decorations.length === expectedCounts.error);
} }
if (customConfig) {
await this.code.waitForElements(`.terminal-command-decoration.codicon-${customConfig.updatedIcon}`, true, decorations => decorations && decorations.length === customConfig.count); if (customIcon) {
await this.code.waitForElements(`.terminal-command-decoration.codicon-${customIcon.updatedIcon}`, true, decorations => decorations && decorations.length === customIcon.count);
} }
} }

View file

@ -36,7 +36,6 @@ export function setup() {
}); });
describe('Decorations', function () { describe('Decorations', function () {
describe('Should show default icons', function () { describe('Should show default icons', function () {
it('Placeholder', async () => { it('Placeholder', async () => {
await createShellIntegrationProfile(); await createShellIntegrationProfile();
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 }); await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
@ -62,8 +61,37 @@ export function setup() {
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconSuccess', '"zap"'); await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconSuccess', '"zap"');
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconError', '"zap"'); await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationIconError', '"zap"');
await terminal.assertCommandDecorations(undefined, { updatedIcon: "zap", count: 3 }); await terminal.assertCommandDecorations(undefined, { updatedIcon: "zap", count: 3 });
});
});
describe('terminal.integrated.shellIntegration.decorationsEnabled should determine gutter and overview ruler decoration visibility', function () {
beforeEach(async () => {
await settingsEditor.clearUserSettings();
await setTerminalTestSettings(app, [['terminal.integrated.shellIntegration.enabled', 'true']]);
await createShellIntegrationProfile();
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
await terminal.runCommandInTerminal(`echo "foo"`);
await terminal.runCommandInTerminal(`bar`);
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 });
});
afterEach(async () => {
await app.workbench.terminal.runCommand(TerminalCommandId.KillAll); await app.workbench.terminal.runCommand(TerminalCommandId.KillAll);
}); });
it('never', async () => {
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationsEnabled', '"never"');
await terminal.assertCommandDecorations({ placeholder: 0, success: 0, error: 0 }, undefined, 'never');
});
it('both', async () => {
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationsEnabled', '"both"');
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 }, undefined, 'both');
});
it('gutter', async () => {
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationsEnabled', '"gutter"');
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 }, undefined, 'gutter');
});
it('overviewRuler', async () => {
await settingsEditor.addUserSetting('terminal.integrated.shellIntegration.decorationsEnabled', '"overviewRuler"');
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 }, undefined, 'overviewRuler');
});
}); });
}); });
}); });