Merge branch 'master' into buffer_optimizations
This commit is contained in:
@@ -82,7 +82,7 @@ export class CircularList<T> extends Disposable implements ICircularList<T> {
|
||||
* Note that for performance reasons there is no bounds checking here, the index reference is
|
||||
* circular so this should always return a value and never throw.
|
||||
* @param index The index of the value to get.
|
||||
* @return The value corresponding to the index.
|
||||
* @returns The value corresponding to the index.
|
||||
*/
|
||||
public get(index: number): T | undefined {
|
||||
return this._array[this._getCyclicIndex(index)];
|
||||
@@ -138,7 +138,7 @@ export class CircularList<T> extends Disposable implements ICircularList<T> {
|
||||
|
||||
/**
|
||||
* Removes and returns the last value on the list.
|
||||
* @return The popped value.
|
||||
* @returns The popped value.
|
||||
*/
|
||||
public pop(): T | undefined {
|
||||
return this._array[this._getCyclicIndex(this._length-- - 1)];
|
||||
|
||||
@@ -184,6 +184,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
||||
|
||||
/**
|
||||
* Scroll the terminal down 1 row, creating a blank line.
|
||||
* @param eraseAttr The attribute data to use the for blank line.
|
||||
* @param isWrapped Whether the new line is wrapped from the previous line.
|
||||
*/
|
||||
public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {
|
||||
|
||||
@@ -8,8 +8,8 @@ import { InputHandler } from 'common/InputHandler';
|
||||
import { IBufferLine, IAttributeData, IColorEvent, ColorIndex, ColorRequestType } from 'common/Types';
|
||||
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { Attributes, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { AttributeData } from 'common/buffer/AttributeData';
|
||||
import { Attributes, BgFlags, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData';
|
||||
import { Params } from 'common/parser/Params';
|
||||
import { MockCoreService, MockBufferService, MockOptionsService, MockLogService, MockCoreMouseService, MockCharsetService, MockUnicodeService, MockOscLinkService } from 'common/TestUtils.test';
|
||||
import { IBufferService, ICoreService } from 'common/services/Services';
|
||||
@@ -1689,6 +1689,37 @@ describe('InputHandler', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('reset text attributes (SGR 0)', () => {
|
||||
it('resets all attributes if there is no url', async () => {
|
||||
await inputHandler.parseP('\x1b[30m\x1b[40m\x1b[4m');
|
||||
assert.notEqual(inputHandler.curAttrData.fg, 0);
|
||||
assert.notEqual(inputHandler.curAttrData.bg, 0);
|
||||
assert.isFalse(inputHandler.curAttrData.extended.isEmpty());
|
||||
|
||||
await inputHandler.parseP('\x1b[m');
|
||||
assert.equal(inputHandler.curAttrData.fg, 0);
|
||||
assert.equal(inputHandler.curAttrData.bg, 0);
|
||||
assert.isTrue(inputHandler.curAttrData.extended.isEmpty());
|
||||
});
|
||||
|
||||
it('resets all attributes except for the url', async () => {
|
||||
await inputHandler.parseP('\x1b[30m\x1b[40m\x1b[4m');
|
||||
await inputHandler.parseP('\x1b]8;;http://example.com\x1b\\');
|
||||
assert.notEqual(inputHandler.curAttrData.fg, 0);
|
||||
assert.notEqual(inputHandler.curAttrData.bg, 0);
|
||||
assert.notEqual(inputHandler.curAttrData.extended.ext, 0);
|
||||
const urlId = inputHandler.curAttrData.extended.urlId;
|
||||
assert.notEqual(urlId, 0);
|
||||
|
||||
await inputHandler.parseP('\x1b[m');
|
||||
assert.equal(inputHandler.curAttrData.fg, 0);
|
||||
assert.equal(inputHandler.curAttrData.bg, BgFlags.HAS_EXTENDED);
|
||||
const expectedExtended = new ExtendedAttrs();
|
||||
expectedExtended.urlId = urlId;
|
||||
assert.deepEqual(inputHandler.curAttrData.extended, expectedExtended);
|
||||
});
|
||||
});
|
||||
|
||||
describe('extended underline style support (SGR 4)', () => {
|
||||
beforeEach(() => {
|
||||
bufferService.resize(10, 5);
|
||||
|
||||
+27
-16
@@ -11,7 +11,7 @@ import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from 'common/input/TextDecoder';
|
||||
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { EventEmitter } from 'common/EventEmitter';
|
||||
import { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from 'common/parser/Types';
|
||||
import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
@@ -121,7 +121,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
private _workCell: CellData = new CellData();
|
||||
private _windowTitle = '';
|
||||
private _iconName = '';
|
||||
private _currentLinkId?: number;
|
||||
private _dirtyRowTracker: IDirtyRowTracker;
|
||||
protected _windowTitleStack: string[] = [];
|
||||
protected _iconNameStack: string[] = [];
|
||||
@@ -406,6 +405,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private _getCurrentLinkId(): number {
|
||||
return this._curAttrData.extended.urlId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse call with async handler support.
|
||||
*
|
||||
@@ -533,8 +536,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (screenReaderMode) {
|
||||
this._onA11yChar.fire(stringFromCodePoint(code));
|
||||
}
|
||||
if (this._currentLinkId !== undefined) {
|
||||
this._oscLinkService.addLineToLink(this._currentLinkId, this._activeBuffer.ybase + this._activeBuffer.y);
|
||||
if (this._getCurrentLinkId()) {
|
||||
this._oscLinkService.addLineToLink(this._getCurrentLinkId(), this._activeBuffer.ybase + this._activeBuffer.y);
|
||||
}
|
||||
|
||||
// insert combining char at last cursor position
|
||||
@@ -1116,10 +1119,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* Helper method to erase cells in a terminal row.
|
||||
* The cell gets replaced with the eraseChar of the terminal.
|
||||
* @param y row index
|
||||
* @param start first cell index to be erased
|
||||
* @param end end - 1 is last erased cell
|
||||
* @param cleanWrap clear the isWrapped flag
|
||||
* @param y The row index relative to the viewport.
|
||||
* @param start The start x index of the range to be erased.
|
||||
* @param end The end x index of the range to be erased (exclusive).
|
||||
* @param clearWrap clear the isWrapped flag
|
||||
* @param respectProtect Whether to respect the protection attribute (DECSCA).
|
||||
*/
|
||||
private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false, respectProtect: boolean = false): void {
|
||||
const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;
|
||||
@@ -2352,6 +2356,17 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
attr.updateExtended();
|
||||
}
|
||||
|
||||
private _processSGR0(attr: IAttributeData): void {
|
||||
attr.fg = DEFAULT_ATTR_DATA.fg;
|
||||
attr.bg = DEFAULT_ATTR_DATA.bg;
|
||||
attr.extended = attr.extended.clone();
|
||||
// Reset underline style and color. Note that we don't want to reset other
|
||||
// fields such as the url id.
|
||||
attr.extended.underlineStyle = UnderlineStyle.NONE;
|
||||
attr.extended.underlineColor &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);
|
||||
attr.updateExtended();
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI Pm m Character Attributes (SGR).
|
||||
*
|
||||
@@ -2437,8 +2452,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
public charAttributes(params: IParams): boolean {
|
||||
// Optimize a single SGR0.
|
||||
if (params.length === 1 && params.params[0] === 0) {
|
||||
this._curAttrData.fg = DEFAULT_ATTR_DATA.fg;
|
||||
this._curAttrData.bg = DEFAULT_ATTR_DATA.bg;
|
||||
this._processSGR0(this._curAttrData);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2466,8 +2480,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
attr.bg |= Attributes.CM_P16 | (p - 100) | 8;
|
||||
} else if (p === 0) {
|
||||
// default
|
||||
attr.fg = DEFAULT_ATTR_DATA.fg;
|
||||
attr.bg = DEFAULT_ATTR_DATA.bg;
|
||||
this._processSGR0(attr);
|
||||
} else if (p === 1) {
|
||||
// bold text
|
||||
attr.fg |= FgFlags.BOLD;
|
||||
@@ -2934,7 +2947,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
private _createHyperlink(params: string, uri: string): boolean {
|
||||
// It's legal to open a new hyperlink without explicitly finishing the previous one
|
||||
if (this._currentLinkId !== undefined) {
|
||||
if (this._getCurrentLinkId()) {
|
||||
this._finishHyperlink();
|
||||
}
|
||||
const parsedParams = params.split(':');
|
||||
@@ -2944,8 +2957,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
id = parsedParams[idParamIndex].slice(3) || undefined;
|
||||
}
|
||||
this._curAttrData.extended = this._curAttrData.extended.clone();
|
||||
this._currentLinkId = this._oscLinkService.registerLink({ id, uri });
|
||||
this._curAttrData.extended.urlId = this._currentLinkId;
|
||||
this._curAttrData.extended.urlId = this._oscLinkService.registerLink({ id, uri });
|
||||
this._curAttrData.updateExtended();
|
||||
return true;
|
||||
}
|
||||
@@ -2954,7 +2966,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._curAttrData.extended = this._curAttrData.extended.clone();
|
||||
this._curAttrData.extended.urlId = 0;
|
||||
this._curAttrData.updateExtended();
|
||||
this._currentLinkId = undefined;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,15 @@ export abstract class Disposable implements IDisposable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the object, triggering the `dispose` method on all registered IDisposables. This is a
|
||||
* readonly property instead of a method to prevent subclasses overriding it which is an easy
|
||||
* mistake that can introduce memory leaks. If a class extends Disposable, all dispose calls
|
||||
* should be done via {@link register}.
|
||||
* Disposes the object, triggering the `dispose` method on all registered IDisposables.
|
||||
*/
|
||||
public readonly dispose = (): void => {
|
||||
public dispose(): void {
|
||||
this._isDisposed = true;
|
||||
for (const d of this._disposables) {
|
||||
d.dispose();
|
||||
}
|
||||
this._disposables.length = 0;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a disposable object.
|
||||
|
||||
@@ -20,6 +20,16 @@ const platform = (isNode) ? 'node' : navigator.platform;
|
||||
export const isFirefox = userAgent.includes('Firefox');
|
||||
export const isLegacyEdge = userAgent.includes('Edge');
|
||||
export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
export function getSafariVersion(): number {
|
||||
if (!isSafari) {
|
||||
return 0;
|
||||
}
|
||||
const majorVersion = userAgent.match(/Version\/(\d+)/);
|
||||
if (majorVersion === null || majorVersion.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
return parseInt(majorVersion[1]);
|
||||
}
|
||||
|
||||
// Find the users platform. We use this to interpret the meta key
|
||||
// and ISO third level shifts.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
import { assert } from 'chai';
|
||||
import { fillFallback, concat } from 'common/TypedArrayUtils';
|
||||
import { concat } from 'common/TypedArrayUtils';
|
||||
|
||||
type TypedArray = Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array;
|
||||
|
||||
@@ -14,77 +14,6 @@ function deepEquals(a: TypedArray, b: TypedArray): void {
|
||||
}
|
||||
}
|
||||
|
||||
describe('polyfill conformance tests', function(): void {
|
||||
describe('TypedArray.fill', function(): void {
|
||||
it('should work with all typed array types', function(): void {
|
||||
const u81 = new Uint8Array(5);
|
||||
const u82 = new Uint8Array(5);
|
||||
deepEquals(fillFallback(u81, 2), u82.fill(2));
|
||||
deepEquals(fillFallback(u81, -1), u82.fill(-1));
|
||||
const u161 = new Uint16Array(5);
|
||||
const u162 = new Uint16Array(5);
|
||||
deepEquals(fillFallback(u161, 2), u162.fill(2));
|
||||
deepEquals(fillFallback(u161, 65535), u162.fill(65535));
|
||||
deepEquals(fillFallback(u161, -1), u162.fill(-1));
|
||||
const u321 = new Uint32Array(5);
|
||||
const u322 = new Uint32Array(5);
|
||||
deepEquals(fillFallback(u321, 2), u322.fill(2));
|
||||
deepEquals(fillFallback(u321, 65537), u322.fill(65537));
|
||||
deepEquals(fillFallback(u321, -1), u322.fill(-1));
|
||||
const i81 = new Int8Array(5);
|
||||
const i82 = new Int8Array(5);
|
||||
deepEquals(fillFallback(i81, 2), i82.fill(2));
|
||||
deepEquals(fillFallback(i81, -1), i82.fill(-1));
|
||||
const i161 = new Int16Array(5);
|
||||
const i162 = new Int16Array(5);
|
||||
deepEquals(fillFallback(i161, 2), i162.fill(2));
|
||||
deepEquals(fillFallback(i161, 65535), i162.fill(65535));
|
||||
deepEquals(fillFallback(i161, -1), i162.fill(-1));
|
||||
const i321 = new Int32Array(5);
|
||||
const i322 = new Int32Array(5);
|
||||
deepEquals(fillFallback(i321, 2), i322.fill(2));
|
||||
deepEquals(fillFallback(i321, 65537), i322.fill(65537));
|
||||
deepEquals(fillFallback(i321, -1), i322.fill(-1));
|
||||
const f321 = new Float32Array(5);
|
||||
const f322 = new Float32Array(5);
|
||||
deepEquals(fillFallback(f321, 1.2345), f322.fill(1.2345));
|
||||
const f641 = new Float64Array(5);
|
||||
const f642 = new Float64Array(5);
|
||||
deepEquals(fillFallback(f641, 1.2345), f642.fill(1.2345));
|
||||
const u8Clamped1 = new Uint8ClampedArray(5);
|
||||
const u8Clamped2 = new Uint8ClampedArray(5);
|
||||
deepEquals(fillFallback(u8Clamped1, 2), u8Clamped2.fill(2));
|
||||
deepEquals(fillFallback(u8Clamped1, 257), u8Clamped2.fill(257));
|
||||
});
|
||||
it('start offset', function(): void {
|
||||
for (let i = -2; i < 10; ++i) {
|
||||
const u81 = new Uint8Array(5);
|
||||
const u83 = new Uint8Array(5);
|
||||
deepEquals(fillFallback(u81, 2, i), u83.fill(2, i));
|
||||
deepEquals(fillFallback(u81, -1, i), u83.fill(-1, i));
|
||||
}
|
||||
});
|
||||
it('end offset', function(): void {
|
||||
for (let i = -2; i < 10; ++i) {
|
||||
const u81 = new Uint8Array(5);
|
||||
const u83 = new Uint8Array(5);
|
||||
deepEquals(fillFallback(u81, 2, 0, i), u83.fill(2, 0, i));
|
||||
deepEquals(fillFallback(u81, -1, 0, i), u83.fill(-1, 0, i));
|
||||
}
|
||||
});
|
||||
it('start/end offset', function(): void {
|
||||
for (let i = -2; i < 10; ++i) {
|
||||
for (let j = -2; j < 10; ++j) {
|
||||
const u81 = new Uint8Array(5);
|
||||
const u83 = new Uint8Array(5);
|
||||
deepEquals(fillFallback(u81, 2, i, j), u83.fill(2, i, j));
|
||||
deepEquals(fillFallback(u81, -1, i, j), u83.fill(-1, i, j));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('typed array convenience functions', () => {
|
||||
it('concat', () => {
|
||||
const a = new Uint8Array([1, 2, 3, 4, 5]);
|
||||
|
||||
@@ -5,39 +5,6 @@
|
||||
|
||||
export type TypedArray = Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Int8Array | Int16Array | Int32Array | Float32Array | Float64Array;
|
||||
|
||||
|
||||
/**
|
||||
* polyfill for TypedArray.fill
|
||||
* This is needed to support .fill in all safari versions and IE 11.
|
||||
*/
|
||||
export function fill<T extends TypedArray>(array: T, value: number, start?: number, end?: number): T {
|
||||
// all modern engines that support .fill
|
||||
if (array.fill) {
|
||||
return array.fill(value, start, end) as T;
|
||||
}
|
||||
return fillFallback(array, value, start, end);
|
||||
}
|
||||
|
||||
export function fillFallback<T extends TypedArray>(array: T, value: number, start: number = 0, end: number = array.length): T {
|
||||
// safari and IE 11
|
||||
// since IE 11 does not support Array.prototype.fill either
|
||||
// we cannot use the suggested polyfill from MDN
|
||||
// instead we simply fall back to looping
|
||||
if (start >= array.length) {
|
||||
return array;
|
||||
}
|
||||
start = (array.length + start) % array.length;
|
||||
if (end >= array.length) {
|
||||
end = array.length;
|
||||
} else {
|
||||
end = (array.length + end) % array.length;
|
||||
}
|
||||
for (let i = start; i < end; ++i) {
|
||||
array[i] = value;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat two typed arrays `a` and `b`.
|
||||
* Returns a new typed array.
|
||||
|
||||
@@ -33,8 +33,7 @@ export class Buffer implements IBuffer {
|
||||
public x: number = 0;
|
||||
public scrollBottom: number;
|
||||
public scrollTop: number;
|
||||
// TODO: Type me
|
||||
public tabs: any;
|
||||
public tabs: { [column: number]: boolean | undefined } = {};
|
||||
public savedY: number = 0;
|
||||
public savedX: number = 0;
|
||||
public savedCurAttrData = DEFAULT_ATTR_DATA.clone();
|
||||
@@ -513,7 +512,7 @@ export class Buffer implements IBuffer {
|
||||
* TODO: respect trim flag after fixing #1685
|
||||
* @param lineIndex line index the string was retrieved from
|
||||
* @param stringIndex index within the string
|
||||
* @param startCol column offset the string was retrieved from
|
||||
* @param trimRight Whether to trim whitespace to the right.
|
||||
*/
|
||||
public stringIndexToBufferIndex(lineIndex: number, stringIndex: number, trimRight: boolean = false): BufferIndex {
|
||||
while (stringIndex) {
|
||||
@@ -542,7 +541,7 @@ export class Buffer implements IBuffer {
|
||||
* Wide characters will count as two columns in the resulting string. This
|
||||
* function is useful for getting the actual text underneath the raw selection
|
||||
* position.
|
||||
* @param line The line being translated.
|
||||
* @param lineIndex The absolute index of the line being translated.
|
||||
* @param trimRight Whether to trim whitespace to the right.
|
||||
* @param startCol The column to start at.
|
||||
* @param endCol The column to end at.
|
||||
|
||||
@@ -133,7 +133,7 @@ export class BufferLine implements IBufferLine {
|
||||
* Test whether contains any chars.
|
||||
* Basically an empty has no content, but other cells might differ in FG/BG
|
||||
* from real empty cells.
|
||||
* */
|
||||
*/
|
||||
public hasContent(index: number): number {
|
||||
return this._data[index * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT_MASK;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@ export interface INewLayoutResult {
|
||||
* Evaluates and returns indexes to be removed after a reflow larger occurs. Lines will be removed
|
||||
* when a wrapped line unwraps.
|
||||
* @param lines The buffer lines.
|
||||
* @param oldCols The columns before resize
|
||||
* @param newCols The columns after resize.
|
||||
* @param bufferAbsoluteY The absolute y position of the cursor (baseY + cursorY).
|
||||
* @param nullCell The cell data to use when filling in empty cells.
|
||||
*/
|
||||
export function reflowLargerGetLinesToRemove(lines: CircularList<IBufferLine>, oldCols: number, newCols: number, bufferAbsoluteY: number, nullCell: ICellData): number[] {
|
||||
// Gather all BufferLines that need to be removed from the Buffer here so that they can be
|
||||
|
||||
@@ -24,7 +24,6 @@ export class BufferSet extends Disposable implements IBufferSet {
|
||||
|
||||
/**
|
||||
* Create a new BufferSet for the given terminal.
|
||||
* @param _terminal - The terminal the BufferSet will belong to
|
||||
*/
|
||||
constructor(
|
||||
private readonly _optionsService: IOptionsService,
|
||||
|
||||
@@ -47,7 +47,7 @@ export class CellData extends AttributeData implements ICellData {
|
||||
* Note this returns the UTF32 codepoint of single chars,
|
||||
* if content is a combined string it returns the codepoint
|
||||
* of the last char in string to be in line with code in CharData.
|
||||
* */
|
||||
*/
|
||||
public getCode(): number {
|
||||
return (this.isCombined())
|
||||
? this.combinedData.charCodeAt(this.combinedData.length - 1)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
export const DEFAULT_COLOR = 256;
|
||||
export const DEFAULT_COLOR = 0;
|
||||
export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0);
|
||||
export const DEFAULT_EXT = 0;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
import { IUnicodeVersionProvider } from 'common/services/Services';
|
||||
import { fill } from 'common/TypedArrayUtils';
|
||||
|
||||
type CharWidth = 0 | 1 | 2;
|
||||
|
||||
@@ -90,26 +89,26 @@ export class UnicodeV6 implements IUnicodeVersionProvider {
|
||||
// init lookup table once
|
||||
if (!table) {
|
||||
table = new Uint8Array(65536);
|
||||
fill(table, 1);
|
||||
table.fill(1);
|
||||
table[0] = 0;
|
||||
// control chars
|
||||
fill(table, 0, 1, 32);
|
||||
fill(table, 0, 0x7f, 0xa0);
|
||||
table.fill(0, 1, 32);
|
||||
table.fill(0, 0x7f, 0xa0);
|
||||
|
||||
// apply wide char rules first
|
||||
// wide chars
|
||||
fill(table, 2, 0x1100, 0x1160);
|
||||
table.fill(2, 0x1100, 0x1160);
|
||||
table[0x2329] = 2;
|
||||
table[0x232a] = 2;
|
||||
fill(table, 2, 0x2e80, 0xa4d0);
|
||||
table.fill(2, 0x2e80, 0xa4d0);
|
||||
table[0x303f] = 1; // wrongly in last line
|
||||
|
||||
fill(table, 2, 0xac00, 0xd7a4);
|
||||
fill(table, 2, 0xf900, 0xfb00);
|
||||
fill(table, 2, 0xfe10, 0xfe1a);
|
||||
fill(table, 2, 0xfe30, 0xfe70);
|
||||
fill(table, 2, 0xff00, 0xff61);
|
||||
fill(table, 2, 0xffe0, 0xffe7);
|
||||
table.fill(2, 0xac00, 0xd7a4);
|
||||
table.fill(2, 0xf900, 0xfb00);
|
||||
table.fill(2, 0xfe10, 0xfe1a);
|
||||
table.fill(2, 0xfe30, 0xfe70);
|
||||
table.fill(2, 0xff00, 0xff61);
|
||||
table.fill(2, 0xffe0, 0xffe7);
|
||||
|
||||
// apply combining last to ensure we overwrite
|
||||
// wrongly wide set chars:
|
||||
@@ -117,7 +116,7 @@ export class UnicodeV6 implements IUnicodeVersionProvider {
|
||||
// through to wide check so we simply do here the opposite
|
||||
// combining 0
|
||||
for (let r = 0; r < BMP_COMBINING.length; ++r) {
|
||||
fill(table, 0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);
|
||||
table.fill(0, BMP_COMBINING[r][0], BMP_COMBINING[r][1] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ export const enum ParserState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal actions of EscapeSequenceParser.
|
||||
*/
|
||||
* Internal actions of EscapeSequenceParser.
|
||||
*/
|
||||
export const enum ParserAction {
|
||||
IGNORE = 0,
|
||||
ERROR = 1,
|
||||
|
||||
@@ -7,7 +7,6 @@ import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler
|
||||
import { ParserState, ParserAction } from 'common/parser/Constants';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IDisposable } from 'common/Types';
|
||||
import { fill } from 'common/TypedArrayUtils';
|
||||
import { Params } from 'common/parser/Params';
|
||||
import { OscParser } from 'common/parser/OscParser';
|
||||
import { DcsParser } from 'common/parser/DcsParser';
|
||||
@@ -39,7 +38,7 @@ export class TransitionTable {
|
||||
* @param next default next state
|
||||
*/
|
||||
public setDefault(action: ParserAction, next: ParserState): void {
|
||||
fill(this.table, action << TableAccess.TRANSITION_ACTION_SHIFT | next);
|
||||
this.table.fill(action << TableAccess.TRANSITION_ACTION_SHIFT | next);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+2
-2
@@ -142,8 +142,8 @@ export type PrintFallbackHandlerType = PrintHandlerType;
|
||||
|
||||
|
||||
/**
|
||||
* EscapeSequenceParser interface.
|
||||
*/
|
||||
* EscapeSequenceParser interface.
|
||||
*/
|
||||
export interface IEscapeSequenceParser extends IDisposable {
|
||||
/**
|
||||
* Preceding codepoint to get REP working correctly.
|
||||
|
||||
@@ -54,6 +54,7 @@ export class BufferService extends Disposable implements IBufferService {
|
||||
|
||||
/**
|
||||
* Scroll the terminal down 1 row, creating a blank line.
|
||||
* @param eraseAttr The attribute data to use the for blank line.
|
||||
* @param isWrapped Whether the new line is wrapped from the previous line.
|
||||
*/
|
||||
public scroll(eraseAttr: IAttributeData, isWrapped: boolean = false): void {
|
||||
|
||||
@@ -42,6 +42,7 @@ export class DecorationService extends Disposable implements IDecorationService
|
||||
this.reset();
|
||||
}));
|
||||
}
|
||||
|
||||
public registerDecoration(options: IDecorationOptions): IDecoration | undefined {
|
||||
if (options.marker.isDisposed) {
|
||||
return undefined;
|
||||
@@ -91,19 +92,25 @@ export class DecorationService extends Disposable implements IDecorationService
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
for (const d of this._decorations.values()) {
|
||||
this._onDecorationRemoved.fire(d);
|
||||
}
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
class Decoration extends Disposable implements IInternalDecoration {
|
||||
public readonly marker: IMarker;
|
||||
public element: HTMLElement | undefined;
|
||||
public isDisposed: boolean = false;
|
||||
|
||||
public readonly onRenderEmitter = this.register(new EventEmitter<HTMLElement>());
|
||||
public readonly onRender = this.onRenderEmitter.event;
|
||||
private readonly _onDispose = this.register(new EventEmitter<void>());
|
||||
public readonly onDispose = this._onDispose.event;
|
||||
|
||||
public get isDisposed(): boolean { return this._isDisposed; }
|
||||
|
||||
private _cachedBg: IColor | undefined | null = null;
|
||||
public get backgroundColorRGB(): IColor | undefined {
|
||||
if (this._cachedBg === null) {
|
||||
@@ -136,12 +143,10 @@ class Decoration extends Disposable implements IInternalDecoration {
|
||||
if (this.options.overviewRulerOptions && !this.options.overviewRulerOptions.position) {
|
||||
this.options.overviewRulerOptions.position = 'full';
|
||||
}
|
||||
}
|
||||
|
||||
this.register(toDisposable(() => {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._onDispose.fire();
|
||||
}));
|
||||
public override dispose(): void {
|
||||
this._onDispose.fire();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user