terminal option unicodeVersion
This commit is contained in:
+2
-1
@@ -256,7 +256,8 @@ function initOptions(term: TerminalType): void {
|
||||
fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
||||
logLevel: ['debug', 'info', 'warn', 'error', 'off'],
|
||||
rendererType: ['dom', 'canvas'],
|
||||
wordSeparator: null
|
||||
wordSeparator: null,
|
||||
unicodeVersion: ['6', '10']
|
||||
};
|
||||
const options = Object.keys((<any>term)._core.options);
|
||||
const booleanOptions = [];
|
||||
|
||||
+9
-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 { wcwidth, wcwidth10 } from 'common/CharWidth';
|
||||
import { wcwidthV6, wcwidthV10 } from 'common/CharWidth';
|
||||
import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { concat } from 'common/TypedArrayUtils';
|
||||
@@ -127,6 +127,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
private _stringDecoder: StringToUtf32 = new StringToUtf32();
|
||||
private _utf8Decoder: Utf8ToUtf32 = new Utf8ToUtf32();
|
||||
private _workCell: CellData = new CellData();
|
||||
private _wcwidth: (codepoint: number) => number;
|
||||
|
||||
private _onCursorMove = new EventEmitter<void>();
|
||||
public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }
|
||||
@@ -146,6 +147,12 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser())
|
||||
{
|
||||
super();
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '10' ? wcwidthV10 : wcwidthV6;
|
||||
this._optionsService.onOptionChange(option => {
|
||||
if (option === 'unicodeVersion') {
|
||||
this._wcwidth = this._optionsService.options.unicodeVersion === '10' ? wcwidthV10 : wcwidthV6;
|
||||
}
|
||||
});
|
||||
|
||||
this.register(this._parser);
|
||||
|
||||
@@ -393,8 +400,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
// calculate print space
|
||||
// expensive call, therefore we save width in line buffer
|
||||
chWidth = wcwidth(code);
|
||||
chWidth = wcwidth10(code);
|
||||
chWidth = this._wcwidth(code);
|
||||
|
||||
// get charset replacement character
|
||||
// charset is only defined for ASCII, therefore we only
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert, expect } from 'chai';
|
||||
import { MockViewport, MockCompositionHelper, MockRenderer, TestTerminal } from './TestUtils.test';
|
||||
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { wcwidth } from 'common/CharWidth';
|
||||
import { wcwidthV6 } from 'common/CharWidth';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { Linkifier } from 'browser/Linkifier';
|
||||
import { MockLogService } from 'common/TestUtils.test';
|
||||
@@ -762,7 +762,7 @@ describe('Terminal', () => {
|
||||
for (let i = 0xDC00; i <= 0xDCFF; ++i) {
|
||||
term.buffer.x = term.cols - 1;
|
||||
term.wraparoundMode = false;
|
||||
const width = wcwidth((0xD800 - 0xD800) * 0x400 + i - 0xDC00 + 0x10000);
|
||||
const width = wcwidthV6((0xD800 - 0xD800) * 0x400 + i - 0xDC00 + 0x10000);
|
||||
if (width !== 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, IMouseZoneManager, IMouseZone, IRegisteredLinkMatcher } from 'browser/Types';
|
||||
import { IBufferStringIteratorResult } from 'common/buffer/Types';
|
||||
import { getStringCellWidth } from 'common/CharWidth';
|
||||
import { getStringCellWidthV6 } from 'common/CharWidth';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { ILogService, IBufferService } from 'common/services/Services';
|
||||
|
||||
@@ -278,7 +278,7 @@ export class Linkifier implements ILinkifier {
|
||||
return;
|
||||
}
|
||||
|
||||
const width = getStringCellWidth(uri);
|
||||
const width = getStringCellWidthV6(uri); // FIXME: apply options.unicodeVersion
|
||||
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 { wcwidth } from 'common/CharWidth';
|
||||
import { wcwidthV6 } from 'common/CharWidth';
|
||||
|
||||
it('wcwidth should match all values from the old implementation', function(): void {
|
||||
// old implementation
|
||||
@@ -177,6 +177,6 @@ it('wcwidth should match all values from the old implementation', function(): vo
|
||||
|
||||
// test full BMP range old vs new implmenetation
|
||||
for (let i = 0; i < 65536; ++i) {
|
||||
assert.equal(wcwidth(i), wcwidthOld(i), `mismatch for i: ${i}`);
|
||||
assert.equal(wcwidthV6(i), wcwidthOld(i), `mismatch for i: ${i}`);
|
||||
}
|
||||
});
|
||||
|
||||
+10
-10
@@ -5,7 +5,7 @@
|
||||
|
||||
import { fill } from 'common/TypedArrayUtils';
|
||||
|
||||
export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number {
|
||||
export const wcwidthV6 = (function(opts: {nul: number, control: number}): (ucs: number) => number {
|
||||
// extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c
|
||||
// combining characters
|
||||
const COMBINING_BMP = [
|
||||
@@ -141,7 +141,7 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu
|
||||
/**
|
||||
* Get the terminal cell width for a string.
|
||||
*/
|
||||
export function getStringCellWidth(s: string): number {
|
||||
export function getStringCellWidthV6(s: string): number {
|
||||
let result = 0;
|
||||
const length = s.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
@@ -154,7 +154,7 @@ export function getStringCellWidth(s: string): number {
|
||||
// and therefore always should contain the second part
|
||||
// for any other string we still have to handle it somehow:
|
||||
// simply treat the lonely surrogate first as a single char (UCS-2 behavior)
|
||||
return result + wcwidth(code);
|
||||
return result + wcwidthV6(code);
|
||||
}
|
||||
const second = s.charCodeAt(i);
|
||||
// convert surrogate pair to high codepoint only for valid second part (UTF-16)
|
||||
@@ -162,10 +162,10 @@ export function getStringCellWidth(s: string): number {
|
||||
if (0xDC00 <= second && second <= 0xDFFF) {
|
||||
code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
|
||||
} else {
|
||||
result += wcwidth(second);
|
||||
result += wcwidthV6(second);
|
||||
}
|
||||
}
|
||||
result += wcwidth(code);
|
||||
result += wcwidthV6(code);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -377,7 +377,7 @@ for (let r = 0; r < WIDE_BMP.length; ++r) {
|
||||
fill(TABLE, 2, WIDE_BMP[r][0], WIDE_BMP[r][1] + 1);
|
||||
}
|
||||
|
||||
export function wcwidth10(num: number): number {
|
||||
export function wcwidthV10(num: number): number {
|
||||
if (num < 32) {
|
||||
return 0;
|
||||
}
|
||||
@@ -390,7 +390,7 @@ export function wcwidth10(num: number): number {
|
||||
return wcwidthHigh(num);
|
||||
};
|
||||
|
||||
export function getStringCellWidth10(s: string): number {
|
||||
export function getStringCellWidthV10(s: string): number {
|
||||
let result = 0;
|
||||
const length = s.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
@@ -403,7 +403,7 @@ export function getStringCellWidth10(s: string): number {
|
||||
// and therefore always should contain the second part
|
||||
// for any other string we still have to handle it somehow:
|
||||
// simply treat the lonely surrogate first as a single char (UCS-2 behavior)
|
||||
return result + wcwidth10(code);
|
||||
return result + wcwidthV10(code);
|
||||
}
|
||||
const second = s.charCodeAt(i);
|
||||
// convert surrogate pair to high codepoint only for valid second part (UTF-16)
|
||||
@@ -411,10 +411,10 @@ export function getStringCellWidth10(s: string): number {
|
||||
if (0xDC00 <= second && second <= 0xDFFF) {
|
||||
code = (code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
|
||||
} else {
|
||||
result += wcwidth10(second);
|
||||
result += wcwidthV10(second);
|
||||
}
|
||||
}
|
||||
result += wcwidth10(code);
|
||||
result += wcwidthV10(code);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ export const DEFAULT_OPTIONS: ITerminalOptions = Object.freeze({
|
||||
screenKeys: false,
|
||||
cancelEvents: false,
|
||||
useFlowControl: false,
|
||||
wordSeparator: ' ()[]{}\',:;"'
|
||||
wordSeparator: ' ()[]{}\',:;"',
|
||||
unicodeVersion: '6'
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -212,6 +212,7 @@ export interface IPartialTerminalOptions {
|
||||
scrollSensitivity?: number;
|
||||
tabStopWidth?: number;
|
||||
theme?: ITheme;
|
||||
unicodeVersion?: '6' | '10';
|
||||
windowsMode?: boolean;
|
||||
wordSeparator?: string;
|
||||
}
|
||||
@@ -244,6 +245,7 @@ export interface ITerminalOptions {
|
||||
scrollSensitivity: number;
|
||||
tabStopWidth: number;
|
||||
theme: ITheme;
|
||||
unicodeVersion: '6' | '10';
|
||||
windowsMode: boolean;
|
||||
wordSeparator: string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user