mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
change to v11, expose unicodeVersion, fix linkifier
This commit is contained in:
+1
-1
@@ -257,7 +257,7 @@ function initOptions(term: TerminalType): void {
|
||||
logLevel: ['debug', 'info', 'warn', 'error', 'off'],
|
||||
rendererType: ['dom', 'canvas'],
|
||||
wordSeparator: null,
|
||||
unicodeVersion: ['6', '10']
|
||||
unicodeVersion: ['6', '11']
|
||||
};
|
||||
const options = Object.keys((<any>term)._core.options);
|
||||
const booleanOptions = [];
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
import { IInputHandler, IInputHandlingTerminal } from './Types';
|
||||
import { C0, C1 } from 'common/data/EscapeSequences';
|
||||
import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets';
|
||||
import { wcwidthV6, wcwidthV10 } from 'common/CharWidth';
|
||||
import { wcwidthV6, wcwidthV11 } from 'common/CharWidth';
|
||||
import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { concat } from 'common/TypedArrayUtils';
|
||||
@@ -147,10 +147,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser())
|
||||
{
|
||||
super();
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '10' ? wcwidthV10 : wcwidthV6;
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '11' ? wcwidthV11 : wcwidthV6;
|
||||
this._optionsService.onOptionChange(option => {
|
||||
if (option === 'unicodeVersion') {
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '10' ? wcwidthV10 : wcwidthV6;
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '11' ? wcwidthV11 : wcwidthV6;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { CellData } from 'common/buffer/CellData';
|
||||
import { wcwidthV6 } from 'common/CharWidth';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { Linkifier } from 'browser/Linkifier';
|
||||
import { MockLogService } from 'common/TestUtils.test';
|
||||
import { MockLogService, MockOptionsService } from 'common/TestUtils.test';
|
||||
import { IRegisteredLinkMatcher, IMouseZoneManager, IMouseZone } from 'browser/Types';
|
||||
|
||||
const INIT_COLS = 80;
|
||||
@@ -1371,7 +1371,7 @@ describe('Terminal', () => {
|
||||
|
||||
class TestLinkifier extends Linkifier {
|
||||
constructor(bufferService: IBufferService) {
|
||||
super(bufferService, new MockLogService());
|
||||
super(bufferService, new MockLogService(), new MockOptionsService());
|
||||
Linkifier._timeBeforeLatency = 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
this._inputHandler.onLineFeed(() => this._onLineFeed.fire());
|
||||
this.register(this._inputHandler);
|
||||
|
||||
this.linkifier = this.linkifier || new Linkifier(this._bufferService, this._logService);
|
||||
this.linkifier = this.linkifier || new Linkifier(this._bufferService, this._logService, this.optionsService);
|
||||
|
||||
if (this.options.windowsMode) {
|
||||
this._windowsMode = applyWindowsMode(this);
|
||||
|
||||
@@ -9,12 +9,12 @@ import { IBufferLine } from 'common/Types';
|
||||
import { Linkifier } from 'browser/Linkifier';
|
||||
import { BufferLine } from 'common/buffer/BufferLine';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { MockLogService, MockBufferService } from 'common/TestUtils.test';
|
||||
import { MockLogService, MockBufferService, MockOptionsService } from 'common/TestUtils.test';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
|
||||
class TestLinkifier extends Linkifier {
|
||||
constructor(bufferService: IBufferService) {
|
||||
super(bufferService, new MockLogService());
|
||||
super(bufferService, new MockLogService(), new MockOptionsService());
|
||||
Linkifier._timeBeforeLatency = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, IMouseZoneManager, IMouseZone, IRegisteredLinkMatcher } from 'browser/Types';
|
||||
import { IBufferStringIteratorResult } from 'common/buffer/Types';
|
||||
import { getStringCellWidthV6 } from 'common/CharWidth';
|
||||
import { getStringCellWidthV6, getStringCellWidthV11 } from 'common/CharWidth';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { ILogService, IBufferService } from 'common/services/Services';
|
||||
import { ILogService, IBufferService, IOptionsService } from 'common/services/Services';
|
||||
|
||||
/**
|
||||
* Limit of the unwrapping line expansion (overscan) at the top and bottom
|
||||
@@ -45,7 +45,8 @@ export class Linkifier implements ILinkifier {
|
||||
|
||||
constructor(
|
||||
protected readonly _bufferService: IBufferService,
|
||||
private readonly _logService: ILogService
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _optionsService: IOptionsService
|
||||
) {
|
||||
this._rowsToLinkify = {
|
||||
start: undefined,
|
||||
@@ -277,8 +278,7 @@ export class Linkifier implements ILinkifier {
|
||||
if (!this._mouseZoneManager || !this._element) {
|
||||
return;
|
||||
}
|
||||
|
||||
const width = getStringCellWidthV6(uri); // FIXME: apply options.unicodeVersion
|
||||
const width = this._optionsService.options.unicodeVersion === '11' ? getStringCellWidthV11(uri) : getStringCellWidthV6(uri);
|
||||
const x1 = x % this._bufferService.cols;
|
||||
const y1 = y + Math.floor(x / this._bufferService.cols);
|
||||
let x2 = (x1 + width) % this._bufferService.cols;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { wcwidthV6 } from 'common/CharWidth';
|
||||
import { wcwidthV6, getStringCellWidthV6, getStringCellWidthV11 } from 'common/CharWidth';
|
||||
|
||||
it('wcwidth should match all values from the old implementation', function(): void {
|
||||
// old implementation
|
||||
@@ -180,3 +180,10 @@ it('wcwidth should match all values from the old implementation', function(): vo
|
||||
assert.equal(wcwidthV6(i), wcwidthOld(i), `mismatch for i: ${i}`);
|
||||
}
|
||||
});
|
||||
|
||||
it('wcwidth V6 vs. V11', () => {
|
||||
const widthV6 = getStringCellWidthV6('🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣');
|
||||
assert.equal(widthV6, 10);
|
||||
const widthV10 = getStringCellWidthV11('🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣');
|
||||
assert.equal(widthV10, 20);
|
||||
});
|
||||
|
||||
+19
-19
@@ -159,7 +159,7 @@ export function getStringCellWidthV6(s: string): number {
|
||||
/**
|
||||
* Unicode version 10
|
||||
*/
|
||||
const BMP_COMBINING_V10 = [
|
||||
const BMP_COMBINING_V11 = [
|
||||
[0x0300, 0x036F], [0x0483, 0x0489], [0x0591, 0x05BD],
|
||||
[0x05BF, 0x05BF], [0x05C1, 0x05C2], [0x05C4, 0x05C5],
|
||||
[0x05C7, 0x05C7], [0x0600, 0x0605], [0x0610, 0x061A],
|
||||
@@ -234,7 +234,7 @@ const BMP_COMBINING_V10 = [
|
||||
[0xFFF9, 0xFFFB]
|
||||
];
|
||||
|
||||
const HIGH_COMBINING_V10 = [
|
||||
const HIGH_COMBINING_V11 = [
|
||||
[0x101FD, 0x101FD], [0x102E0, 0x102E0],
|
||||
[0x10376, 0x1037A], [0x10A01, 0x10A03], [0x10A05, 0x10A06],
|
||||
[0x10A0C, 0x10A0F], [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F],
|
||||
@@ -277,7 +277,7 @@ const HIGH_COMBINING_V10 = [
|
||||
[0xE0100, 0xE01EF]
|
||||
];
|
||||
|
||||
const BMP_WIDE_V10 = [
|
||||
const BMP_WIDE_V11 = [
|
||||
[0x1100, 0x115F], [0x231A, 0x231B], [0x2329, 0x232A],
|
||||
[0x23E9, 0x23EC], [0x23F0, 0x23F0], [0x23F3, 0x23F3],
|
||||
[0x25FD, 0x25FE], [0x2614, 0x2615], [0x2648, 0x2653],
|
||||
@@ -301,7 +301,7 @@ const BMP_WIDE_V10 = [
|
||||
[0xFFE0, 0xFFE6]
|
||||
];
|
||||
|
||||
const HIGH_WIDE_V10 = [
|
||||
const HIGH_WIDE_V11 = [
|
||||
[0x16FE0, 0x16FE3], [0x17000, 0x187F7],
|
||||
[0x18800, 0x18AF2], [0x1B000, 0x1B11E], [0x1B150, 0x1B152],
|
||||
[0x1B164, 0x1B167], [0x1B170, 0x1B2FB], [0x1F004, 0x1F004],
|
||||
@@ -322,27 +322,27 @@ const HIGH_WIDE_V10 = [
|
||||
[0x1FA90, 0x1FA95], [0x20000, 0x2FFFD], [0x30000, 0x3FFFD]
|
||||
];
|
||||
|
||||
const BMP_TABLE_V10 = new Uint8Array(65536);
|
||||
fill(BMP_TABLE_V10, 1);
|
||||
BMP_TABLE_V10[0] = 0;
|
||||
fill(BMP_TABLE_V10, 0, 1, 32);
|
||||
fill(BMP_TABLE_V10, 0, 0x7f, 0xa0);
|
||||
for (let r = 0; r < BMP_COMBINING_V10.length; ++r) {
|
||||
fill(BMP_TABLE_V10, 0, BMP_COMBINING_V10[r][0], BMP_COMBINING_V10[r][1] + 1);
|
||||
const BMP_TABLE_V11 = new Uint8Array(65536);
|
||||
fill(BMP_TABLE_V11, 1);
|
||||
BMP_TABLE_V11[0] = 0;
|
||||
fill(BMP_TABLE_V11, 0, 1, 32);
|
||||
fill(BMP_TABLE_V11, 0, 0x7f, 0xa0);
|
||||
for (let r = 0; r < BMP_COMBINING_V11.length; ++r) {
|
||||
fill(BMP_TABLE_V11, 0, BMP_COMBINING_V11[r][0], BMP_COMBINING_V11[r][1] + 1);
|
||||
}
|
||||
for (let r = 0; r < BMP_WIDE_V10.length; ++r) {
|
||||
fill(BMP_TABLE_V10, 2, BMP_WIDE_V10[r][0], BMP_WIDE_V10[r][1] + 1);
|
||||
for (let r = 0; r < BMP_WIDE_V11.length; ++r) {
|
||||
fill(BMP_TABLE_V11, 2, BMP_WIDE_V11[r][0], BMP_WIDE_V11[r][1] + 1);
|
||||
}
|
||||
|
||||
export function wcwidthV10(num: number): number {
|
||||
export function wcwidthV11(num: number): number {
|
||||
if (num < 32) return 0;
|
||||
if (num < 127) return 1;
|
||||
if (num < 65536) return BMP_TABLE_V10[num];
|
||||
if (bisearch(num, HIGH_COMBINING_V10)) return 0;
|
||||
if (bisearch(num, HIGH_WIDE_V10)) return 2;
|
||||
if (num < 65536) return BMP_TABLE_V11[num];
|
||||
if (bisearch(num, HIGH_COMBINING_V11)) return 0;
|
||||
if (bisearch(num, HIGH_WIDE_V11)) return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
export function getStringCellWidthV10(s: string): number {
|
||||
return getStringCellWidthPrivate(wcwidthV10, s);
|
||||
export function getStringCellWidthV11(s: string): number {
|
||||
return getStringCellWidthPrivate(wcwidthV11, s);
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ export interface IPartialTerminalOptions {
|
||||
scrollSensitivity?: number;
|
||||
tabStopWidth?: number;
|
||||
theme?: ITheme;
|
||||
unicodeVersion?: '6' | '10';
|
||||
unicodeVersion?: '6' | '11';
|
||||
windowsMode?: boolean;
|
||||
wordSeparator?: string;
|
||||
}
|
||||
@@ -245,7 +245,7 @@ export interface ITerminalOptions {
|
||||
scrollSensitivity: number;
|
||||
tabStopWidth: number;
|
||||
theme: ITheme;
|
||||
unicodeVersion: '6' | '10';
|
||||
unicodeVersion: '6' | '11';
|
||||
windowsMode: boolean;
|
||||
wordSeparator: string;
|
||||
|
||||
|
||||
Vendored
+5
@@ -198,6 +198,11 @@ declare module 'xterm' {
|
||||
*/
|
||||
theme?: ITheme;
|
||||
|
||||
/**
|
||||
* Unicode version to be used for wcwidth. Default is version 6.
|
||||
*/
|
||||
unicodeVersion?: '6' | '11';
|
||||
|
||||
/**
|
||||
* Whether "Windows mode" is enabled. Because Windows backends winpty and
|
||||
* conpty operate by doing line wrapping on their side, xterm.js does not
|
||||
|
||||
Reference in New Issue
Block a user