From cb486e930ff97dcde5df5e78803b4af39ce34b15 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 4 Feb 2020 12:29:37 -0800 Subject: [PATCH] Terminal unicode 11 support Fixes #90029 --- package.json | 1 + remote/package.json | 1 + remote/web/package.json | 1 + remote/web/yarn.lock | 5 ++++ remote/yarn.lock | 5 ++++ .../code/browser/workbench/workbench-dev.html | 1 + src/vs/code/browser/workbench/workbench.html | 1 + .../terminal/browser/terminal.contribution.ts | 10 +++++++ .../contrib/terminal/browser/terminal.ts | 6 +++-- .../terminal/browser/terminalInstance.ts | 18 +++++++++++++ .../browser/terminalInstanceService.ts | 27 ++++++++++++------- .../contrib/terminal/common/terminal.ts | 1 + .../terminalInstanceService.ts | 13 +++++++-- .../terminalLinkHandler.test.ts | 9 ++++--- yarn.lock | 5 ++++ 15 files changed, 88 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 2ec281d3f0f..a5ee2a45350 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "vscode-textmate": "4.4.0", "xterm": "4.4.0", "xterm-addon-search": "0.4.0", + "xterm-addon-unicode11": "0.1.1", "xterm-addon-web-links": "0.2.1", "xterm-addon-webgl": "0.5.0", "yauzl": "^2.9.2", diff --git a/remote/package.json b/remote/package.json index 27a6f5f6ffd..3481542d70f 100644 --- a/remote/package.json +++ b/remote/package.json @@ -22,6 +22,7 @@ "vscode-textmate": "4.4.0", "xterm": "4.4.0", "xterm-addon-search": "0.4.0", + "xterm-addon-unicode11": "0.1.1", "xterm-addon-web-links": "0.2.1", "xterm-addon-webgl": "0.5.0", "yauzl": "^2.9.2", diff --git a/remote/web/package.json b/remote/web/package.json index bf2772093f5..70a55a9074f 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -7,6 +7,7 @@ "vscode-textmate": "4.4.0", "xterm": "4.4.0", "xterm-addon-search": "0.4.0", + "xterm-addon-unicode11": "0.1.1", "xterm-addon-web-links": "0.2.1", "xterm-addon-webgl": "0.5.0" } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 9424e0433c1..b4c1b7d0b6c 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -36,6 +36,11 @@ xterm-addon-search@0.4.0: resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.4.0.tgz#a7beadb3caa7330eb31fb1f17d92de25537684a1" integrity sha512-g07qb/Z4aSfrQ25e6Z6rz6KiExm2DvesQXkx+eA715VABBr5VM/9Jf0INoCiDSYy/nn7rpna+kXiGVJejIffKg== +xterm-addon-unicode11@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.1.1.tgz#b209ef137db38096f68636af4ef4d0c0acba85ad" + integrity sha512-z6vJTL+dpNljwAYzYoyDjJP8A2XjZuEosl0sRa+FGRf3jEyEVWquDM53MfUd1ztVdAPQ839qR6eYK1BXV04Bhw== + xterm-addon-web-links@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2" diff --git a/remote/yarn.lock b/remote/yarn.lock index 7d4351dff72..bc865255b62 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -418,6 +418,11 @@ xterm-addon-search@0.4.0: resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.4.0.tgz#a7beadb3caa7330eb31fb1f17d92de25537684a1" integrity sha512-g07qb/Z4aSfrQ25e6Z6rz6KiExm2DvesQXkx+eA715VABBr5VM/9Jf0INoCiDSYy/nn7rpna+kXiGVJejIffKg== +xterm-addon-unicode11@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.1.1.tgz#b209ef137db38096f68636af4ef4d0c0acba85ad" + integrity sha512-z6vJTL+dpNljwAYzYoyDjJP8A2XjZuEosl0sRa+FGRf3jEyEVWquDM53MfUd1ztVdAPQ839qR6eYK1BXV04Bhw== + xterm-addon-web-links@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2" diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html index af6317d035f..7355cabbb7c 100644 --- a/src/vs/code/browser/workbench/workbench-dev.html +++ b/src/vs/code/browser/workbench/workbench-dev.html @@ -31,6 +31,7 @@ 'onigasm-umd': `${window.location.origin}/static/remote/web/node_modules/onigasm-umd/release/main`, 'xterm': `${window.location.origin}/static/remote/web/node_modules/xterm/lib/xterm.js`, 'xterm-addon-search': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, + 'xterm-addon-unicode11': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`, 'xterm-addon-web-links': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'xterm-addon-webgl': `${window.location.origin}/static/remote/web/node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js`, 'semver-umd': `${window.location.origin}/static/remote/web/node_modules/semver-umd/lib/semver-umd.js`, diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 8a6a9f54e67..db616831643 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -35,6 +35,7 @@ 'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`, 'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`, 'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, + 'xterm-addon-unicode11': `${window.location.origin}/static/node_modules/xterm-addon-unicode11/lib/xterm-addon-unicode11.js`, 'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'xterm-addon-webgl': `${window.location.origin}/static/node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js`, 'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`, diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 1623b352c9f..c21eb0a4e61 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -343,6 +343,16 @@ configurationRegistry.registerConfiguration({ description: nls.localize('terminal.integrated.enableFileLinks', "Whether to enable file links in the terminal. Links can be slow when working on a network drive in particular because each file link is verified against the file system."), type: 'boolean', default: true + }, + 'terminal.integrated.unicodeVersion': { + type: 'string', + enum: ['6', '11'], + enumDescriptions: [ + nls.localize('terminal.integrated.unicodeVersion.six', "Version 6 of unicode, this is an older version which should work better on older systems."), + nls.localize('terminal.integrated.unicodeVersion.eleven', "Version 11 of unicode, this version provides better support for emoji on modern systems.") + ], + default: '11', + description: nls.localize('terminal.integrated.unicodeVersion', "Controls what version of unicode to use when evaluating the width of characters in the terminal. If you experience emoji not taking up the right amount of space or being able to backspace beyond your prompt character then you may want to try tweaking this setting.") } } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 1591ec7f6f7..bf5916960b9 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { Terminal as XTermTerminal } from 'xterm'; -import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; +import { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11'; +import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; 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'; @@ -30,8 +31,9 @@ export interface ITerminalInstanceService { onRequestDefaultShellAndArgs?: Event; getXtermConstructor(): Promise; - getXtermWebLinksConstructor(): Promise; getXtermSearchConstructor(): Promise; + getXtermUnicode11Constructor(): Promise; + getXtermWebLinksConstructor(): Promise; getXtermWebglConstructor(): Promise; createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 11b1ad6f68b..b41879ccedc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -35,6 +35,7 @@ import { ITerminalInstanceService, ITerminalInstance, TerminalShellType } from ' import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager'; import { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm'; import { SearchAddon, ISearchOptions } from 'xterm-addon-search'; +import { Unicode11Addon } from 'xterm-addon-unicode11'; 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'; @@ -200,6 +201,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _xterm: XTermTerminal | undefined; private _xtermCore: XTermCore | undefined; private _xtermSearch: SearchAddon | undefined; + private _xtermUnicode11: Unicode11Addon | undefined; private _xtermElement: HTMLDivElement | undefined; private _terminalHasTextContextKey: IContextKey; private _terminalA11yTreeFocusContextKey: IContextKey; @@ -328,6 +330,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // supported. this.setVisible(this._isVisible); } + if (e.affectsConfiguration('terminal.integrated.unicodeVersion')) { + this._updateUnicodeVersion(); + } if (e.affectsConfiguration('editor.accessibilitySupport')) { this.updateAccessibilitySupport(); } @@ -484,6 +489,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { }); this._xterm = xterm; this._xtermCore = (xterm as any)._core as XTermCore; + this._updateUnicodeVersion(); this.updateAccessibilitySupport(); this._terminalInstanceService.getXtermSearchConstructor().then(Addon => { this._xtermSearch = new Addon(); @@ -1242,6 +1248,18 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + private async _updateUnicodeVersion(): Promise { + if (!this._xterm) { + throw new Error('Cannot update unicode version before xterm has been initialized'); + } + if (!this._xtermUnicode11 && this._configHelper.config.unicodeVersion === '11') { + const Addon = await this._terminalInstanceService.getXtermUnicode11Constructor(); + this._xtermUnicode11 = new Addon(); + this._xterm.loadAddon(this._xtermUnicode11); + } + this._xterm.unicode.activeVersion = this._configHelper.config.unicodeVersion; + } + public updateAccessibilitySupport(): void { const isEnabled = this._accessibilityService.isScreenReaderOptimized(); if (isEnabled) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index 5fa453db273..df405001f97 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -6,16 +6,18 @@ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IWindowsShellHelper, ITerminalChildProcess, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/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 { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11'; +import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; 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'; let Terminal: typeof XTermTerminal; -let WebLinksAddon: typeof XTermWebLinksAddon; let SearchAddon: typeof XTermSearchAddon; +let Unicode11Addon: typeof XTermUnicode11Addon; +let WebLinksAddon: typeof XTermWebLinksAddon; let WebglAddon: typeof XTermWebglAddon; export class TerminalInstanceService implements ITerminalInstanceService { @@ -31,13 +33,6 @@ export class TerminalInstanceService implements ITerminalInstanceService { return Terminal; } - public async getXtermWebLinksConstructor(): Promise { - if (!WebLinksAddon) { - WebLinksAddon = (await import('xterm-addon-web-links')).WebLinksAddon; - } - return WebLinksAddon; - } - public async getXtermSearchConstructor(): Promise { if (!SearchAddon) { SearchAddon = (await import('xterm-addon-search')).SearchAddon; @@ -45,6 +40,20 @@ export class TerminalInstanceService implements ITerminalInstanceService { return SearchAddon; } + public async getXtermUnicode11Constructor(): Promise { + if (!Unicode11Addon) { + Unicode11Addon = (await import('xterm-addon-unicode11')).Unicode11Addon; + } + return Unicode11Addon; + } + + public async getXtermWebLinksConstructor(): Promise { + if (!WebLinksAddon) { + WebLinksAddon = (await import('xterm-addon-web-links')).WebLinksAddon; + } + return WebLinksAddon; + } + public async getXtermWebglConstructor(): Promise { if (!WebglAddon) { WebglAddon = (await import('xterm-addon-webgl')).WebglAddon; diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 563313aeca8..21522a35bd5 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -122,6 +122,7 @@ export interface ITerminalConfiguration { experimentalRefreshOnResume: boolean; experimentalUseTitleEvent: boolean; enableFileLinks: boolean; + unicodeVersion: '6' | '11'; } export interface ITerminalConfigHelper { diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index a825775d8d2..b3632da5988 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -11,8 +11,9 @@ import { IProcessEnvironment, platform, Platform } from 'vs/base/common/platform import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; 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 { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11'; +import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; 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'; @@ -24,8 +25,9 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { ILogService } from 'vs/platform/log/common/log'; let Terminal: typeof XTermTerminal; -let WebLinksAddon: typeof XTermWebLinksAddon; let SearchAddon: typeof XTermSearchAddon; +let Unicode11Addon: typeof XTermUnicode11Addon; +let WebLinksAddon: typeof XTermWebLinksAddon; let WebglAddon: typeof XTermWebglAddon; export class TerminalInstanceService implements ITerminalInstanceService { @@ -63,6 +65,13 @@ export class TerminalInstanceService implements ITerminalInstanceService { return SearchAddon; } + public async getXtermUnicode11Constructor(): Promise { + if (!Unicode11Addon) { + Unicode11Addon = (await import('xterm-addon-unicode11')).Unicode11Addon; + } + return Unicode11Addon; + } + public async getXtermWebglConstructor(): Promise { if (!WebglAddon) { WebglAddon = (await import('xterm-addon-webgl')).WebglAddon; diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index a8c87781724..dcfcf378d02 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -40,12 +40,15 @@ class MockTerminalInstanceService implements ITerminalInstanceService { getXtermConstructor(): Promise { throw new Error('Method not implemented.'); } - async getXtermWebLinksConstructor(): Promise { - return (await import('xterm-addon-web-links')).WebLinksAddon; - } getXtermSearchConstructor(): Promise { throw new Error('Method not implemented.'); } + getXtermUnicode11Constructor(): Promise { + throw new Error('Method not implemented.'); + } + async getXtermWebLinksConstructor(): Promise { + return (await import('xterm-addon-web-links')).WebLinksAddon; + } getXtermWebglConstructor(): Promise { throw new Error('Method not implemented.'); } diff --git a/yarn.lock b/yarn.lock index 057492738cc..63a7c96fd5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10025,6 +10025,11 @@ xterm-addon-search@0.4.0: resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.4.0.tgz#a7beadb3caa7330eb31fb1f17d92de25537684a1" integrity sha512-g07qb/Z4aSfrQ25e6Z6rz6KiExm2DvesQXkx+eA715VABBr5VM/9Jf0INoCiDSYy/nn7rpna+kXiGVJejIffKg== +xterm-addon-unicode11@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.1.1.tgz#b209ef137db38096f68636af4ef4d0c0acba85ad" + integrity sha512-z6vJTL+dpNljwAYzYoyDjJP8A2XjZuEosl0sRa+FGRf3jEyEVWquDM53MfUd1ztVdAPQ839qR6eYK1BXV04Bhw== + xterm-addon-web-links@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2" -- GitLab