diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 3e5cef57..e42216af 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -8,7 +8,8 @@ import { InputHandler } from './InputHandler'; import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test'; import { Terminal } from './Terminal'; import { IBufferLine } from 'common/Types'; -import { CellData, Attributes, AttributeData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { Attributes, AttributeData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; describe('InputHandler', () => { describe('save and restore cursor', () => { diff --git a/src/InputHandler.ts b/src/InputHandler.ts index a8085f43..1c6b1cce 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -13,10 +13,11 @@ import { IDisposable } from 'xterm'; import { Disposable } from 'common/Lifecycle'; import { concat } from 'common/TypedArrayUtils'; import { StringToUtf32, stringFromCodePoint, utf32ToString, Utf8ToUtf32 } from 'common/input/TextDecoder'; -import { CellData, Attributes, FgFlags, BgFlags, AttributeData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { Attributes, FgFlags, BgFlags, AttributeData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { EventEmitter, IEvent } from 'common/EventEmitter'; import { IParsingState, IDcsHandler, IEscapeSequenceParser } from 'common/parser/Types'; -import { NULL_CELL_CODE, NULL_CELL_WIDTH } from '../out/common/buffer/Constants'; +import { NULL_CELL_CODE, NULL_CELL_WIDTH } from 'common/buffer/Constants'; +import { CellData } from 'common/buffer/CellData'; /** * Map collect to glevel. Used in `selectCharset`. diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 8b7e71a0..1ccae7fc 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -9,7 +9,8 @@ import { IBufferLine } from 'common/Types'; import { Linkifier } from './Linkifier'; import { MockBuffer, MockTerminal, TestTerminal } from './TestUtils.test'; import { CircularList } from 'common/CircularList'; -import { BufferLine, CellData } from 'common/buffer/BufferLine'; +import { BufferLine } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; class TestLinkifier extends Linkifier { constructor(terminal: ITerminal) { diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 5dc692af..f58815f0 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -12,9 +12,10 @@ import { IBuffer } from 'common/buffer/Types'; import { IBufferLine } from 'common/Types'; import { MockTerminal } from './TestUtils.test'; import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; -import { BufferLine, CellData } from 'common/buffer/BufferLine'; +import { BufferLine } from 'common/buffer/BufferLine'; import { IBufferService } from 'common/services/Services'; import { MockCharSizeService } from 'browser/TestUtils.test'; +import { CellData } from 'common/buffer/CellData'; class TestMockTerminal extends MockTerminal { emit(event: string, data: any): void {} diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 4b6a0de0..05beaeab 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -10,7 +10,7 @@ import { MouseHelper } from 'browser/input/MouseHelper'; import * as Browser from 'common/Platform'; import { SelectionModel } from './SelectionModel'; import { AltClickHandler } from './handlers/AltClickHandler'; -import { CellData } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; import { IDisposable } from 'xterm'; import { EventEmitter, IEvent } from 'common/EventEmitter'; import { ICharSizeService } from 'browser/services/Services'; diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 36886da1..f3f7fc58 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -6,7 +6,8 @@ import { assert, expect } from 'chai'; import { Terminal } from './Terminal'; import { MockViewport, MockCompositionHelper, MockRenderer } from './TestUtils.test'; -import { CellData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/Terminal2.test.ts b/src/Terminal2.test.ts index 076c37f5..c8164c54 100644 --- a/src/Terminal2.test.ts +++ b/src/Terminal2.test.ts @@ -12,7 +12,7 @@ import * as path from 'path'; import * as pty from 'node-pty'; import { Terminal } from './Terminal'; import { IViewport } from './Types'; -import { CellData } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; import { WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; class TestTerminal extends Terminal { diff --git a/src/common/buffer/Buffer.test.ts b/src/common/buffer/Buffer.test.ts index 01516b3c..af5abeca 100644 --- a/src/common/buffer/Buffer.test.ts +++ b/src/common/buffer/Buffer.test.ts @@ -7,7 +7,8 @@ import { assert } from 'chai'; import { Buffer } from 'common/buffer/Buffer'; import { CircularList } from 'common/CircularList'; import { MockOptionsService, MockBufferService } from 'common/TestUtils.test'; -import { BufferLine, CellData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts index b247cce3..b06545da 100644 --- a/src/common/buffer/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -6,7 +6,8 @@ import { CircularList, IInsertEvent } from 'common/CircularList'; import { IBuffer, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult } from 'common/buffer/Types'; import { IBufferLine, ICellData, IAttributeData } from 'common/Types'; -import { BufferLine, CellData, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { BufferLine, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_WIDTH, WHITESPACE_CELL_CODE, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from 'common/buffer/Constants'; import { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from 'common/buffer/BufferReflow'; import { Marker } from 'common/buffer/Marker'; diff --git a/src/common/buffer/BufferLine.test.ts b/src/common/buffer/BufferLine.test.ts index 14a21650..4ee604b5 100644 --- a/src/common/buffer/BufferLine.test.ts +++ b/src/common/buffer/BufferLine.test.ts @@ -4,7 +4,8 @@ */ import * as chai from 'chai'; import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from 'common/buffer/Constants'; -import { BufferLine, CellData, Content } from 'common/buffer//BufferLine'; +import { BufferLine, Content } from 'common/buffer//BufferLine'; +import { CellData } from 'common/buffer/CellData'; import { CharData, IBufferLine } from '../Types'; class TestBufferLine extends BufferLine { diff --git a/src/common/buffer/BufferLine.ts b/src/common/buffer/BufferLine.ts index b591a7e1..b171649c 100644 --- a/src/common/buffer/BufferLine.ts +++ b/src/common/buffer/BufferLine.ts @@ -6,6 +6,7 @@ import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from 'common/Types'; import { stringFromCodePoint } from 'common/input/TextDecoder'; import { DEFAULT_COLOR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; +import { CellData } from './CellData'; /** * buffer memory layout: @@ -195,96 +196,6 @@ export class AttributeData implements IAttributeData { export const DEFAULT_ATTR_DATA = Object.freeze(new AttributeData()); -/** - * CellData - represents a single Cell in the terminal buffer. - */ -export class CellData extends AttributeData implements ICellData { - - /** Helper to create CellData from CharData. */ - public static fromCharData(value: CharData): CellData { - const obj = new CellData(); - obj.setFromCharData(value); - return obj; - } - - /** Primitives from terminal buffer. */ - public content: number = 0; - public fg: number = 0; - public bg: number = 0; - public combinedData: string = ''; - - /** Whether cell contains a combined string. */ - public isCombined(): number { - return this.content & Content.IS_COMBINED_MASK; - } - - /** Width of the cell. */ - public getWidth(): number { - return this.content >> Content.WIDTH_SHIFT; - } - - /** JS string of the content. */ - public getChars(): string { - if (this.content & Content.IS_COMBINED_MASK) { - return this.combinedData; - } - if (this.content & Content.CODEPOINT_MASK) { - return stringFromCodePoint(this.content & Content.CODEPOINT_MASK); - } - return ''; - } - - /** - * Codepoint of cell - * 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) - : this.content & Content.CODEPOINT_MASK; - } - - /** Set data from CharData */ - public setFromCharData(value: CharData): void { - this.fg = value[CHAR_DATA_ATTR_INDEX]; - this.bg = 0; - let combined = false; - - // surrogates and combined strings need special treatment - if (value[CHAR_DATA_CHAR_INDEX].length > 2) { - combined = true; - } else if (value[CHAR_DATA_CHAR_INDEX].length === 2) { - const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0); - // if the 2-char string is a surrogate create single codepoint - // everything else is combined - if (0xD800 <= code && code <= 0xDBFF) { - const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1); - if (0xDC00 <= second && second <= 0xDFFF) { - this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); - } else { - combined = true; - } - } else { - combined = true; - } - } else { - this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); - } - if (combined) { - this.combinedData = value[CHAR_DATA_CHAR_INDEX]; - this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); - } - } - - /** Get data as CharData. */ - public getAsCharData(): CharData { - return [this.fg, this.getChars(), this.getWidth(), this.getCode()]; - } -} - - /** * Typed array based bufferline implementation. * diff --git a/src/common/buffer/CellData.ts b/src/common/buffer/CellData.ts new file mode 100644 index 00000000..11fa607b --- /dev/null +++ b/src/common/buffer/CellData.ts @@ -0,0 +1,87 @@ +import { CharData, ICellData } from 'common/Types'; +import { stringFromCodePoint } from 'common/input/TextDecoder'; +import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX } from 'common/buffer/Constants'; +import { AttributeData, Content } from './BufferLine'; +/** + * CellData - represents a single Cell in the terminal buffer. + */ +export class CellData extends AttributeData implements ICellData { + /** Helper to create CellData from CharData. */ + public static fromCharData(value: CharData): CellData { + const obj = new CellData(); + obj.setFromCharData(value); + return obj; + } + /** Primitives from terminal buffer. */ + public content: number = 0; + public fg: number = 0; + public bg: number = 0; + public combinedData: string = ''; + /** Whether cell contains a combined string. */ + public isCombined(): number { + return this.content & Content.IS_COMBINED_MASK; + } + /** Width of the cell. */ + public getWidth(): number { + return this.content >> Content.WIDTH_SHIFT; + } + /** JS string of the content. */ + public getChars(): string { + if (this.content & Content.IS_COMBINED_MASK) { + return this.combinedData; + } + if (this.content & Content.CODEPOINT_MASK) { + return stringFromCodePoint(this.content & Content.CODEPOINT_MASK); + } + return ''; + } + /** + * Codepoint of cell + * 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) + : this.content & Content.CODEPOINT_MASK; + } + /** Set data from CharData */ + public setFromCharData(value: CharData): void { + this.fg = value[CHAR_DATA_ATTR_INDEX]; + this.bg = 0; + let combined = false; + // surrogates and combined strings need special treatment + if (value[CHAR_DATA_CHAR_INDEX].length > 2) { + combined = true; + } + else if (value[CHAR_DATA_CHAR_INDEX].length === 2) { + const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0); + // if the 2-char string is a surrogate create single codepoint + // everything else is combined + if (0xD800 <= code && code <= 0xDBFF) { + const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1); + if (0xDC00 <= second && second <= 0xDFFF) { + this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); + } + else { + combined = true; + } + } + else { + combined = true; + } + } + else { + this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); + } + if (combined) { + this.combinedData = value[CHAR_DATA_CHAR_INDEX]; + this.content = Content.IS_COMBINED_MASK | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT); + } + } + /** Get data as CharData. */ + public getAsCharData(): CharData { + return [this.fg, this.getChars(), this.getWidth(), this.getCode()]; + } +} diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 8315f4c7..021c4fba 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -12,8 +12,9 @@ import { IGlyphIdentifier } from './atlas/Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from './atlas/Constants'; import { BaseCharAtlas } from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; -import { CellData, AttributeData } from 'common/buffer/BufferLine'; +import { AttributeData } from 'common/buffer/BufferLine'; import { IColorSet } from 'browser/Types'; +import { CellData } from 'common/buffer/CellData'; export abstract class BaseRenderLayer implements IRenderLayer { private _canvas: HTMLCanvasElement; diff --git a/src/renderer/CharacterJoinerRegistry.test.ts b/src/renderer/CharacterJoinerRegistry.test.ts index e5ab08ea..a73672a2 100644 --- a/src/renderer/CharacterJoinerRegistry.test.ts +++ b/src/renderer/CharacterJoinerRegistry.test.ts @@ -10,8 +10,9 @@ import { CircularList } from 'common/CircularList'; import { ICharacterJoinerRegistry } from './Types'; import { CharacterJoinerRegistry } from './CharacterJoinerRegistry'; -import { BufferLine, CellData } from 'common/buffer/BufferLine'; +import { BufferLine } from 'common/buffer/BufferLine'; import { IBufferLine } from 'common/Types'; +import { CellData } from 'common/buffer/CellData'; describe('CharacterJoinerRegistry', () => { let registry: ICharacterJoinerRegistry; diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index d06d824b..b82d419b 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -6,8 +6,9 @@ import { ITerminal } from '../Types'; import { IBufferLine, ICellData, CharData } from 'common/Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData, Content, AttributeData } from 'common/buffer/BufferLine'; +import { Content, AttributeData } from 'common/buffer/BufferLine'; import { WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; +import { CellData } from 'common/buffer/CellData'; export class JoinedCellData extends AttributeData implements ICellData { private _width: number; diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 9626f772..b2d856d1 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -7,7 +7,7 @@ import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { ITerminal } from '../Types'; import { ICellData } from 'common/Types'; -import { CellData } from 'common/buffer/BufferLine'; +import { CellData } from 'common/buffer/CellData'; import { IColorSet } from 'browser/Types'; interface ICursorState { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index f55de915..0d462a2c 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -9,10 +9,11 @@ import { ITerminal } from '../Types'; import { CharData, ICellData } from 'common/Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { CellData, AttributeData, Content } from 'common/buffer/BufferLine'; +import { AttributeData, Content } from 'common/buffer/BufferLine'; import { NULL_CELL_CODE } from 'common/buffer/Constants'; import { JoinedCellData } from './CharacterJoinerRegistry'; import { IColorSet } from 'browser/Types'; +import { CellData } from 'common/buffer/CellData'; /** * This CharData looks like a null character, which will forc a clear and render diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index a69adba9..ad4b96cd 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -7,9 +7,10 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { DomRendererRowFactory } from './DomRendererRowFactory'; import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR } from 'common/buffer/Constants'; -import { BufferLine, CellData, FgFlags, BgFlags, Attributes, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; +import { BufferLine, FgFlags, BgFlags, Attributes, DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { ITerminalOptions } from '../../Types'; import { IBufferLine } from 'common/Types'; +import { CellData } from 'common/buffer/CellData'; describe('DomRendererRowFactory', () => { let dom: jsdom.JSDOM; diff --git a/src/renderer/dom/DomRendererRowFactory.ts b/src/renderer/dom/DomRendererRowFactory.ts index bb2d86f1..4dc67ed4 100644 --- a/src/renderer/dom/DomRendererRowFactory.ts +++ b/src/renderer/dom/DomRendererRowFactory.ts @@ -6,8 +6,9 @@ import { ITerminalOptions } from '../../Types'; import { IBufferLine } from 'common/Types'; import { INVERTED_DEFAULT_COLOR } from '../atlas/Constants'; -import { CellData, AttributeData } from 'common/buffer/BufferLine'; +import { AttributeData } from 'common/buffer/BufferLine'; import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from 'common/buffer/Constants'; +import { CellData } from 'common/buffer/CellData'; export const BOLD_CLASS = 'xterm-bold'; export const DIM_CLASS = 'xterm-dim';