From 43303ba4c1c10ccb62fe0e0fdfa85807f7903325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 5 Dec 2019 21:30:59 +0100 Subject: [PATCH] add interfaces and option handling --- src/Terminal.ts | 5 ++++ src/common/input/UnicodeV11.ts | 4 +-- src/common/input/UnicodeV6.ts | 4 +-- src/common/services/Services.ts | 4 +-- src/common/services/UnicodeService.test.ts | 6 ++--- src/public/Terminal.ts | 23 +++++++++++++++- typings/xterm.d.ts | 31 ++++++++++++++++++++++ 7 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index b2586df9..5a655da7 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -391,6 +391,11 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this._windowsMode = undefined; } break; + case 'unicodeVersion': + if (this._unicodeService.activeVersion !== this.optionsService.options.unicodeVersion) { + this._unicodeService.activeVersion = this.optionsService.options.unicodeVersion; + } + break; } }); } diff --git a/src/common/input/UnicodeV11.ts b/src/common/input/UnicodeV11.ts index 6393e3f5..b3ee56d3 100644 --- a/src/common/input/UnicodeV11.ts +++ b/src/common/input/UnicodeV11.ts @@ -205,10 +205,10 @@ export class UnicodeV11 implements IUnicodeVersionProvider { } } - public wcwidth(num: number): number { + public wcwidth(num: number): 0 | 1 | 2 { if (num < 32) return 0; if (num < 127) return 1; - if (num < 65536) return UnicodeV11.bmpTable[num]; + if (num < 65536) return UnicodeV11.bmpTable[num] as 0 | 1 | 2; if (UnicodeV11.bisearch(num, UnicodeV11.highCombining)) return 0; if (UnicodeV11.bisearch(num, UnicodeV11.highWide)) return 2; return 1; diff --git a/src/common/input/UnicodeV6.ts b/src/common/input/UnicodeV6.ts index 56ee71fd..af5089b2 100644 --- a/src/common/input/UnicodeV6.ts +++ b/src/common/input/UnicodeV6.ts @@ -118,10 +118,10 @@ export class UnicodeV6 implements IUnicodeVersionProvider { } } - public wcwidth(num: number): number { + public wcwidth(num: number): 0 | 1 | 2 { if (num < 32) return 0; if (num < 127) return 1; - if (num < 65536) return UnicodeV6.bmpTable[num]; + if (num < 65536) return UnicodeV6.bmpTable[num] as 0 | 1 | 2; if (UnicodeV6.bisearch(num, UnicodeV6.highCombining)) return 0; if ((num >= 0x20000 && num <= 0x2fffd) || (num >= 0x30000 && num <= 0x3fffd)) return 2; return 1; diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 554e5e96..9ee348fb 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -289,7 +289,7 @@ export interface IUnicodeService { /** Registered Unicode versions. */ readonly versions: string[]; /** Currently active version. */ - readonly activeVersion: string; + activeVersion: string; /** Event triggered, when activate version changed. */ readonly onChange: IEvent; @@ -302,5 +302,5 @@ export interface IUnicodeService { export interface IUnicodeVersionProvider { version: string; - wcwidth(ucs: number): number; + wcwidth(ucs: number): 0 | 1 | 2; } diff --git a/src/common/services/UnicodeService.test.ts b/src/common/services/UnicodeService.test.ts index 7df72605..cb03b09b 100644 --- a/src/common/services/UnicodeService.test.ts +++ b/src/common/services/UnicodeService.test.ts @@ -9,8 +9,8 @@ import { IUnicodeVersionProvider } from 'common/services/Services'; class DummyProvider implements IUnicodeVersionProvider { version = '123'; - wcwidth(n: number): number { - return 123; + wcwidth(n: number): 0 | 1 | 2 { + return 2; } } @@ -41,7 +41,7 @@ describe('unicode provider', () => { const dummyProvider = new DummyProvider(); us.register(dummyProvider); us.activeVersion = dummyProvider.version; - assert.equal(us.getStringCellWidth('hello'), 123 * 5); + assert.equal(us.getStringCellWidth('hello'), 2 * 5); }); it('wcwidth V6 emoji test', () => { const widthV6 = us.getStringCellWidth('🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣'); diff --git a/src/public/Terminal.ts b/src/public/Terminal.ts index 397898c7..75c35e84 100644 --- a/src/public/Terminal.ts +++ b/src/public/Terminal.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi, IParser, IFunctionIdentifier } from 'xterm'; +import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi, IParser, IFunctionIdentifier, IUnicodeHandling, IUnicodeVersionProvider } from 'xterm'; import { ITerminal } from '../Types'; import { IBufferLine } from 'common/Types'; import { IBuffer } from 'common/buffer/Types'; @@ -41,6 +41,9 @@ export class Terminal implements ITerminalApi { } return this._parser; } + public get unicode(): IUnicodeHandling { + return new UnicodeApi(this._core); + } public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; } public get rows(): number { return this._core.rows; } public get cols(): number { return this._core.cols; } @@ -240,3 +243,21 @@ class ParserApi implements IParser { return this._core.addOscHandler(ident, callback); } } + +class UnicodeApi implements IUnicodeHandling { + constructor(private _core: ITerminal) {} + + public register(provider: IUnicodeVersionProvider): void {} + + public get versions(): string[] { + return (this._core as any)._unicodeService.versions; + } + + public get activeVersion(): string { + return (this._core as any)._unicodeService.activeVersion; + } + + public set activeVersion(version: string) { + (this._core as any)._unicodeService.activeVersion = version; + } +} diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index a00bdcca..a1ecbbff 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -426,6 +426,12 @@ declare module 'xterm' { */ readonly parser: IParser; + /** + * (EXPERIMENTAL) Get the Unicode handling interface + * to register and switch Unicode version. + */ + readonly unicode: IUnicodeHandling; + /** * Natural language strings that can be localized. */ @@ -1130,4 +1136,29 @@ declare module 'xterm' { */ addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable; } + + /** + * (EXPERIMENTAL) Unicode version provider. + * Used to register custom Unicode versions with `Terminal.unicode.register`. + */ + export interface IUnicodeVersionProvider { + /** String indicating the Unicode version provided. */ + version: string; + /** Unicode version dependent wcwidth implementation. */ + wcwidth(ucs: number): 0 | 1 | 2; + } + + /** + * (EXPERIMENTAL) Unicode handling interface. + */ + export interface IUnicodeHandling { + /** + * Register a custom Unicode version provider. + */ + register(provider: IUnicodeVersionProvider): void; + /** + * Registered Unicode versions. + */ + versions: string[]; + } }