diff --git a/src/tsconfig.json b/src/tsconfig.json index dcff5cff53f27..8917d57336d6a 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -24,6 +24,9 @@ "./vs" ], "exclude": [ - "./typings/require-monaco.d.ts" + "./typings/require-monaco.d.ts", + "./typings/xterm.d.ts", + "./typings/xterm-addon-search.d.ts", + "./typings/xterm-addon-web-links.d.ts" ] } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 79138f8545a7a..3e0b3e13d4d2c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -10,7 +10,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; -import { Terminal as XTermTerminal } from 'xterm'; import { INotificationService, NeverShowAgainScope } from 'vs/platform/notification/common/notification'; import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; import { Emitter, Event } from 'vs/base/common/event'; @@ -21,6 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { InstallRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IProductService } from 'vs/platform/product/common/product'; +import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; const MINIMUM_FONT_SIZE = 6; const MAXIMUM_FONT_SIZE = 25; @@ -129,7 +129,7 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { * Gets the font information based on the terminal.integrated.fontFamily * terminal.integrated.fontSize, terminal.integrated.lineHeight configuration properties */ - public getFont(xterm?: XTermTerminal, excludeDimensions?: boolean): ITerminalFont { + public getFont(xtermCore?: XTermCore, excludeDimensions?: boolean): ITerminalFont { const editorConfig = this._configurationService.getValue('editor'); let fontFamily = this.config.fontFamily || editorConfig.fontFamily || EDITOR_FONT_DEFAULTS.fontFamily; @@ -161,15 +161,15 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { } // Get the character dimensions from xterm if it's available - if (xterm) { - if (xterm._core._charSizeService && xterm._core._charSizeService.width && xterm._core._charSizeService.height) { + if (xtermCore) { + if (xtermCore._charSizeService && xtermCore._charSizeService.width && xtermCore._charSizeService.height) { return { fontFamily, fontSize, letterSpacing, lineHeight, - charHeight: xterm._core._charSizeService.height, - charWidth: xterm._core._charSizeService.width + charHeight: xtermCore._charSizeService.height, + charWidth: xtermCore._charSizeService.width }; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index c210bb9d05dc8..2cc1f6ed4919a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -38,6 +38,7 @@ import { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm'; import { SearchAddon, ISearchOptions } from 'xterm-addon-search'; import { CommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon'; import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/addons/navigationModeAddon'; +import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; // How long in milliseconds should an average frame take to render for a notification to appear // which suggests the fallback DOM-based renderer @@ -184,6 +185,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _title: string = ''; private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined; private _xterm: XTermTerminal | undefined; + private _xtermCore: XTermCore | undefined; private _xtermSearch: SearchAddon | undefined; private _xtermElement: HTMLDivElement | undefined; private _terminalHasTextContextKey: IContextKey; @@ -351,7 +353,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return null; } - const font = this._configHelper.getFont(this._xterm); + const font = this._configHelper.getFont(this._xtermCore); if (!font.charWidth || !font.charHeight) { this._setLastKnownColsAndRows(); return null; @@ -399,7 +401,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _getDimension(width: number, height: number): ICanvasDimensions | undefined { // The font needs to have been initialized - const font = this._configHelper.getFont(this._xterm); + const font = this._configHelper.getFont(this._xtermCore); if (!font || !font.charWidth || !font.charHeight) { return undefined; } @@ -412,8 +414,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // needs to happen otherwise its scrollTop value is invalid when the panel is toggled as // it gets removed and then added back to the DOM (resetting scrollTop to 0). // Upstream issue: https://github.com/sourcelair/xterm.js/issues/291 - if (this._xterm) { - this._xterm._core._onScroll.fire(this._xterm.buffer.viewportY); + if (this._xterm && this._xtermCore) { + this._xtermCore._onScroll.fire(this._xterm.buffer.viewportY); } } @@ -472,6 +474,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType }); this._xterm = xterm; + this._xtermCore = (xterm as any)._core as XTermCore; this.updateAccessibilitySupport(); this._terminalInstanceService.getXtermSearchConstructor().then(Addon => { this._xtermSearch = new Addon(); @@ -674,9 +677,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } private async _measureRenderTime(): Promise { - const xterm = await this._xtermReadyPromise; + await this._xtermReadyPromise; const frameTimes: number[] = []; - const textRenderLayer = xterm._core._renderService._renderer._renderLayers[0]; + const textRenderLayer = this._xtermCore!._renderService._renderer._renderLayers[0]; const originalOnGridChanged = textRenderLayer.onGridChanged; const evaluateCanvasRenderer = () => { @@ -893,12 +896,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { if (this._wrapperElement) { dom.toggleClass(this._wrapperElement, 'active', visible); } - if (visible && this._xterm) { + if (visible && this._xterm && this._xtermCore) { // Trigger a manual scroll event which will sync the viewport and scroll bar. This is // necessary if the number of rows in the terminal has decreased while it was in the // background since scrollTop changes take no effect but the terminal's position does // change since the number of visible rows decreases. - this._xterm._core._onScroll.fire(this._xterm.buffer.viewportY); + this._xtermCore._onScroll.fire(this._xterm.buffer.viewportY); if (this._container && this._container.parentElement) { // Force a layout when the instance becomes invisible. This is particularly important // for ensuring that terminals that are created in the background by an extension will @@ -1322,11 +1325,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { let cols = this.cols; let rows = this.rows; - if (this._xterm) { + if (this._xterm && this._xtermCore) { // Only apply these settings when the terminal is visible so that // the characters are measured correctly. if (this._isVisible) { - const font = this._configHelper.getFont(this._xterm); + const font = this._configHelper.getFont(this._xtermCore); const config = this._configHelper.config; this._safeSetOption('letterSpacing', font.letterSpacing); this._safeSetOption('lineHeight', font.lineHeight); @@ -1354,7 +1357,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // maximize on Windows/Linux would fire an event saying that the terminal was not // visible. if (this._xterm.getOption('rendererType') === 'canvas') { - this._xterm._core._renderService._onIntersectionChange({ intersectionRatio: 1 }); + this._xtermCore._renderService._onIntersectionChange({ intersectionRatio: 1 }); // HACK: Force a refresh of the screen to ensure links are refresh corrected. // This can probably be removed when the above hack is fixed in Chromium. this._xterm.refresh(0, this._xterm.rows - 1); diff --git a/src/vs/workbench/contrib/terminal/browser/xterm-private.d.ts b/src/vs/workbench/contrib/terminal/browser/xterm-private.d.ts new file mode 100644 index 0000000000000..50aa2e843a8c1 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/xterm-private.d.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface XTermCore { + _onScroll: IEventEmitter; + _onKey: IEventEmitter<{ key: string }>; + + _charSizeService: { + width: number; + height: number; + }; + + _coreService: { + triggerDataEvent(data: string, wasUserInput?: boolean): void; + }; + + _renderService: { + _renderer: { + _renderLayers: any[]; + }; + _onIntersectionChange: any; + }; + + // TODO: Remove below once a synchronous write API is added + // The below are only used in tests + writeBuffer: string[]; + _innerWrite(): void; +} + +export interface IEventEmitter { + fire(e: T): void; +} diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts index 2c74cd5468289..f6198e4428c62 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts @@ -4,17 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { Terminal, TerminalCore } from 'xterm'; +import { Terminal } from 'xterm'; import { CommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon'; import { isWindows } from 'vs/base/common/platform'; - -interface TestTerminalCore extends TerminalCore { - writeBuffer: string[]; - _innerWrite(): void; -} +import { XTermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; interface TestTerminal extends Terminal { - _core: TestTerminalCore; + _core: XTermCore; } function syncWrite(term: TestTerminal, data: string): void {