From c65dd1f476c0a273a85779457f7b93b74d10592c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 29 Jul 2018 13:05:27 -0700 Subject: [PATCH] Use const for null cell Fixes #1584 --- src/Buffer.ts | 6 +++++- src/InputHandler.ts | 14 +++++++------- src/Terminal.ts | 12 ++++++------ src/addons/winptyCompat/winptyCompat.ts | 5 ++++- src/renderer/TextRenderLayer.ts | 4 ++-- src/renderer/dom/DomRendererRowFactory.test.ts | 4 ++-- src/utils/TestUtils.test.ts | 4 ++-- 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index 5183009f..5d45645f 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -15,6 +15,10 @@ export const CHAR_DATA_WIDTH_INDEX = 2; export const CHAR_DATA_CODE_INDEX = 3; export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 +export const NULL_CELL_CHAR = ' '; +export const NULL_CELL_WIDTH = 1; +export const NULL_CELL_CODE = 32; + /** * This class represents a terminal buffer (an internal state of the terminal), where the * following information is stored (in high-level): @@ -117,7 +121,7 @@ export class Buffer implements IBuffer { if (this.lines.length > 0) { // Deal with columns increasing (we don't do anything when columns reduce) if (this._terminal.cols < newCols) { - const ch: CharData = [DEFAULT_ATTR, ' ', 1, 32]; // does xterm use the default attr? + const ch: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // does xterm use the default attr? for (let i = 0; i < this.lines.length; i++) { while (this.lines.get(i).length < newCols) { this.lines.get(i).push(ch); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 3fda521f..b97152be 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -7,7 +7,7 @@ import { CharData, IInputHandler, IDcsHandler, IEscapeSequenceParser, IBuffer } from './Types'; import { C0, C1 } from './common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets'; -import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, DEFAULT_ATTR } from './Buffer'; +import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Buffer'; import { FLAGS } from './renderer/Types'; import { wcwidth } from './CharWidth'; import { EscapeSequenceParser } from './EscapeSequenceParser'; @@ -431,11 +431,11 @@ export class InputHandler extends Disposable implements IInputHandler { if (removed[CHAR_DATA_WIDTH_INDEX] === 0 && bufferRow[this._terminal.cols - 2] && bufferRow[this._terminal.cols - 2][CHAR_DATA_WIDTH_INDEX] === 2) { - bufferRow[this._terminal.cols - 2] = [curAttr, ' ', 1, 32 /* ' '.charCodeAt(0) */ ]; + bufferRow[this._terminal.cols - 2] = [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; } // insert empty cell at cursor - bufferRow.splice(buffer.x, 0, [curAttr, ' ', 1, 32 /* ' '.charCodeAt(0) */ ]); + bufferRow.splice(buffer.x, 0, [curAttr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); } } @@ -547,7 +547,7 @@ export class InputHandler extends Disposable implements IInputHandler { const row = buffer.y + buffer.ybase; let j = buffer.x; - const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + const ch: CharData = [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm while (param-- && j < this._terminal.cols) { buffer.lines.get(row).splice(j++, 0, ch); @@ -857,7 +857,7 @@ export class InputHandler extends Disposable implements IInputHandler { const buffer = this._terminal.buffer; const row = buffer.y + buffer.ybase; - const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + const ch: CharData = [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm while (param--) { buffer.lines.get(row).splice(buffer.x, 1); @@ -919,7 +919,7 @@ export class InputHandler extends Disposable implements IInputHandler { const row = buffer.y + buffer.ybase; let j = buffer.x; - const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm + const ch: CharData = [this._terminal.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm while (param-- && j < this._terminal.cols) { buffer.lines.get(row)[j++] = ch; @@ -981,7 +981,7 @@ export class InputHandler extends Disposable implements IInputHandler { const buffer = this._terminal.buffer; const line = buffer.lines.get(buffer.ybase + buffer.y); - const ch = line[buffer.x - 1] || [DEFAULT_ATTR, ' ', 1, 32]; + const ch = line[buffer.x - 1] || [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; while (param--) { line[buffer.x++] = ch; diff --git a/src/Terminal.ts b/src/Terminal.ts index e8366290..8bd385f0 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -25,7 +25,7 @@ import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions import { IMouseZoneManager } from './ui/Types'; import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; -import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR } from './Buffer'; +import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from './Buffer'; import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './EventEmitter'; import { Viewport } from './Viewport'; @@ -1697,7 +1697,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II if (!line) { return; } - const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm + const ch: CharData = [this.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm for (; x < this.cols; x++) { line[x] = ch; } @@ -1714,7 +1714,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II if (!line) { return; } - const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm + const ch: CharData = [this.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // xterm x++; while (x--) { line[x] = ch; @@ -1760,7 +1760,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II public blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData { const attr = cur ? this.eraseAttr() : DEFAULT_ATTR; - const ch: CharData = [attr, ' ', 1, 32 /* ' '.charCodeAt(0) */]; // width defaults to 1 halfwidth character + const ch: CharData = [attr, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // width defaults to 1 halfwidth character const line: LineData = []; // TODO: It is not ideal that this is a property on an array, a buffer line @@ -1783,9 +1783,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II */ public ch(cur?: boolean): CharData { if (cur) { - return [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; + return [this.eraseAttr(), NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; } - return [DEFAULT_ATTR, ' ', 1, 32 /* ' '.charCodeAt(0) */]; + return [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; } /** diff --git a/src/addons/winptyCompat/winptyCompat.ts b/src/addons/winptyCompat/winptyCompat.ts index 84b21590..25ad7d91 100644 --- a/src/addons/winptyCompat/winptyCompat.ts +++ b/src/addons/winptyCompat/winptyCompat.ts @@ -6,6 +6,9 @@ import { Terminal } from 'xterm'; import { IWinptyCompatAddonTerminal } from './Interfaces'; +const CHAR_DATA_CODE_INDEX = 3; +const NULL_CELL_CODE = 32; + export function winptyCompatInit(terminal: Terminal): void { const addonTerminal = terminal; @@ -29,7 +32,7 @@ export function winptyCompatInit(terminal: Terminal): void { const line = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y - 1); const lastChar = line[addonTerminal.cols - 1]; - if (lastChar[3] !== 32 /* ' ' */) { + if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE) { const nextLine = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y); (nextLine).isWrapped = true; } diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index e57276d7..d40aa28d 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../Buffer'; +import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, NULL_CELL_CODE } from '../Buffer'; import { FLAGS, IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types'; import { CharData, ITerminal } from '../Types'; import { INVERTED_DEFAULT_COLOR } from './atlas/Types'; @@ -124,7 +124,7 @@ export class TextRenderLayer extends BaseRenderLayer { // get removed, and `a` would not re-render because it thinks it's // already in the correct state. // this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA; - if (lastCharX < line.length - 1 && line[lastCharX + 1][CHAR_DATA_CODE_INDEX] === 32 /*' '*/) { + if (lastCharX < line.length - 1 && line[lastCharX + 1][CHAR_DATA_CODE_INDEX] === NULL_CELL_CODE) { width = 2; // this._clearChar(x + 1, y); // The overlapping char's char data will force a clear and render when the diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index e91c71fe..c90dd6e5 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -7,7 +7,7 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { DomRendererRowFactory } from './DomRendererRowFactory'; import { LineData } from '../../Types'; -import { DEFAULT_ATTR } from '../../Buffer'; +import { DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '../../Buffer'; import { FLAGS } from '../Types'; describe('DomRendererRowFactory', () => { @@ -149,7 +149,7 @@ describe('DomRendererRowFactory', () => { function createEmptyLineData(cols: number): LineData { const lineData: LineData = []; for (let i = 0; i < cols; i++) { - lineData.push([DEFAULT_ATTR, ' ', 1, 32 /* ' '.charCodeAt(0) */]); + lineData.push([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); } return lineData; } diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index 78a1942b..e2e8e393 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -5,7 +5,7 @@ import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types'; import { LineData, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener, CharacterJoinerHandler } from '../Types'; -import { Buffer } from '../Buffer'; +import { Buffer, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '../Buffer'; import * as Browser from '../shared/utils/Browser'; import { ITheme, IDisposable, IMarker } from 'xterm'; @@ -152,7 +152,7 @@ export class MockTerminal implements ITerminal { const line: LineData = []; cols = cols || this.cols; for (let i = 0; i < cols; i++) { - line.push([0, ' ', 1, 32]); + line.push([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); } return line; }