Skip to content

Commit

Permalink
Merge pull request microsoft#209258 from microsoft/tyriar/181900
Browse files Browse the repository at this point in the history
Introduce ITerminalConfigurationService, move TerminalConfigHelper.config to it
  • Loading branch information
Tyriar authored Apr 1, 2024
2 parents be1efcc + 8a1fc77 commit fd5ac01
Show file tree
Hide file tree
Showing 20 changed files with 300 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ import { WorkbenchPhase, registerWorkbenchContribution2 } from 'vs/workbench/com
import { EditorExtensions, IEditorFactoryRegistry } from 'vs/workbench/common/editor';
import { IViewContainersRegistry, IViewsRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation } from 'vs/workbench/common/views';
import { RemoteTerminalBackendContribution } from 'vs/workbench/contrib/terminal/browser/remoteTerminalBackend';
import { ITerminalEditorService, ITerminalGroupService, ITerminalInstanceService, ITerminalService, TerminalDataTransfers, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalConfigurationService, ITerminalEditorService, ITerminalGroupService, ITerminalInstanceService, ITerminalService, TerminalDataTransfers, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { registerTerminalActions, terminalSendSequenceCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions';
import { setupTerminalCommands } from 'vs/workbench/contrib/terminal/browser/terminalCommands';
import { TerminalConfigurationService } from 'vs/workbench/contrib/terminal/browser/terminalConfigurationService';
import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor';
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { TerminalInputSerializer } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer';
Expand All @@ -56,6 +57,7 @@ import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalSt

// Register services
registerSingleton(ITerminalLogService, TerminalLogService, InstantiationType.Delayed);
registerSingleton(ITerminalConfigurationService, TerminalConfigurationService, InstantiationType.Delayed);
registerSingleton(ITerminalService, TerminalService, InstantiationType.Delayed);
registerSingleton(ITerminalEditorService, TerminalEditorService, InstantiationType.Delayed);
registerSingleton(ITerminalGroupService, TerminalGroupService, InstantiationType.Delayed);
Expand Down
22 changes: 21 additions & 1 deletion src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ACTIVE_GROUP_TYPE, AUX_WINDOW_GROUP_TYPE, SIDE_GROUP_TYPE } from 'vs/wo
import type { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetection/terminalCommand';

export const ITerminalService = createDecorator<ITerminalService>('terminalService');
export const ITerminalConfigurationService = createDecorator<ITerminalConfigurationService>('terminalConfigurationService');
export const ITerminalEditorService = createDecorator<ITerminalEditorService>('terminalEditorService');
export const ITerminalGroupService = createDecorator<ITerminalGroupService>('terminalGroupService');
export const ITerminalInstanceService = createDecorator<ITerminalInstanceService>('terminalInstanceService');
Expand Down Expand Up @@ -87,7 +88,6 @@ export interface ITerminalInstanceService {
}

export interface ITerminalConfigHelper {
config: ITerminalConfiguration;
panelContainer: HTMLElement | undefined;

configFontIsMonospace(): boolean;
Expand Down Expand Up @@ -352,6 +352,26 @@ export interface ITerminalService extends ITerminalInstanceHost {
*/
createOnInstanceCapabilityEvent<T extends TerminalCapability, K>(capabilityId: T, getEvent: (capability: ITerminalCapabilityImplMap[T]) => Event<K>): IDynamicListEventMultiplexer<{ instance: ITerminalInstance; data: K }>;
}

/**
* A service that provides convenient access to the terminal configuration and derived values.
*/
export interface ITerminalConfigurationService {
readonly _serviceBrand: undefined;

/**
* A typed and partially validated representation of the terminal configuration.
*/
readonly config: Readonly<ITerminalConfiguration>;

/**
* Fires when something within the terminal configuration changes.
*/
readonly onConfigChanged: Event<void>;

// TODO: Expose xterm.js font metrics here
}

export class TerminalLinkQuickPickEvent extends MouseEvent {

}
Expand Down
15 changes: 11 additions & 4 deletions src/vs/workbench/contrib/terminal/browser/terminalActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { ITerminalProfile, TerminalExitReason, TerminalIcon, TerminalLocation, T
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
import { Direction, ICreateTerminalOptions, IDetachedTerminalInstance, ITerminalConfigHelper, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
import { Direction, ICreateTerminalOptions, IDetachedTerminalInstance, ITerminalConfigurationService, ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess';
import { IRemoteTerminalAttachTarget, ITerminalProfileResolverService, ITerminalProfileService, TERMINAL_VIEW_ID, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
Expand Down Expand Up @@ -92,8 +92,13 @@ export interface WorkspaceFolderCwdPair {
isOverridden: boolean;
}

export async function getCwdForSplit(configHelper: ITerminalConfigHelper, instance: ITerminalInstance, folders?: IWorkspaceFolder[], commandService?: ICommandService): Promise<string | URI | undefined> {
switch (configHelper.config.splitCwd) {
export async function getCwdForSplit(
instance: ITerminalInstance,
folders: IWorkspaceFolder[] | undefined,
commandService: ICommandService,
configService: ITerminalConfigurationService
): Promise<string | URI | undefined> {
switch (configService.config.splitCwd) {
case 'workspaceRoot':
if (folders !== undefined && commandService !== undefined) {
if (folders.length === 1) {
Expand Down Expand Up @@ -286,6 +291,7 @@ export function registerActiveXtermAction(

export interface ITerminalServicesCollection {
service: ITerminalService;
configService: ITerminalConfigurationService;
groupService: ITerminalGroupService;
instanceService: ITerminalInstanceService;
editorService: ITerminalEditorService;
Expand All @@ -296,6 +302,7 @@ export interface ITerminalServicesCollection {
function getTerminalServices(accessor: ServicesAccessor): ITerminalServicesCollection {
return {
service: accessor.get(ITerminalService),
configService: accessor.get(ITerminalConfigurationService),
groupService: accessor.get(ITerminalGroupService),
instanceService: accessor.get(ITerminalInstanceService),
editorService: accessor.get(ITerminalEditorService),
Expand Down Expand Up @@ -1183,7 +1190,7 @@ export function registerTerminalActions() {
if (!activeInstance) {
return;
}
const cwd = await getCwdForSplit(c.service.configHelper, activeInstance, workspaceContextService.getWorkspace().folders, commandService);
const cwd = await getCwdForSplit(activeInstance, workspaceContextService.getWorkspace().folders, commandService, c.configService);
if (cwd === undefined) {
return;
}
Expand Down
46 changes: 10 additions & 36 deletions src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
import * as nls from 'vs/nls';
import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalConfiguration, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, DEFAULT_FONT_WEIGHT, DEFAULT_BOLD_FONT_WEIGHT, FontWeight, ITerminalFont } from 'vs/workbench/contrib/terminal/common/terminal';
import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, ITerminalFont } from 'vs/workbench/contrib/terminal/common/terminal';
import Severity from 'vs/base/common/severity';
import { INotificationService, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
import { ITerminalConfigHelper, LinuxDistro } from 'vs/workbench/contrib/terminal/browser/terminal';
import { Emitter, Event } from 'vs/base/common/event';
import { ITerminalConfigHelper, ITerminalConfigurationService, LinuxDistro } from 'vs/workbench/contrib/terminal/browser/terminal';
import { basename } from 'vs/base/common/path';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
Expand All @@ -36,25 +35,16 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
private _charMeasureElement: HTMLElement | undefined;
private _lastFontMeasurement: ITerminalFont | undefined;
protected _linuxDistro: LinuxDistro = LinuxDistro.Unknown;
config!: ITerminalConfiguration;

private readonly _onConfigChanged = this._register(new Emitter<void>());
get onConfigChanged(): Event<void> { return this._onConfigChanged.event; }

constructor(
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IExtensionManagementService private readonly _extensionManagementService: IExtensionManagementService,
@INotificationService private readonly _notificationService: INotificationService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IProductService private readonly _productService: IProductService,
@ITerminalConfigurationService private readonly _terminalConfigurationService: ITerminalConfigurationService,
) {
super();
this._updateConfig();
this._register(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(TERMINAL_CONFIG_SECTION)) {
this._updateConfig();
}
}));
if (isLinux) {
if (navigator.userAgent.includes('Ubuntu')) {
this._linuxDistro = LinuxDistro.Ubuntu;
Expand All @@ -64,18 +54,9 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
}
}

private _updateConfig(): void {
const configValues = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION);
configValues.fontWeight = this._normalizeFontWeight(configValues.fontWeight, DEFAULT_FONT_WEIGHT);
configValues.fontWeightBold = this._normalizeFontWeight(configValues.fontWeightBold, DEFAULT_BOLD_FONT_WEIGHT);

this.config = configValues;
this._onConfigChanged.fire();
}

configFontIsMonospace(): boolean {
const fontSize = 15;
const fontFamily = this.config.fontFamily || this._configurationService.getValue<IEditorOptions>('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily;
const fontFamily = this._terminalConfigurationService.config.fontFamily || this._configurationService.getValue<IEditorOptions>('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily;
const iRect = this._getBoundingRectFor('i', fontFamily, fontSize);
const wRect = this._getBoundingRectFor('w', fontFamily, fontSize);

Expand Down Expand Up @@ -139,7 +120,7 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
this._lastFontMeasurement.charHeight = Math.ceil(rect.height);
// Char width is calculated differently for DOM and the other renderer types. Refer to
// how each renderer updates their dimensions in xterm.js
if (this.config.gpuAcceleration === 'off') {
if (this._terminalConfigurationService.config.gpuAcceleration === 'off') {
this._lastFontMeasurement.charWidth = rect.width;
} else {
const deviceCharWidth = Math.floor(rect.width * w.devicePixelRatio);
Expand All @@ -159,11 +140,11 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
getFont(w: Window, xtermCore?: IXtermCore, excludeDimensions?: boolean): ITerminalFont {
const editorConfig = this._configurationService.getValue<IEditorOptions>('editor');

let fontFamily = this.config.fontFamily || editorConfig.fontFamily || EDITOR_FONT_DEFAULTS.fontFamily;
let fontSize = this._clampInt(this.config.fontSize, FontConstants.MinimumFontSize, FontConstants.MaximumFontSize, EDITOR_FONT_DEFAULTS.fontSize);
let fontFamily = this._terminalConfigurationService.config.fontFamily || editorConfig.fontFamily || EDITOR_FONT_DEFAULTS.fontFamily;
let fontSize = this._clampInt(this._terminalConfigurationService.config.fontSize, FontConstants.MinimumFontSize, FontConstants.MaximumFontSize, EDITOR_FONT_DEFAULTS.fontSize);

// Work around bad font on Fedora/Ubuntu
if (!this.config.fontFamily) {
if (!this._terminalConfigurationService.config.fontFamily) {
if (this._linuxDistro === LinuxDistro.Fedora) {
fontFamily = '\'DejaVu Sans Mono\'';
}
Expand All @@ -178,8 +159,8 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
// Always fallback to monospace, otherwise a proportional font may become the default
fontFamily += ', monospace';

const letterSpacing = this.config.letterSpacing ? Math.max(Math.floor(this.config.letterSpacing), MINIMUM_LETTER_SPACING) : DEFAULT_LETTER_SPACING;
const lineHeight = this.config.lineHeight ? Math.max(this.config.lineHeight, 1) : DEFAULT_LINE_HEIGHT;
const letterSpacing = this._terminalConfigurationService.config.letterSpacing ? Math.max(Math.floor(this._terminalConfigurationService.config.letterSpacing), MINIMUM_LETTER_SPACING) : DEFAULT_LETTER_SPACING;
const lineHeight = this._terminalConfigurationService.config.lineHeight ? Math.max(this._terminalConfigurationService.config.lineHeight, 1) : DEFAULT_LINE_HEIGHT;

if (excludeDimensions) {
return {
Expand Down Expand Up @@ -264,11 +245,4 @@ export class TerminalConfigHelper extends Disposable implements ITerminalConfigH
const extensions = await this._extensionManagementService.getInstalled();
return extensions.some(e => e.identifier.id === id);
}

private _normalizeFontWeight(input: any, defaultWeight: FontWeight): FontWeight {
if (input === 'normal' || input === 'bold') {
return input;
}
return this._clampInt(input, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, defaultWeight);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITerminalConfigurationService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { DEFAULT_BOLD_FONT_WEIGHT, DEFAULT_FONT_WEIGHT, FontWeight, ITerminalConfiguration, MAXIMUM_FONT_WEIGHT, MINIMUM_FONT_WEIGHT, TERMINAL_CONFIG_SECTION } from 'vs/workbench/contrib/terminal/common/terminal';

export class TerminalConfigurationService extends Disposable implements ITerminalConfigurationService {
declare _serviceBrand: undefined;

private _config!: Readonly<ITerminalConfiguration>;
get config() { return this._config; }

private readonly _onConfigChanged = new Emitter<void>();
get onConfigChanged(): Event<void> { return this._onConfigChanged.event; }

constructor(
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
super();
this._register(Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => {
if (!e || e.affectsConfiguration(TERMINAL_CONFIG_SECTION)) {
this._updateConfig();
}
}));
}

private _updateConfig(): void {
const configValues = { ...this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION) };
configValues.fontWeight = this._normalizeFontWeight(configValues.fontWeight, DEFAULT_FONT_WEIGHT);
configValues.fontWeightBold = this._normalizeFontWeight(configValues.fontWeightBold, DEFAULT_BOLD_FONT_WEIGHT);
this._config = configValues;
this._onConfigChanged.fire();
}

private _normalizeFontWeight(input: any, defaultWeight: FontWeight): FontWeight {
if (input === 'normal' || input === 'bold') {
return input;
}
return clampInt(input, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, defaultWeight);
}
}


function clampInt<T>(source: any, minimum: number, maximum: number, fallback: T): number | T {
let r = parseInt(source, 10);
if (isNaN(r)) {
return fallback;
}
if (typeof minimum === 'number') {
r = Math.max(minimum, r);
}
if (typeof maximum === 'number') {
r = Math.min(maximum, r);
}
return r;
}
7 changes: 4 additions & 3 deletions src/vs/workbench/contrib/terminal/browser/terminalEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { IEditorOpenContext } from 'vs/workbench/common/editor';
import { ITerminalEditorService, ITerminalService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalConfigurationService, ITerminalEditorService, ITerminalService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { getTerminalActionBarArgs } from 'vs/workbench/contrib/terminal/browser/terminalMenus';
import { ITerminalProfileResolverService, ITerminalProfileService, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
Expand Down Expand Up @@ -54,6 +54,7 @@ export class TerminalEditor extends EditorPane {
@ITerminalEditorService private readonly _terminalEditorService: ITerminalEditorService,
@ITerminalProfileResolverService private readonly _terminalProfileResolverService: ITerminalProfileResolverService,
@ITerminalService private readonly _terminalService: ITerminalService,
@ITerminalConfigurationService private readonly _terminalConfigurationService: ITerminalConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IMenuService menuService: IMenuService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
Expand Down Expand Up @@ -129,7 +130,7 @@ export class TerminalEditor extends EditorPane {
const terminal = this._terminalEditorService.activeInstance;
terminal?.focus();
} else if (event.which === 3) {
const rightClickBehavior = this._terminalService.configHelper.config.rightClickBehavior;
const rightClickBehavior = this._terminalConfigurationService.config.rightClickBehavior;
if (rightClickBehavior === 'nothing') {
if (!event.shiftKey) {
this._cancelContextMenu = true;
Expand Down Expand Up @@ -172,7 +173,7 @@ export class TerminalEditor extends EditorPane {
}
}));
this._register(dom.addDisposableListener(this._editorInstanceElement, 'contextmenu', (event: MouseEvent) => {
const rightClickBehavior = this._terminalService.configHelper.config.rightClickBehavior;
const rightClickBehavior = this._terminalConfigurationService.config.rightClickBehavior;
if (rightClickBehavior === 'nothing' && !event.shiftKey) {
event.preventDefault();
event.stopImmediatePropagation();
Expand Down
Loading

0 comments on commit fd5ac01

Please sign in to comment.