From 672db9437f650c7882dca2fa3eecc2babbf5faa5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 01:55:56 +0000 Subject: [PATCH 01/37] Create ui project, add Lifecycle --- src/tsconfig.json | 3 ++- src/ui/Lifecycle.ts | 4 +--- src/ui/tsconfig.json | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 src/ui/tsconfig.json diff --git a/src/tsconfig.json b/src/tsconfig.json index f0b1c7490..1e8230a2d 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -24,6 +24,7 @@ ], "references": [ { "path": "./common" }, - { "path": "./core" } + { "path": "./core" }, + { "path": "./ui" } ] } diff --git a/src/ui/Lifecycle.ts b/src/ui/Lifecycle.ts index 9f058106a..4d36a1f12 100644 --- a/src/ui/Lifecycle.ts +++ b/src/ui/Lifecycle.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { IDisposable } from 'xterm'; +import { IDisposable } from '../common/Types'; /** * Adds a disposable listener to a node in the DOM, returning the disposable. @@ -24,8 +24,6 @@ export function addDisposableDomListener( return; } node.removeEventListener(type, handler, useCapture); - node = null; - handler = null; } }; } diff --git a/src/ui/tsconfig.json b/src/ui/tsconfig.json new file mode 100644 index 000000000..2763c6b15 --- /dev/null +++ b/src/ui/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../tsconfig-library-base", + "compilerOptions": { + "lib": [ + "dom", + "es5", + ], + "outDir": "../../lib", + "types": [ + "../../node_modules/@types/mocha" + ] + }, + "include": [ + "./Lifecycle.ts" + ], + "references": [ + { "path": "../common" } + ] +} \ No newline at end of file From 4c3082c924ac2bd950edd2a16300d1d28469f5c6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 01:59:40 +0000 Subject: [PATCH 02/37] Remove ITerminal dependency in RenderDebouncer --- src/AccessibilityManager.ts | 4 ++-- src/renderer/Renderer.ts | 4 ++-- src/renderer/dom/DomRenderer.ts | 4 ++-- src/ui/RenderDebouncer.ts | 15 ++++++++++----- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/AccessibilityManager.ts b/src/AccessibilityManager.ts index e2115797f..1f44c1321 100644 --- a/src/AccessibilityManager.ts +++ b/src/AccessibilityManager.ts @@ -61,7 +61,7 @@ export class AccessibilityManager extends Disposable { this._refreshRowsDimensions(); this._accessibilityTreeRoot.appendChild(this._rowContainer); - this._renderRowsDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this)); + this._renderRowsDebouncer = new RenderDebouncer(this._renderRows.bind(this)); this._refreshRows(); this._liveRegion = document.createElement('div'); @@ -239,7 +239,7 @@ export class AccessibilityManager extends Disposable { } private _refreshRows(start?: number, end?: number): void { - this._renderRowsDebouncer.refresh(start, end); + this._renderRowsDebouncer.refresh(start, end, this._terminal.rows); } private _renderRows(start: number, end: number): void { diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 2a205be36..14ce72b35 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -68,7 +68,7 @@ export class Renderer extends Disposable implements IRenderer { this._updateDimensions(); this.onOptionsChanged(); - this._renderDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this)); + this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this)); this._screenDprMonitor = new ScreenDprMonitor(); this._screenDprMonitor.setListener(() => this.onWindowResize(window.devicePixelRatio)); this.register(this._screenDprMonitor); @@ -194,7 +194,7 @@ export class Renderer extends Disposable implements IRenderer { this._needsFullRefresh = true; return; } - this._renderDebouncer.refresh(start, end); + this._renderDebouncer.refresh(start, end, this._terminal.rows); } /** diff --git a/src/renderer/dom/DomRenderer.ts b/src/renderer/dom/DomRenderer.ts index 1d879fcd1..ea3ac5d98 100644 --- a/src/renderer/dom/DomRenderer.ts +++ b/src/renderer/dom/DomRenderer.ts @@ -80,7 +80,7 @@ export class DomRenderer extends Disposable implements IRenderer { }; this._updateDimensions(); - this._renderDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this)); + this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this)); this._rowFactory = new DomRendererRowFactory(_terminal.options, document); this._terminal.element.classList.add(TERMINAL_CLASS_PREFIX + this._terminalClass); @@ -340,7 +340,7 @@ export class DomRenderer extends Disposable implements IRenderer { } public refreshRows(start: number, end: number): void { - this._renderDebouncer.refresh(start, end); + this._renderDebouncer.refresh(start, end, this._terminal.rows); } private _renderRows(start: number, end: number): void { diff --git a/src/ui/RenderDebouncer.ts b/src/ui/RenderDebouncer.ts index 775b7f748..260de12e9 100644 --- a/src/ui/RenderDebouncer.ts +++ b/src/ui/RenderDebouncer.ts @@ -1,4 +1,8 @@ -import { ITerminal } from '../Types'; +/** + * Copyright (c) 2018 The xterm.js authors. All rights reserved. + * @license MIT + */ + import { IDisposable } from 'xterm'; /** @@ -7,10 +11,10 @@ import { IDisposable } from 'xterm'; export class RenderDebouncer implements IDisposable { private _rowStart: number; private _rowEnd: number; + private _rowCount: number; private _animationFrame: number = null; constructor( - private _terminal: ITerminal, private _callback: (start: number, end: number) => void ) { } @@ -22,10 +26,11 @@ export class RenderDebouncer implements IDisposable { } } - public refresh(rowStart: number, rowEnd: number): void { + public refresh(rowStart: number, rowEnd: number, rowCount: number): void { + this._rowCount = rowCount; // Get the min/max row start/end for the arg values rowStart = rowStart !== null && rowStart !== undefined ? rowStart : 0; - rowEnd = rowEnd !== null && rowEnd !== undefined ? rowEnd : this._terminal.rows - 1; + rowEnd = rowEnd !== null && rowEnd !== undefined ? rowEnd : this._rowCount - 1; // Check whether the row start/end values have already been set const isRowStartSet = this._rowStart !== undefined && this._rowStart !== null; const isRowEndSet = this._rowEnd !== undefined && this._rowEnd !== null; @@ -43,7 +48,7 @@ export class RenderDebouncer implements IDisposable { private _innerRefresh(): void { // Clamp values this._rowStart = Math.max(this._rowStart, 0); - this._rowEnd = Math.min(this._rowEnd, this._terminal.rows - 1); + this._rowEnd = Math.min(this._rowEnd, this._rowCount - 1); // Run render callback this._callback(this._rowStart, this._rowEnd); From ebfa57b71cfc3f14f84144a5db6417043e655d3c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 02:03:41 +0000 Subject: [PATCH 03/37] Strict null check RenderDebouncer --- src/ui/RenderDebouncer.ts | 38 ++++++++++++++++++++------------------ src/ui/tsconfig.json | 3 ++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/ui/RenderDebouncer.ts b/src/ui/RenderDebouncer.ts index 260de12e9..ee2ab16e7 100644 --- a/src/ui/RenderDebouncer.ts +++ b/src/ui/RenderDebouncer.ts @@ -3,40 +3,37 @@ * @license MIT */ -import { IDisposable } from 'xterm'; +import { IDisposable } from '../common/Types'; /** * Debounces calls to render terminal rows using animation frames. */ export class RenderDebouncer implements IDisposable { - private _rowStart: number; - private _rowEnd: number; - private _rowCount: number; - private _animationFrame: number = null; + private _rowStart: number | undefined; + private _rowEnd: number | undefined; + private _rowCount: number | undefined; + private _animationFrame: number | undefined; constructor( - private _callback: (start: number, end: number) => void + private _renderCallback: (start: number, end: number) => void ) { } public dispose(): void { if (this._animationFrame) { window.cancelAnimationFrame(this._animationFrame); - this._animationFrame = null; + this._animationFrame = undefined; } } public refresh(rowStart: number, rowEnd: number, rowCount: number): void { this._rowCount = rowCount; // Get the min/max row start/end for the arg values - rowStart = rowStart !== null && rowStart !== undefined ? rowStart : 0; - rowEnd = rowEnd !== null && rowEnd !== undefined ? rowEnd : this._rowCount - 1; - // Check whether the row start/end values have already been set - const isRowStartSet = this._rowStart !== undefined && this._rowStart !== null; - const isRowEndSet = this._rowEnd !== undefined && this._rowEnd !== null; + rowStart = rowStart !== undefined ? rowStart : 0; + rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1; // Set the properties to the updated values - this._rowStart = isRowStartSet ? Math.min(this._rowStart, rowStart) : rowStart; - this._rowEnd = isRowEndSet ? Math.max(this._rowEnd, rowEnd) : rowEnd; + this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart; + this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd; if (this._animationFrame) { return; @@ -46,16 +43,21 @@ export class RenderDebouncer implements IDisposable { } private _innerRefresh(): void { + // Make sure values are set + if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) { + return; + } + // Clamp values this._rowStart = Math.max(this._rowStart, 0); this._rowEnd = Math.min(this._rowEnd, this._rowCount - 1); // Run render callback - this._callback(this._rowStart, this._rowEnd); + this._renderCallback(this._rowStart, this._rowEnd); // Reset debouncer - this._rowStart = null; - this._rowEnd = null; - this._animationFrame = null; + this._rowStart = undefined; + this._rowEnd = undefined; + this._animationFrame = undefined; } } diff --git a/src/ui/tsconfig.json b/src/ui/tsconfig.json index 2763c6b15..672d464e9 100644 --- a/src/ui/tsconfig.json +++ b/src/ui/tsconfig.json @@ -11,7 +11,8 @@ ] }, "include": [ - "./Lifecycle.ts" + "./Lifecycle.ts", + "./RenderDebouncer.ts" ], "references": [ { "path": "../common" } From 88d5cf46f873deca4b3d47c10a538e01f5423089 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 02:16:28 +0000 Subject: [PATCH 04/37] Strict null check ScreenDprMonitor --- src/ui/ScreenDprMonitor.ts | 27 +++++++++++++++++---------- src/ui/tsconfig.json | 3 ++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/ui/ScreenDprMonitor.ts b/src/ui/ScreenDprMonitor.ts index d66eeb64f..37c6a0dab 100644 --- a/src/ui/ScreenDprMonitor.ts +++ b/src/ui/ScreenDprMonitor.ts @@ -18,10 +18,10 @@ export type ScreenDprListener = (newDevicePixelRatio?: number, oldDevicePixelRat * monitor with a different DPI. */ export class ScreenDprMonitor extends Disposable { - private _currentDevicePixelRatio: number; - private _outerListener: (this: MediaQueryList, ev: MediaQueryListEvent) => any; - private _listener: ScreenDprListener; - private _resolutionMediaMatchList: MediaQueryList; + private _currentDevicePixelRatio: number = window.devicePixelRatio; + private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined; + private _listener: ScreenDprListener | undefined; + private _resolutionMediaMatchList: MediaQueryList | undefined; public setListener(listener: ScreenDprListener): void { if (this._listener) { @@ -29,6 +29,9 @@ export class ScreenDprMonitor extends Disposable { } this._listener = listener; this._outerListener = () => { + if (!this._listener) { + return; + } this._listener(window.devicePixelRatio, this._currentDevicePixelRatio); this._updateDpr(); }; @@ -41,10 +44,13 @@ export class ScreenDprMonitor extends Disposable { } private _updateDpr(): void { - // Clear listeners for old DPR - if (this._resolutionMediaMatchList) { - this._resolutionMediaMatchList.removeListener(this._outerListener); + if (!this._resolutionMediaMatchList || !this._outerListener) { + return; } + + // Clear listeners for old DPR + this._resolutionMediaMatchList.removeListener(this._outerListener); + // Add listeners for new DPR this._currentDevicePixelRatio = window.devicePixelRatio; this._resolutionMediaMatchList = window.matchMedia(`screen and (resolution: ${window.devicePixelRatio}dppx)`); @@ -52,11 +58,12 @@ export class ScreenDprMonitor extends Disposable { } public clearListener(): void { - if (!this._listener) { + if (!this._resolutionMediaMatchList || !this._listener || !this._outerListener) { return; } this._resolutionMediaMatchList.removeListener(this._outerListener); - this._listener = null; - this._outerListener = null; + this._resolutionMediaMatchList = undefined; + this._listener = undefined; + this._outerListener = undefined; } } diff --git a/src/ui/tsconfig.json b/src/ui/tsconfig.json index 672d464e9..b3613eeff 100644 --- a/src/ui/tsconfig.json +++ b/src/ui/tsconfig.json @@ -12,7 +12,8 @@ }, "include": [ "./Lifecycle.ts", - "./RenderDebouncer.ts" + "./RenderDebouncer.ts", + "./ScreenDprMonitor.ts" ], "references": [ { "path": "../common" } From 362152004b39fc6572927b4eaed083a9d696e239 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 02:27:41 +0000 Subject: [PATCH 05/37] Move files not in ui project back to root --- src/Buffer.test.ts | 2 +- src/BufferSet.test.ts | 2 +- src/{ui => }/CharMeasure.test.ts | 2 +- src/{ui => }/CharMeasure.ts | 4 ++-- src/CharWidth.test.ts | 2 +- src/{ui => }/Clipboard.test.ts | 0 src/{ui => }/Clipboard.ts | 2 +- src/InputHandler.test.ts | 2 +- src/Linkifier.test.ts | 5 ++--- src/Linkifier.ts | 4 ++-- src/{ui => }/MouseHelper.test.ts | 0 src/{ui => }/MouseHelper.ts | 4 ++-- src/{ui => }/MouseZoneManager.ts | 7 +++--- src/SelectionManager.test.ts | 4 ++-- src/SelectionManager.ts | 4 ++-- src/SelectionModel.test.ts | 2 +- src/Terminal.test.ts | 2 +- src/Terminal.ts | 11 +++++----- src/{ui => }/TestUtils.test.ts | 14 ++++++------ src/Types.ts | 18 ++++++++++++++- src/Viewport.ts | 2 +- src/renderer/CharacterJoinerRegistry.test.ts | 2 +- src/ui/Types.ts | 23 -------------------- 23 files changed, 54 insertions(+), 64 deletions(-) rename src/{ui => }/CharMeasure.test.ts (97%) rename src/{ui => }/CharMeasure.ts (93%) rename src/{ui => }/Clipboard.test.ts (100%) rename src/{ui => }/Clipboard.ts (98%) rename src/{ui => }/MouseHelper.test.ts (100%) rename src/{ui => }/MouseHelper.ts (96%) rename src/{ui => }/MouseZoneManager.ts (97%) rename src/{ui => }/TestUtils.test.ts (97%) delete mode 100644 src/ui/Types.ts diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index d5a27bf1a..d866fd569 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -7,7 +7,7 @@ import { assert, expect } from 'chai'; import { ITerminal } from './Types'; import { Buffer, DEFAULT_ATTR_DATA } from './Buffer'; import { CircularList } from './common/CircularList'; -import { MockTerminal, TestTerminal } from './ui/TestUtils.test'; +import { MockTerminal, TestTerminal } from './TestUtils.test'; import { BufferLine, CellData } from './BufferLine'; const INIT_COLS = 80; diff --git a/src/BufferSet.test.ts b/src/BufferSet.test.ts index 576a8ca47..cdc220b3f 100644 --- a/src/BufferSet.test.ts +++ b/src/BufferSet.test.ts @@ -7,7 +7,7 @@ import { assert } from 'chai'; import { ITerminal } from './Types'; import { BufferSet } from './BufferSet'; import { Buffer } from './Buffer'; -import { MockTerminal } from './ui/TestUtils.test'; +import { MockTerminal } from './TestUtils.test'; describe('BufferSet', () => { let terminal: ITerminal; diff --git a/src/ui/CharMeasure.test.ts b/src/CharMeasure.test.ts similarity index 97% rename from src/ui/CharMeasure.test.ts rename to src/CharMeasure.test.ts index a3cb3b3b4..5fd17eb24 100644 --- a/src/ui/CharMeasure.test.ts +++ b/src/CharMeasure.test.ts @@ -4,7 +4,7 @@ */ import jsdom = require('jsdom'); -import { ICharMeasure } from '../Types'; +import { ICharMeasure } from './Types'; import { assert } from 'chai'; import { CharMeasure } from './CharMeasure'; diff --git a/src/ui/CharMeasure.ts b/src/CharMeasure.ts similarity index 93% rename from src/ui/CharMeasure.ts rename to src/CharMeasure.ts index c37df312a..efee89729 100644 --- a/src/ui/CharMeasure.ts +++ b/src/CharMeasure.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { ICharMeasure, ITerminalOptions } from '../Types'; -import { EventEmitter2, IEvent } from '../common/EventEmitter2'; +import { ICharMeasure, ITerminalOptions } from './Types'; +import { EventEmitter2, IEvent } from './common/EventEmitter2'; /** * Utility class that measures the size of a character. Measurements are done in diff --git a/src/CharWidth.test.ts b/src/CharWidth.test.ts index 8608c6fa3..ff6f17ede 100644 --- a/src/CharWidth.test.ts +++ b/src/CharWidth.test.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { TestTerminal } from './ui/TestUtils.test'; +import { TestTerminal } from './TestUtils.test'; import { assert } from 'chai'; import { getStringCellWidth, wcwidth } from './CharWidth'; import { IBuffer } from './Types'; diff --git a/src/ui/Clipboard.test.ts b/src/Clipboard.test.ts similarity index 100% rename from src/ui/Clipboard.test.ts rename to src/Clipboard.test.ts diff --git a/src/ui/Clipboard.ts b/src/Clipboard.ts similarity index 98% rename from src/ui/Clipboard.ts rename to src/Clipboard.ts index 2570a8b17..7a32badcd 100644 --- a/src/ui/Clipboard.ts +++ b/src/Clipboard.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal, ISelectionManager } from '../Types'; +import { ITerminal, ISelectionManager } from './Types'; interface IWindow extends Window { clipboardData?: { diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 01596f808..dcd4d1b46 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -5,7 +5,7 @@ import { assert, expect } from 'chai'; import { InputHandler } from './InputHandler'; -import { MockInputHandlingTerminal, TestTerminal } from './ui/TestUtils.test'; +import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test'; import { DEFAULT_ATTR_DATA } from './Buffer'; import { Terminal } from './Terminal'; import { IBufferLine } from './Types'; diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index c7bbbeb83..8f734bacb 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -4,10 +4,9 @@ */ import { assert } from 'chai'; -import { IMouseZoneManager, IMouseZone } from './ui/Types'; -import { ILinkMatcher, ITerminal, IBufferLine } from './Types'; +import { IMouseZoneManager, IMouseZone, ILinkMatcher, ITerminal, IBufferLine } from './Types'; import { Linkifier } from './Linkifier'; -import { MockBuffer, MockTerminal, TestTerminal } from './ui/TestUtils.test'; +import { MockBuffer, MockTerminal, TestTerminal } from './TestUtils.test'; import { CircularList } from './common/CircularList'; import { BufferLine, CellData } from './BufferLine'; diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 8c57e1b22..7227013dc 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { IMouseZoneManager } from './ui/Types'; +import { IMouseZoneManager } from './Types'; import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult } from './Types'; -import { MouseZone } from './ui/MouseZoneManager'; +import { MouseZone } from './MouseZoneManager'; import { getStringCellWidth } from './CharWidth'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; diff --git a/src/ui/MouseHelper.test.ts b/src/MouseHelper.test.ts similarity index 100% rename from src/ui/MouseHelper.test.ts rename to src/MouseHelper.test.ts diff --git a/src/ui/MouseHelper.ts b/src/MouseHelper.ts similarity index 96% rename from src/ui/MouseHelper.ts rename to src/MouseHelper.ts index e36e7f17c..fb91c9ef8 100644 --- a/src/ui/MouseHelper.ts +++ b/src/MouseHelper.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { ICharMeasure, IMouseHelper } from '../Types'; -import { IRenderer } from '../renderer/Types'; +import { ICharMeasure, IMouseHelper } from './Types'; +import { IRenderer } from './renderer/Types'; export class MouseHelper implements IMouseHelper { constructor(private _renderer: IRenderer) {} diff --git a/src/ui/MouseZoneManager.ts b/src/MouseZoneManager.ts similarity index 97% rename from src/ui/MouseZoneManager.ts rename to src/MouseZoneManager.ts index 372dccc57..2f293df14 100644 --- a/src/ui/MouseZoneManager.ts +++ b/src/MouseZoneManager.ts @@ -3,10 +3,9 @@ * @license MIT */ -import { ITerminal } from '../Types'; -import { IMouseZoneManager, IMouseZone } from './Types'; -import { Disposable } from '../common/Lifecycle'; -import { addDisposableDomListener } from './Lifecycle'; +import { ITerminal, IMouseZoneManager, IMouseZone } from './Types'; +import { Disposable } from './common/Lifecycle'; +import { addDisposableDomListener } from './ui/Lifecycle'; const HOVER_DURATION = 500; diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index d65f97160..9a2ac4051 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -4,12 +4,12 @@ */ import { assert } from 'chai'; -import { CharMeasure } from './ui/CharMeasure'; +import { CharMeasure } from './CharMeasure'; import { SelectionManager, SelectionMode } from './SelectionManager'; import { SelectionModel } from './SelectionModel'; import { BufferSet } from './BufferSet'; import { ITerminal, IBuffer, IBufferLine } from './Types'; -import { MockTerminal } from './ui/TestUtils.test'; +import { MockTerminal } from './TestUtils.test'; import { BufferLine, CellData } from './BufferLine'; class TestMockTerminal extends MockTerminal { diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index eed206cc6..dcd600687 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -4,9 +4,9 @@ */ import { ITerminal, ISelectionManager, IBuffer, IBufferLine, ISelectionRedrawRequestEvent } from './Types'; -import { MouseHelper } from './ui/MouseHelper'; +import { MouseHelper } from './MouseHelper'; import * as Browser from './common/Platform'; -import { CharMeasure } from './ui/CharMeasure'; +import { CharMeasure } from './CharMeasure'; import { SelectionModel } from './SelectionModel'; import { AltClickHandler } from './handlers/AltClickHandler'; import { CellData } from './BufferLine'; diff --git a/src/SelectionModel.test.ts b/src/SelectionModel.test.ts index d49f41d0c..c2b261a98 100644 --- a/src/SelectionModel.test.ts +++ b/src/SelectionModel.test.ts @@ -7,7 +7,7 @@ import { assert } from 'chai'; import { ITerminal } from './Types'; import { SelectionModel } from './SelectionModel'; import { BufferSet } from './BufferSet'; -import { MockTerminal } from './ui/TestUtils.test'; +import { MockTerminal } from './TestUtils.test'; class TestSelectionModel extends SelectionModel { constructor( diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index dd8e32e18..69fbb8e2e 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -5,7 +5,7 @@ import { assert, expect } from 'chai'; import { Terminal } from './Terminal'; -import { MockViewport, MockCompositionHelper, MockRenderer } from './ui/TestUtils.test'; +import { MockViewport, MockCompositionHelper, MockRenderer } from './TestUtils.test'; import { DEFAULT_ATTR_DATA } from './Buffer'; import { CellData } from './BufferLine'; diff --git a/src/Terminal.ts b/src/Terminal.ts index 16ac69b32..3fe5b5904 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -21,27 +21,26 @@ * http://linux.die.net/man/7/urxvt */ -import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData } from './Types'; -import { IMouseZoneManager } from './ui/Types'; +import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData, IMouseZoneManager } from './Types'; import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer'; import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './common/EventEmitter'; import { Viewport } from './Viewport'; -import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './ui/Clipboard'; +import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './Clipboard'; import { C0 } from './common/data/EscapeSequences'; import { InputHandler } from './InputHandler'; import { Renderer } from './renderer/Renderer'; import { Linkifier } from './Linkifier'; import { SelectionManager } from './SelectionManager'; -import { CharMeasure } from './ui/CharMeasure'; +import { CharMeasure } from './CharMeasure'; import * as Browser from './common/Platform'; import { addDisposableDomListener } from './ui/Lifecycle'; import * as Strings from './Strings'; -import { MouseHelper } from './ui/MouseHelper'; +import { MouseHelper } from './MouseHelper'; import { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager'; -import { MouseZoneManager } from './ui/MouseZoneManager'; +import { MouseZoneManager } from './MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ScreenDprMonitor } from './ui/ScreenDprMonitor'; import { ITheme, IMarker, IDisposable } from 'xterm'; diff --git a/src/ui/TestUtils.test.ts b/src/TestUtils.test.ts similarity index 97% rename from src/ui/TestUtils.test.ts rename to src/TestUtils.test.ts index 5ee0f9d5c..92018d1f1 100644 --- a/src/ui/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -3,14 +3,14 @@ * @license MIT */ -import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types'; -import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferLine, IBufferStringIterator, ICellData, IAttributeData } from '../Types'; -import { ICircularList, XtermListener } from '../common/Types'; -import { Buffer } from '../Buffer'; -import * as Browser from '../common/Platform'; +import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from './renderer/Types'; +import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferLine, IBufferStringIterator, ICellData, IAttributeData } from './Types'; +import { ICircularList, XtermListener } from './common/Types'; +import { Buffer } from './Buffer'; +import * as Browser from './common/Platform'; import { ITheme, IDisposable, IMarker, IEvent } from 'xterm'; -import { Terminal } from '../Terminal'; -import { AttributeData } from '../BufferLine'; +import { Terminal } from './Terminal'; +import { AttributeData } from './BufferLine'; export class TestTerminal extends Terminal { writeSync(data: string): void { diff --git a/src/Types.ts b/src/Types.ts index a70dfdad2..e603e92b5 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -5,7 +5,6 @@ import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter, IDisposable } from 'xterm'; import { IColorSet, IRenderer } from './renderer/Types'; -import { IMouseZoneManager } from './ui/Types'; import { ICharset } from './core/Types'; import { ICircularList } from './common/Types'; import { IEvent } from './common/EventEmitter2'; @@ -604,3 +603,20 @@ export interface IBufferLine { isCombined(index: number): number; getString(index: number): string; } + +export interface IMouseZoneManager extends IDisposable { + add(zone: IMouseZone): void; + clearAll(start?: number, end?: number): void; +} + +export interface IMouseZone { + x1: number; + x2: number; + y1: number; + y2: number; + clickCallback: (e: MouseEvent) => any; + hoverCallback: (e: MouseEvent) => any | undefined; + tooltipCallback: (e: MouseEvent) => any | undefined; + leaveCallback: () => any | undefined; + willLinkActivate: (e: MouseEvent) => boolean; +} diff --git a/src/Viewport.ts b/src/Viewport.ts index 50d044571..6bf92531c 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -5,7 +5,7 @@ import { IColorSet } from './renderer/Types'; import { ITerminal, IViewport } from './Types'; -import { CharMeasure } from './ui/CharMeasure'; +import { CharMeasure } from './CharMeasure'; import { Disposable } from './common/Lifecycle'; import { addDisposableDomListener } from './ui/Lifecycle'; diff --git a/src/renderer/CharacterJoinerRegistry.test.ts b/src/renderer/CharacterJoinerRegistry.test.ts index effdbfaaf..2ccfd1978 100644 --- a/src/renderer/CharacterJoinerRegistry.test.ts +++ b/src/renderer/CharacterJoinerRegistry.test.ts @@ -1,6 +1,6 @@ import { assert } from 'chai'; -import { MockTerminal, MockBuffer } from '../ui/TestUtils.test'; +import { MockTerminal, MockBuffer } from '../TestUtils.test'; import { CircularList } from '../common/CircularList'; import { ICharacterJoinerRegistry } from './Types'; diff --git a/src/ui/Types.ts b/src/ui/Types.ts deleted file mode 100644 index 89dfa1a4f..000000000 --- a/src/ui/Types.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { IDisposable } from 'xterm'; - -export interface IMouseZoneManager extends IDisposable { - add(zone: IMouseZone): void; - clearAll(start?: number, end?: number): void; -} - -export interface IMouseZone { - x1: number; - x2: number; - y1: number; - y2: number; - clickCallback: (e: MouseEvent) => any; - hoverCallback: (e: MouseEvent) => any | undefined; - tooltipCallback: (e: MouseEvent) => any | undefined; - leaveCallback: () => any | undefined; - willLinkActivate: (e: MouseEvent) => boolean; -} From 4453a1cbf7b2f539956a60898876b341fd717788 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 28 Apr 2019 03:52:08 +0000 Subject: [PATCH 06/37] Automatically release stable builds Part of #1921 --- bin/publish.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index ec7bf173d..d5e5047e9 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -11,9 +11,12 @@ const packageJson = require('../package.json'); // Setup auth fs.writeFileSync(`${process.env['HOME']}/.npmrc`, `//registry.npmjs.org/:_authToken=${process.env['NPM_AUTH_TOKEN']}`); -// Get the version -const tag = 'beta' -const nextVersion = getNextVersion(tag); +// Determine if this is a stable or beta release +const publishedVersions = getPublishedVersions(); +const isStableRelease = publishedVersions.indexOf(packageJson.version) === -1; + +// Get the next version +let nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion(); console.log(`Publishing version: ${nextVersion}`); // Set the version in package.json @@ -22,16 +25,19 @@ packageJson.version = nextVersion; fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2)); // Publish -const result = cp.spawn('npm', ['publish', '--tag', tag], { - stdio: 'inherit' -}); +const args = ['publish']; +if (!isStableRelease) { + args.push('--tag', 'beta'); +} +const result = cp.spawn('npm', args, { stdio: 'inherit' }); result.on('exit', code => process.exit(code)); -function getNextVersion(tag) { +function getNextBetaVersion() { if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.exec(packageJson.version)) { console.error('The package.json version must be of the form x.y.z'); process.exit(1); } + const tag = 'beta'; const stableVersion = packageJson.version.split('.'); const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.${stableVersion[2]}`; const publishedVersions = getPublishedVersions(nextStableVersion, tag); @@ -46,5 +52,8 @@ function getNextVersion(tag) { function getPublishedVersions(version, tag) { const versionsProcess = cp.spawnSync('npm', ['view', 'xterm', 'versions', '--json']); const versionsJson = JSON.parse(versionsProcess.stdout); - return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`))); + if (tag) { + return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`))); + } + return versionsJson; } From f0c3bab156ea5f32f0d824215ff86b14837ed3a9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 29 Apr 2019 11:35:42 -0700 Subject: [PATCH 07/37] Add build and test task --- .vscode/tasks.json | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .vscode/tasks.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..2ff9f3cb7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,48 @@ +{ + "version": "2.0.0", + "presentation": { + "echo": false, + "reveal": "always", + "focus": false, + "panel": "dedicated", + "showReuseMessage": true + }, + "tasks": [ + { + "type": "npm", + "script": "test", + "group": "test", + "problemMatcher": [] + }, + { + "type": "npm", + "script": "watch", + "group": "build", + "isBackground": true, + "problemMatcher": [], + "presentation": { + "group": "vscode" + } + }, + { + "type": "npm", + "script": "start", + "group": "build", + "isBackground": true, + "problemMatcher": [], + "presentation": { + "group": "vscode" + } + }, + { + "label": "Start demo", + "dependsOn": ["npm: watch", "npm: start"], + "group": "build", + "isBackground": true, + "problemMatcher": [], + "presentation": { + "group": "vscode" + } + } + ] +} From 42b1dca7dbc3f9cb93b63f0cabdee4ecb06e0e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 29 Apr 2019 22:33:01 +0200 Subject: [PATCH 08/37] add handling for default fg color --- src/renderer/BaseRenderLayer.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 008b216a9..d851b2f26 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -322,14 +322,18 @@ export abstract class BaseRenderLayer implements IRenderLayer { } else { this._ctx.fillStyle = this._colors.ansi[cell.getBgColor()].css; } - } else if (cell.isFgRGB()) { - this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; - } else if (cell.isFgPalette()) { - let fg = cell.getFgColor(); - if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { - fg += 8; + } else { + if (cell.isFgDefault()) { + this._ctx.fillStyle = this._colors.foreground.css; + } else if (cell.isFgRGB()) { + this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; + } else { + let fg = cell.getFgColor(); + if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { + fg += 8; + } + this._ctx.fillStyle = this._colors.ansi[fg].css; } - this._ctx.fillStyle = this._colors.ansi[fg].css; } this._clipRow(terminal, y); From 1f42e7c06aa617e8e7fc46e9fa0759e59779bcb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 29 Apr 2019 23:19:16 +0200 Subject: [PATCH 09/37] fix fg color for underline --- src/renderer/TextRenderLayer.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 2547ecb24..c4bdf19fd 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -217,10 +217,18 @@ export class TextRenderLayer extends BaseRenderLayer { } else { this._ctx.fillStyle = this._colors.ansi[cell.getBgColor()].css; } - } else if (cell.isFgRGB()) { - this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; - } else if (cell.isFgPalette()) { - this._ctx.fillStyle = this._colors.ansi[cell.getFgColor()].css; + } else { + if (cell.isFgDefault()) { + this._ctx.fillStyle = this._colors.foreground.css; + } else if (cell.isFgRGB()) { + this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; + } else { + let fg = cell.getFgColor(); + if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { + fg += 8; + } + this._ctx.fillStyle = this._colors.ansi[fg].css; + } } this.fillBottomLineAtCells(x, y, cell.getWidth()); From 4fd9b3f249ae7788ff0664f76f875b3202fdced4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 30 Apr 2019 00:58:18 +0200 Subject: [PATCH 10/37] jix joined cell representation as overloaded CellData type --- src/renderer/BaseRenderLayer.ts | 5 +-- src/renderer/CharacterJoinerRegistry.ts | 47 +++++++++++++++++++++++-- src/renderer/TextRenderLayer.ts | 14 ++++---- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index d851b2f26..00b38dcd3 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -10,6 +10,7 @@ import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { CellData, AttributeData } from '../BufferLine'; import { WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer'; +import { JoinedCellData } from './CharacterJoinerRegistry'; export abstract class BaseRenderLayer implements IRenderLayer { private _canvas: HTMLCanvasElement; @@ -260,8 +261,8 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { - // skip cache right away if we draw in RGB - if (cell.isFgRGB() || cell.isBgRGB()) { + // skip cache right away if we draw in RGB or have joined cells + if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof JoinedCellData) { this._drawUncachedChars(terminal, cell, x, y); return; } diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 8c521dd9d..6a47ee222 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -1,8 +1,51 @@ -import { ITerminal, IBufferLine } from '../Types'; +import { ITerminal, IBufferLine, ICellData, CharData } from '../Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData } from '../BufferLine'; +import { CellData, Content } from '../BufferLine'; import { WHITESPACE_CELL_CHAR } from '../Buffer'; +export class JoinedCellData extends CellData implements ICellData { + private _width: number = 0; + private _code: number = 0x1FFFFF; // highest allowed codepoint, meant as -1 + + public content: number = 0; + public fg: number = 0; + public bg: number = 0; + public combinedData: string = ''; + + constructor(firstCell: ICellData, chars: string, width: number) { + super(); + this.fg = firstCell.fg; + this.bg = firstCell.bg; + this.combinedData = chars; + this._width = width; + } + + public isCombined(): number { + // always mark joined cell data as combined + return Content.IS_COMBINED_MASK; + } + + public getWidth(): number { + return this._width; + } + + public getChars(): string { + return this.combinedData; + } + + public getCode(): number { + return this._code; + } + + public setFromCharData(value: CharData): void { + throw new Error('not implemented'); + } + + public getAsCharData(): CharData { + return [this.fg, this.getChars(), this.getWidth(), this.getCode()]; + } +} + export class CharacterJoinerRegistry implements ICharacterJoinerRegistry { private _characterJoiners: ICharacterJoiner[] = []; diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index c4bdf19fd..d54008b8a 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -9,6 +9,7 @@ import { CharData, ITerminal, ICellData } from '../Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; import { CellData, AttributeData, Content } from '../BufferLine'; +import { JoinedCellData } from './CharacterJoinerRegistry'; /** * This CharData looks like a null character, which will forc a clear and render @@ -89,15 +90,12 @@ export class TextRenderLayer extends BaseRenderLayer { // We already know the exact start and end column of the joined range, // so we get the string and width representing it directly - cell = CellData.fromCharData([ - 0, + + cell = new JoinedCellData( + this._workCell, line.translateToString(true, range[0], range[1]), - range[1] - range[0], - 0xFFFFFF - ]); - // hacky: patch attrs - cell.fg = this._workCell.fg; - cell.bg = this._workCell.bg; + range[1] - range[0] + ); // Skip over the cells occupied by this range in the loop lastCharX = range[1] - 1; From 63833b59ed78c1bb5eb40f92dbcda6d845e5d97f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 29 Apr 2019 22:24:44 -0700 Subject: [PATCH 11/37] Fix lint --- src/Linkifier.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 7227013dc..9744929e1 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -3,8 +3,7 @@ * @license MIT */ -import { IMouseZoneManager } from './Types'; -import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult } from './Types'; +import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult, IMouseZoneManager } from './Types'; import { MouseZone } from './MouseZoneManager'; import { getStringCellWidth } from './CharWidth'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; From 469d5158a01d2d8bb5b18bc4066ba77c3cda581b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 30 Apr 2019 19:19:41 +0000 Subject: [PATCH 12/37] Make Terminal.markers readonly --- typings/xterm.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 24a30b256..b6d1e3207 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -359,7 +359,7 @@ declare module 'xterm' { * (EXPERIMENTAL) Get all markers registered against the buffer. If the alt * buffer is active this will always return []. */ - readonly markers: IMarker[]; + readonly markers: ReadonlyArray; /** * Natural language strings that can be localized. From f416bd155a7e40f555c403431e828b37f7b9e1d6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 May 2019 07:53:28 -0700 Subject: [PATCH 13/37] Make compound task the default --- .vscode/tasks.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2ff9f3cb7..2f752faf0 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -37,7 +37,10 @@ { "label": "Start demo", "dependsOn": ["npm: watch", "npm: start"], - "group": "build", + "group": { + "kind": "build", + "isDefault": true + }, "isBackground": true, "problemMatcher": [], "presentation": { From ea09c6af09f89c3a2a1a6886a7daf9d3e4a79ea0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 2 May 2019 09:23:13 -0700 Subject: [PATCH 14/37] Fix build --- src/public/Terminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/Terminal.ts b/src/public/Terminal.ts index d05a4f100..70ce7db4d 100644 --- a/src/public/Terminal.ts +++ b/src/public/Terminal.ts @@ -30,7 +30,7 @@ export class Terminal implements ITerminalApi { public get textarea(): HTMLTextAreaElement { return this._core.textarea; } public get rows(): number { return this._core.rows; } public get cols(): number { return this._core.cols; } - public get markers(): IMarker[] { return this._core.markers; } + public get markers(): ReadonlyArray { return this._core.markers; } public blur(): void { this._core.blur(); } From 23eed1b3ea169fee0e1739fdd712bb256ff4892e Mon Sep 17 00:00:00 2001 From: roottool Date: Sat, 4 May 2019 02:02:26 +0900 Subject: [PATCH 15/37] Fix: Changed pathClause --- src/addons/webLinks/webLinks.test.ts | 166 +++++++++++++++++++++------ src/addons/webLinks/webLinks.ts | 3 +- 2 files changed, 133 insertions(+), 36 deletions(-) diff --git a/src/addons/webLinks/webLinks.test.ts b/src/addons/webLinks/webLinks.test.ts index 1e8a4ae7e..1423e0103 100644 --- a/src/addons/webLinks/webLinks.test.ts +++ b/src/addons/webLinks/webLinks.test.ts @@ -28,63 +28,159 @@ describe('webLinks addon', () => { }); }); - it('should allow ~ character in URI path', () => { - const term = new MockTerminal(); - webLinks.webLinksInit(term); + describe('should allow simple URI path', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); - const row = ' http://foo.com/a~b#c~d?e~f '; + const row = ' http://foo.com '; - const match = row.match(term.regex); - const uri = match[term.options.matchIndex]; + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; - assert.equal(uri, 'http://foo.com/a~b#c~d?e~f'); + assert.equal(uri, 'http://foo.com'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = ' http://bar.io '; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io'); + }); }); - it('should allow : character in URI path', () => { - const term = new MockTerminal(); - webLinks.webLinksInit(term); + describe('should allow ~ character in URI path', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); - const row = ' http://foo.com/colon:test '; + const row = ' http://foo.com/a~b#c~d?e~f '; - const match = row.match(term.regex); - const uri = match[term.options.matchIndex]; + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; - assert.equal(uri, 'http://foo.com/colon:test'); + assert.equal(uri, 'http://foo.com/a~b#c~d?e~f'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = ' http://bar.io/a~b#c~d?e~f '; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/a~b#c~d?e~f'); + }); }); - it('should not allow : character at the end of a URI path', () => { - const term = new MockTerminal(); - webLinks.webLinksInit(term); + describe('should allow : character in URI path', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); - const row = ' http://foo.com/colon:test: '; + const row = ' http://foo.com/colon:test '; - const match = row.match(term.regex); - const uri = match[term.options.matchIndex]; + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; - assert.equal(uri, 'http://foo.com/colon:test'); + assert.equal(uri, 'http://foo.com/colon:test'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = ' http://bar.io/colon:test '; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/colon:test'); + }); }); - it('should not allow " character at the end of a URI enclosed with ""', () => { - const term = new MockTerminal(); - webLinks.webLinksInit(term); + describe('should not allow : character at the end of a URI path', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); - const row = '"http://foo.com/"'; + const row = ' http://foo.com/colon:test: '; - const match = row.match(term.regex); - const uri = match[term.options.matchIndex]; + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; - assert.equal(uri, 'http://foo.com/'); + assert.equal(uri, 'http://foo.com/colon:test'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = ' http://bar.io/colon:test: '; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/colon:test'); + }); }); - it('should not allow \' character at the end of a URI enclosed with \'\'', () => { - const term = new MockTerminal(); - webLinks.webLinksInit(term); + describe('should not allow " character at the end of a URI enclosed with ""', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); - const row = '\'http://foo.com/\''; + const row = '"http://foo.com/"'; - const match = row.match(term.regex); - const uri = match[term.options.matchIndex]; + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; - assert.equal(uri, 'http://foo.com/'); + assert.equal(uri, 'http://foo.com/'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = '"http://bar.io/"'; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/'); + }); + }); + + describe('should not allow \' character at the end of a URI enclosed with \'\'', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = '\'http://foo.com/\''; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://foo.com/'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = '\'http://bar.io/\''; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/'); + }); }); }); diff --git a/src/addons/webLinks/webLinks.ts b/src/addons/webLinks/webLinks.ts index f0d69cc58..9ebc86929 100644 --- a/src/addons/webLinks/webLinks.ts +++ b/src/addons/webLinks/webLinks.ts @@ -14,7 +14,8 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; -const pathClause = '(\\/[\\/\\w\\.\\-%~:]*)*([^:"\'\\s])'; +const pathCharacterSet = '(\\/[\\/\\w\\.\\-%~:]*)*([^:"\'\\s])'; +const pathClause = '(' + pathCharacterSet + ')?'; const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?'; From 4269777f1c17a48a570f57c7242c702e20222ab0 Mon Sep 17 00:00:00 2001 From: roottool Date: Sat, 4 May 2019 02:54:38 +0900 Subject: [PATCH 16/37] Fix: Refactored the css code of keyframes blink --- src/renderer/dom/DomRenderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dom/DomRenderer.ts b/src/renderer/dom/DomRenderer.ts index ea3ac5d98..01d5c7dce 100644 --- a/src/renderer/dom/DomRenderer.ts +++ b/src/renderer/dom/DomRenderer.ts @@ -174,9 +174,9 @@ export class DomRenderer extends Disposable implements IRenderer { // Blink animation styles += `@keyframes blink {` + - ` 0 % { opacity: 1.0; }` + + ` 0% { opacity: 1.0; }` + ` 50% { opacity: 0.0; }` + - ` 100 % { opacity: 1.0; }` + + ` 100% { opacity: 1.0; }` + `}`; // Cursor styles += From 613f8779546ceeb1405dcd07e7a8125d16ab26ab Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 3 May 2019 21:07:21 -0700 Subject: [PATCH 17/37] Add a dev container This lets users using VS Code/Docker avoid installing node and the C++ dependencies necessary for running xterm.js. --- .devcontainer/Dockerfile | 22 ++++++++++++++++++++++ .devcontainer/devcontainer.json | 9 +++++++++ 2 files changed, 31 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..4d4e605b9 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,22 @@ +FROM node:10 + +# Configure apt +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && apt-get -y install --no-install-recommends apt-utils 2>&1 + +# Verify git and process tools are installed +RUN apt-get install -y git procps + +# Install yarn +RUN apt-get install -y curl apt-transport-https lsb-release \ + && curl -sS https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/pubkey.gpg | apt-key add - 2>/dev/null \ + && echo "deb https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ + && apt-get update \ + && apt-get -y install --no-install-recommends yarn + +# Clean up +RUN apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* +ENV DEBIAN_FRONTEND=dialog diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..b00a26936 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,9 @@ +{ + "name": "xterm.js", + "dockerFile": "Dockerfile", + "appPort": 3000, + "extensions": [ + "editorconfig.editorconfig", + "ms-vscode.vscode-typescript-tslint-plugin" + ] +} From ffcdba8d5b86231e5847fa913a0722da0b8f303b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 5 May 2019 21:48:35 +0200 Subject: [PATCH 18/37] simplify JoinedCellData --- src/renderer/BaseRenderLayer.ts | 5 ++++- src/renderer/CharacterJoinerRegistry.ts | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 00b38dcd3..ace1f6781 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -261,7 +261,10 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { - // skip cache right away if we draw in RGB or have joined cells + // skip cache right away if we draw in RGB + // Note: to avoid bad runtime JoinedCellData will be skipped + // in the cache handler (atlasDidDraw == false) itself and + // fall through to uncached later down below if (cell.isFgRGB() || cell.isBgRGB() || cell instanceof JoinedCellData) { this._drawUncachedChars(terminal, cell, x, y); return; diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 6a47ee222..7a3bb8e05 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -1,15 +1,15 @@ import { ITerminal, IBufferLine, ICellData, CharData } from '../Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData, Content } from '../BufferLine'; +import { CellData, Content, AttributeData } from '../BufferLine'; import { WHITESPACE_CELL_CHAR } from '../Buffer'; -export class JoinedCellData extends CellData implements ICellData { - private _width: number = 0; - private _code: number = 0x1FFFFF; // highest allowed codepoint, meant as -1 - +export class JoinedCellData extends AttributeData implements ICellData { + private _width: number; + // .content carries no meaning for joined CellData, simply nullify it + // thus we have to overload all other .content accessors public content: number = 0; - public fg: number = 0; - public bg: number = 0; + public fg: number; + public bg: number; public combinedData: string = ''; constructor(firstCell: ICellData, chars: string, width: number) { @@ -34,7 +34,9 @@ export class JoinedCellData extends CellData implements ICellData { } public getCode(): number { - return this._code; + // code always gets the highest possible fake codepoint (read as -1) + // this is needed as code is used by caches as identifier + return 0x1FFFFF; } public setFromCharData(value: CharData): void { From a88469aac6edd162f6461112d19cecb6c8095c47 Mon Sep 17 00:00:00 2001 From: cubiclesoft Date: Tue, 7 May 2019 12:07:00 -0700 Subject: [PATCH 19/37] Added PHP App Server to Real-world uses section. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2e9f02f2..cbb2d6970 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,8 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Jumpserver**](https://github.com/jumpserver/luna): Jumpserver Luna project, Jumpserver is a bastion server project, Luna use xterm.js for web terminal emulation. - [**LxdMosaic**](https://github.com/turtle0x1/LxdMosaic): Uses xterm.js to give terminal access to containers through LXD - [**CodeInterview.io**](https://codeinterview.io): A coding interview platform in 25+ languages and many web frameworks. Uses xterm.js to provide shell access. -- [**Bastillion**](https://www.bastillion.io): Bastillion is an open-source web-based SSH console that centrally manages administrative access to systems. +- [**Bastillion**](https://www.bastillion.io): Bastillion is an open-source web-based SSH console that centrally manages administrative access to systems. +- [**PHP App Server**](https://github.com/cubiclesoft/php-app-server/): Create lightweight, installable almost-native applications for desktop OSes. ExecTerminal (nicely wraps the xterm.js Terminal), TerminalManager, and RunProcessSDK are self-contained, reusable ES5+ compliant Javascript components. [And much more...](https://github.com/xtermjs/xterm.js/network/dependents) From e831bdf1ef4636f5362fe8f3d941f905c46f84b6 Mon Sep 17 00:00:00 2001 From: Khaja Nizamuddin Date: Wed, 8 May 2019 21:06:22 +0530 Subject: [PATCH 20/37] Allow + char in URI path --- src/addons/webLinks/webLinks.test.ts | 26 ++++++++++++++++++++++++++ src/addons/webLinks/webLinks.ts | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/addons/webLinks/webLinks.test.ts b/src/addons/webLinks/webLinks.test.ts index 1423e0103..da5569ab8 100644 --- a/src/addons/webLinks/webLinks.test.ts +++ b/src/addons/webLinks/webLinks.test.ts @@ -183,4 +183,30 @@ describe('webLinks addon', () => { assert.equal(uri, 'http://bar.io/'); }); }); + + describe('should allow + character in URI path', () => { + it('foo.com', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = 'http://foo.com/subpath/+/id'; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://foo.com/subpath/+/id'); + }); + + it('bar.io', () => { + const term = new MockTerminal(); + webLinks.webLinksInit(term); + + const row = 'http://bar.io/subpath/+/id'; + + const match = row.match(term.regex); + const uri = match[term.options.matchIndex]; + + assert.equal(uri, 'http://bar.io/subpath/+/id'); + }); + }); }); diff --git a/src/addons/webLinks/webLinks.ts b/src/addons/webLinks/webLinks.ts index 9ebc86929..8a0fec097 100644 --- a/src/addons/webLinks/webLinks.ts +++ b/src/addons/webLinks/webLinks.ts @@ -14,7 +14,7 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})'; const localHostClause = '(localhost)'; const portClause = '(:\\d{1,5})'; const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?'; -const pathCharacterSet = '(\\/[\\/\\w\\.\\-%~:]*)*([^:"\'\\s])'; +const pathCharacterSet = '(\\/[\\/\\w\\.\\-%~:+]*)*([^:"\'\\s])'; const pathClause = '(' + pathCharacterSet + ')?'; const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*'; const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?'; From 0d5cd9582fb5dd62d2ee6dbac714725410226c13 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 May 2019 18:03:06 -0700 Subject: [PATCH 21/37] Base the next beta version on the correct current beta Fixes #2044 --- bin/publish.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bin/publish.js b/bin/publish.js index d5e5047e9..350cecebd 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -44,7 +44,14 @@ function getNextBetaVersion() { if (publishedVersions.length === 0) { return `${packageJson.version}-${tag}1`; } - const latestPublishedVersion = publishedVersions.sort((a, b) => b.localeCompare(a))[0]; + const latestPublishedVersion = publishedVersions.sort((a, b) => { + if (b.length > a.length) { + return true; + } else if (b.length < a.length) { + return false; + } + return b.localeCompare(a) + })[0]; const latestTagVersion = parseInt(latestPublishedVersion.substr(latestPublishedVersion.search(/[0-9]+$/)), 10); return `${nextStableVersion}-${tag}${latestTagVersion + 1}`; } From 4b1c54d634bd2b6afc63a2626106ab9b58dd67aa Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 May 2019 20:53:24 -0700 Subject: [PATCH 22/37] Update terminal dimensions after line height changes Fixes #2048 --- demo/client.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/demo/client.ts b/demo/client.ts index c73d81ddc..90a913d7d 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -259,8 +259,11 @@ function initOptions(term: TerminalType): void { console.log('change', o, input.value); if (o === 'cols' || o === 'rows') { updateTerminalSize(); + } else if (o === 'lineHeight') { + term.setOption(o, parseFloat(input.value)); + updateTerminalSize(); } else { - term.setOption(o, o === 'lineHeight' ? parseFloat(input.value) : parseInt(input.value, 10)); + term.setOption(o, parseInt(input.value)); } }); }); From 71886167be39c4e43e4a0584eab3989196a5c271 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 8 May 2019 23:08:39 -0700 Subject: [PATCH 23/37] Replace prepublish On prepublishOnly we want to do a full build, on prepare we want to only build the ts projects so the .d.ts files are avilable. Fixes #2019 --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 539b96daf..41d3e52a8 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "mocha": "gulp test", "prebuild": "tsc -b ./src/tsconfig.all.json", "build": "gulp build", - "prepublish": "npm run build", + "prepare": "npm run prebuild", + "prepublishOnly": "npm run build", "coveralls": "nyc report --reporter=text-lcov | coveralls", "watch": "tsc -b -w ./src/tsconfig.all.json --preserveWatchOutput" } From dc236aeb204d303c91b69b50bf49a61a82e1b6fb Mon Sep 17 00:00:00 2001 From: Jared Flatow Date: Thu, 9 May 2019 00:06:32 -0700 Subject: [PATCH 24/37] Send the unit separator for C-_, like some other keyboards --- src/core/input/Keyboard.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/input/Keyboard.ts b/src/core/input/Keyboard.ts index 5e4c4e617..36097f912 100644 --- a/src/core/input/Keyboard.ts +++ b/src/core/input/Keyboard.ts @@ -352,6 +352,10 @@ export function evaluateKeyboardEvent( } else if (ev.key && !ev.ctrlKey && !ev.altKey && !ev.metaKey && ev.keyCode >= 48 && ev.key.length === 1) { // Include only keys that that result in a _single_ character; don't include num lock, volume up, etc. result.key = ev.key; + } else if (ev.key && ev.ctrlKey) { + if (ev.key === '_') { // ^_ + result.key = C0.US; + } } break; } From b959fc8d6a1faa2674607e25af455c17bc9df6af Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 07:49:50 -0700 Subject: [PATCH 25/37] Update year in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbb2d6970..83170eff5 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,6 @@ You can read the [guide on the wiki](https://github.com/xtermjs/xterm.js/wiki/Co If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. -Copyright (c) 2017-2018, [The xterm.js authors](https://github.com/xtermjs/xterm.js/graphs/contributors) (MIT License)
+Copyright (c) 2017-2019, [The xterm.js authors](https://github.com/xtermjs/xterm.js/graphs/contributors) (MIT License)
Copyright (c) 2014-2017, SourceLair, Private Company ([www.sourcelair.com](https://www.sourcelair.com/home)) (MIT License)
Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) From 79e182d63f8dcbe5f98462f5811771ddce294029 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 08:19:33 -0700 Subject: [PATCH 26/37] Actually fix beta CD Part of #2044 --- bin/publish.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 350cecebd..d55c9b97c 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -45,12 +45,9 @@ function getNextBetaVersion() { return `${packageJson.version}-${tag}1`; } const latestPublishedVersion = publishedVersions.sort((a, b) => { - if (b.length > a.length) { - return true; - } else if (b.length < a.length) { - return false; - } - return b.localeCompare(a) + const aVersion = parseInt(a.substr(a.search(/[0-9]+$/))); + const bVersion = parseInt(b.substr(b.search(/[0-9]+$/))); + return aVersion > bVersion ? -1 : 1; })[0]; const latestTagVersion = parseInt(latestPublishedVersion.substr(latestPublishedVersion.search(/[0-9]+$/)), 10); return `${nextStableVersion}-${tag}${latestTagVersion + 1}`; From e40f9249134ca3f5038fb95fd4eb5f0d036b1228 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 09:37:07 -0700 Subject: [PATCH 27/37] v3.13.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d58a6a5d0..afa6ca5d3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "xterm", "description": "Full xterm terminal, in your browser", - "version": "3.12.0", + "version": "3.13.0", "main": "lib/public/Terminal.js", "types": "typings/xterm.d.ts", "repository": "https://github.com/xtermjs/xterm.js", @@ -61,4 +61,4 @@ "coveralls": "nyc report --reporter=text-lcov | coveralls", "watch": "tsc -b -w ./src/tsconfig.all.json --preserveWatchOutput" } -} \ No newline at end of file +} From 3abc090412bf2f2d6728d4606fdfff39c1977d78 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 10:02:42 -0700 Subject: [PATCH 28/37] Add missing space to typings --- typings/xterm.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index b6d1e3207..9f1fbe62d 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -594,6 +594,7 @@ declare module 'xterm' { * @return An IDisposable you can call to remove this handler. */ addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable; + /** * (EXPERIMENTAL) Registers a link matcher, allowing custom link patterns to * be matched and handled. From 6d55ab23fd38482008e873930b7a4ff32a8d7b70 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 10:11:25 -0700 Subject: [PATCH 29/37] Fix beta CD for new major/minor beta versions --- bin/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/publish.js b/bin/publish.js index d55c9b97c..3b13d6a5a 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -42,7 +42,7 @@ function getNextBetaVersion() { const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.${stableVersion[2]}`; const publishedVersions = getPublishedVersions(nextStableVersion, tag); if (publishedVersions.length === 0) { - return `${packageJson.version}-${tag}1`; + return `${nextStableVersion}-${tag}1`; } const latestPublishedVersion = publishedVersions.sort((a, b) => { const aVersion = parseInt(a.substr(a.search(/[0-9]+$/))); From f381cdfc331a15b51ec606fb7bd89815a2bbd5f4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 21:57:33 -0700 Subject: [PATCH 30/37] Move a bunch of types to core --- src/Buffer.ts | 27 +----- src/BufferLine.test.ts | 6 +- src/BufferLine.ts | 26 +++++- src/BufferReflow.test.ts | 3 +- src/BufferReflow.ts | 2 +- src/BufferSet.ts | 3 +- src/CharWidth.test.ts | 3 +- src/InputHandler.test.ts | 2 +- src/InputHandler.ts | 4 +- src/Linkifier.test.ts | 3 +- src/SelectionManager.test.ts | 3 +- src/SelectionManager.ts | 3 +- src/Terminal.integration.ts | 3 +- src/Terminal.ts | 3 +- src/TestUtils.test.ts | 3 +- src/Types.ts | 82 +------------------ src/WindowsMode.ts | 2 +- src/core/Types.ts | 79 ++++++++++++++++++ src/handlers/AltClickHandler.ts | 3 +- src/renderer/BaseRenderLayer.ts | 6 +- src/renderer/CharacterJoinerRegistry.test.ts | 7 +- src/renderer/CharacterJoinerRegistry.ts | 11 ++- src/renderer/CursorRenderLayer.ts | 3 +- src/renderer/TextRenderLayer.ts | 6 +- .../dom/DomRendererRowFactory.test.ts | 7 +- src/renderer/dom/DomRendererRowFactory.ts | 6 +- 26 files changed, 161 insertions(+), 145 deletions(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index c1c08c85a..db02fd0d6 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -4,9 +4,10 @@ */ import { CircularList, IInsertEvent } from './common/CircularList'; -import { ITerminal, IBuffer, IBufferLine, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult, ICellData, IAttributeData } from './Types'; +import { ITerminal, IBuffer, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult } from './Types'; +import { IBufferLine, ICellData, IAttributeData } from './core/Types'; import { IMarker } from 'xterm'; -import { BufferLine, CellData, AttributeData } from './BufferLine'; +import { BufferLine, CellData, AttributeData, 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 './BufferLine'; import { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from './BufferReflow'; import { DEFAULT_COLOR } from './renderer/atlas/Types'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; @@ -16,30 +17,8 @@ export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); export const DEFAULT_ATTR_DATA = new AttributeData(); -export const CHAR_DATA_ATTR_INDEX = 0; -export const CHAR_DATA_CHAR_INDEX = 1; -export const CHAR_DATA_WIDTH_INDEX = 2; -export const CHAR_DATA_CODE_INDEX = 3; export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 -/** - * Null cell - a real empty cell (containing nothing). - * Note that code should always be 0 for a null cell as - * several test condition of the buffer line rely on this. - */ -export const NULL_CELL_CHAR = ''; -export const NULL_CELL_WIDTH = 1; -export const NULL_CELL_CODE = 0; - -/** - * Whitespace cell. - * This is meant as a replacement for empty cells when needed - * during rendering lines to preserve correct aligment. - */ -export const WHITESPACE_CELL_CHAR = ' '; -export const WHITESPACE_CELL_WIDTH = 1; -export const WHITESPACE_CELL_CODE = 32; - /** * This class represents a terminal buffer (an internal state of the terminal), where the * following information is stored (in high-level): diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index 5b029cb80..82e9610dc 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -3,9 +3,9 @@ * @license MIT */ import * as chai from 'chai'; -import { BufferLine, CellData, Content } from './BufferLine'; -import { CharData, IBufferLine } from './Types'; -import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './Buffer'; +import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; +import { CharData, IBufferLine } from './core/Types'; +import { DEFAULT_ATTR } from './Buffer'; class TestBufferLine extends BufferLine { diff --git a/src/BufferLine.ts b/src/BufferLine.ts index d2f7af402..92ed1de4e 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -2,11 +2,33 @@ * Copyright (c) 2018 The xterm.js authors. All rights reserved. * @license MIT */ -import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from './Types'; -import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, WHITESPACE_CELL_CHAR, CHAR_DATA_ATTR_INDEX } from './Buffer'; +import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from './core/Types'; import { stringFromCodePoint } from './core/input/TextDecoder'; +export const CHAR_DATA_ATTR_INDEX = 0; +export const CHAR_DATA_CHAR_INDEX = 1; +export const CHAR_DATA_WIDTH_INDEX = 2; +export const CHAR_DATA_CODE_INDEX = 3; + +/** + * Null cell - a real empty cell (containing nothing). + * Note that code should always be 0 for a null cell as + * several test condition of the buffer line rely on this. + */ +export const NULL_CELL_CHAR = ''; +export const NULL_CELL_WIDTH = 1; +export const NULL_CELL_CODE = 0; + +/** + * Whitespace cell. + * This is meant as a replacement for empty cells when needed + * during rendering lines to preserve correct aligment. + */ +export const WHITESPACE_CELL_CHAR = ' '; +export const WHITESPACE_CELL_WIDTH = 1; +export const WHITESPACE_CELL_CODE = 32; + /** * buffer memory layout: * diff --git a/src/BufferReflow.test.ts b/src/BufferReflow.test.ts index 9c978dc0a..9a2f3906e 100644 --- a/src/BufferReflow.test.ts +++ b/src/BufferReflow.test.ts @@ -3,9 +3,8 @@ * @license MIT */ import { assert } from 'chai'; -import { BufferLine } from './BufferLine'; +import { BufferLine, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; import { reflowSmallerGetNewLineLengths } from './BufferReflow'; -import { NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './Buffer'; describe('BufferReflow', () => { describe('reflowSmallerGetNewLineLengths', () => { diff --git a/src/BufferReflow.ts b/src/BufferReflow.ts index 40e16c744..7c53de7a4 100644 --- a/src/BufferReflow.ts +++ b/src/BufferReflow.ts @@ -5,7 +5,7 @@ import { BufferLine } from './BufferLine'; import { CircularList } from './common/CircularList'; -import { IBufferLine, ICellData } from './Types'; +import { IBufferLine, ICellData } from './core/Types'; export interface INewLayoutResult { layout: number[]; diff --git a/src/BufferSet.ts b/src/BufferSet.ts index ba885a0e9..f22b92dca 100644 --- a/src/BufferSet.ts +++ b/src/BufferSet.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { ITerminal, IBufferSet, IAttributeData, IBuffer } from './Types'; +import { ITerminal, IBufferSet, IBuffer } from './Types'; +import { IAttributeData } from './core/Types'; import { Buffer } from './Buffer'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; diff --git a/src/CharWidth.test.ts b/src/CharWidth.test.ts index ff6f17ede..0821d8645 100644 --- a/src/CharWidth.test.ts +++ b/src/CharWidth.test.ts @@ -7,8 +7,7 @@ import { TestTerminal } from './TestUtils.test'; import { assert } from 'chai'; import { getStringCellWidth, wcwidth } from './CharWidth'; import { IBuffer } from './Types'; -import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer'; -import { CellData } from './BufferLine'; +import { CellData, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './BufferLine'; describe('getStringCellWidth', function(): void { diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index dcd4d1b46..3089aa0aa 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -8,7 +8,7 @@ import { InputHandler } from './InputHandler'; import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test'; import { DEFAULT_ATTR_DATA } from './Buffer'; import { Terminal } from './Terminal'; -import { IBufferLine } from './Types'; +import { IBufferLine } from './core/Types'; import { CellData, Attributes, AttributeData } from './BufferLine'; describe('InputHandler', () => { diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 66d16c04c..dc2e5eb2c 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -7,14 +7,14 @@ import { IInputHandler, IDcsHandler, IEscapeSequenceParser, IInputHandlingTerminal } from './Types'; import { C0, C1 } from './common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets'; -import { NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR_DATA } from './Buffer'; +import { DEFAULT_ATTR_DATA } from './Buffer'; import { wcwidth } from './CharWidth'; import { EscapeSequenceParser } from './EscapeSequenceParser'; import { IDisposable } from 'xterm'; import { Disposable } from './common/Lifecycle'; import { concat } from './common/TypedArrayUtils'; import { StringToUtf32, stringFromCodePoint, utf32ToString } from './core/input/TextDecoder'; -import { CellData, Attributes, FgFlags, BgFlags, AttributeData } from './BufferLine'; +import { CellData, Attributes, FgFlags, BgFlags, AttributeData, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; /** diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 8f734bacb..d22244c9f 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -4,7 +4,8 @@ */ import { assert } from 'chai'; -import { IMouseZoneManager, IMouseZone, ILinkMatcher, ITerminal, IBufferLine } from './Types'; +import { IMouseZoneManager, IMouseZone, ILinkMatcher, ITerminal } from './Types'; +import { IBufferLine } from './core/Types'; import { Linkifier } from './Linkifier'; import { MockBuffer, MockTerminal, TestTerminal } from './TestUtils.test'; import { CircularList } from './common/CircularList'; diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 9a2ac4051..07bbe8be1 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -8,7 +8,8 @@ import { CharMeasure } from './CharMeasure'; import { SelectionManager, SelectionMode } from './SelectionManager'; import { SelectionModel } from './SelectionModel'; import { BufferSet } from './BufferSet'; -import { ITerminal, IBuffer, IBufferLine } from './Types'; +import { ITerminal, IBuffer } from './Types'; +import { IBufferLine } from './core/Types'; import { MockTerminal } from './TestUtils.test'; import { BufferLine, CellData } from './BufferLine'; diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index dcd600687..2d6513480 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { ITerminal, ISelectionManager, IBuffer, IBufferLine, ISelectionRedrawRequestEvent } from './Types'; +import { ITerminal, ISelectionManager, IBuffer, ISelectionRedrawRequestEvent } from './Types'; +import { IBufferLine } from './core/Types'; import { MouseHelper } from './MouseHelper'; import * as Browser from './common/Platform'; import { CharMeasure } from './CharMeasure'; diff --git a/src/Terminal.integration.ts b/src/Terminal.integration.ts index 100430066..b03627dfc 100644 --- a/src/Terminal.integration.ts +++ b/src/Terminal.integration.ts @@ -13,9 +13,8 @@ import * as path from 'path'; import * as pty from 'node-pty'; import { assert } from 'chai'; import { Terminal } from './Terminal'; -import { WHITESPACE_CELL_CHAR } from './Buffer'; import { IViewport } from './Types'; -import { CellData } from './BufferLine'; +import { CellData, WHITESPACE_CELL_CHAR } from './BufferLine'; class TestTerminal extends Terminal { innerWrite(): void { this._innerWrite(); } diff --git a/src/Terminal.ts b/src/Terminal.ts index 3fe5b5904..3653efc7d 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -21,7 +21,8 @@ * http://linux.die.net/man/7/urxvt */ -import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData, IMouseZoneManager } from './Types'; +import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IMouseZoneManager } from './Types'; +import { IBufferLine, IAttributeData } from './core/Types'; import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer'; diff --git a/src/TestUtils.test.ts b/src/TestUtils.test.ts index 92018d1f1..8170681d8 100644 --- a/src/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -4,7 +4,8 @@ */ import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from './renderer/Types'; -import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferLine, IBufferStringIterator, ICellData, IAttributeData } from './Types'; +import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferStringIterator } from './Types'; +import { IBufferLine, ICellData, IAttributeData } from './core/Types'; import { ICircularList, XtermListener } from './common/Types'; import { Buffer } from './Buffer'; import * as Browser from './common/Platform'; diff --git a/src/Types.ts b/src/Types.ts index e603e92b5..56feb71f5 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -5,13 +5,12 @@ import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter, IDisposable } from 'xterm'; import { IColorSet, IRenderer } from './renderer/Types'; -import { ICharset } from './core/Types'; +import { ICharset, IAttributeData, ICellData, IBufferLine, CharData } from './core/Types'; import { ICircularList } from './common/Types'; import { IEvent } from './common/EventEmitter2'; export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean; -export type CharData = [number, string, number, number]; export type LineData = CharData[]; export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void; @@ -525,85 +524,6 @@ export interface IEscapeSequenceParser extends IDisposable { clearErrorHandler(): void; } -/** RGB color type */ -export type IColorRGB = [number, number, number]; - -/** Attribute data */ -export interface IAttributeData { - fg: number; - bg: number; - - clone(): IAttributeData; - - // flags - isInverse(): number; - isBold(): number; - isUnderline(): number; - isBlink(): number; - isInvisible(): number; - isItalic(): number; - isDim(): number; - - // color modes - getFgColorMode(): number; - getBgColorMode(): number; - isFgRGB(): boolean; - isBgRGB(): boolean; - isFgPalette(): boolean; - isBgPalette(): boolean; - isFgDefault(): boolean; - isBgDefault(): boolean; - - // colors - getFgColor(): number; - getBgColor(): number; -} - -/** Cell data */ -export interface ICellData extends IAttributeData { - content: number; - combinedData: string; - isCombined(): number; - getWidth(): number; - getChars(): string; - getCode(): number; - setFromCharData(value: CharData): void; - getAsCharData(): CharData; -} - -/** - * Interface for a line in the terminal buffer. - */ -export interface IBufferLine { - length: number; - isWrapped: boolean; - get(index: number): CharData; - set(index: number, value: CharData): void; - loadCell(index: number, cell: ICellData): ICellData; - setCell(index: number, cell: ICellData): void; - setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void; - addCodepointToCell(index: number, codePoint: number): void; - insertCells(pos: number, n: number, ch: ICellData): void; - deleteCells(pos: number, n: number, fill: ICellData): void; - replaceCells(start: number, end: number, fill: ICellData): void; - resize(cols: number, fill: ICellData): void; - fill(fillCellData: ICellData): void; - copyFrom(line: IBufferLine): void; - clone(): IBufferLine; - getTrimmedLength(): number; - translateToString(trimRight?: boolean, startCol?: number, endCol?: number): string; - - /* direct access to cell attrs */ - getWidth(index: number): number; - hasWidth(index: number): number; - getFg(index: number): number; - getBg(index: number): number; - hasContent(index: number): number; - getCodePoint(index: number): number; - isCombined(index: number): number; - getString(index: number): string; -} - export interface IMouseZoneManager extends IDisposable { add(zone: IMouseZone): void; clearAll(start?: number, end?: number): void; diff --git a/src/WindowsMode.ts b/src/WindowsMode.ts index ac1d193e4..1e58c50ce 100644 --- a/src/WindowsMode.ts +++ b/src/WindowsMode.ts @@ -5,7 +5,7 @@ import { IDisposable } from 'xterm'; import { ITerminal } from './Types'; -import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './Buffer'; +import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './BufferLine'; export function applyWindowsMode(terminal: ITerminal): IDisposable { // Winpty does not support wraparound mode which means that lines will never diff --git a/src/core/Types.ts b/src/core/Types.ts index 4001e4488..ae9274b84 100644 --- a/src/core/Types.ts +++ b/src/core/Types.ts @@ -19,3 +19,82 @@ export interface IKeyboardResult { export interface ICharset { [key: string]: string; } + +export type CharData = [number, string, number, number]; +export type IColorRGB = [number, number, number]; + +/** Attribute data */ +export interface IAttributeData { + fg: number; + bg: number; + + clone(): IAttributeData; + + // flags + isInverse(): number; + isBold(): number; + isUnderline(): number; + isBlink(): number; + isInvisible(): number; + isItalic(): number; + isDim(): number; + + // color modes + getFgColorMode(): number; + getBgColorMode(): number; + isFgRGB(): boolean; + isBgRGB(): boolean; + isFgPalette(): boolean; + isBgPalette(): boolean; + isFgDefault(): boolean; + isBgDefault(): boolean; + + // colors + getFgColor(): number; + getBgColor(): number; +} + +/** Cell data */ +export interface ICellData extends IAttributeData { + content: number; + combinedData: string; + isCombined(): number; + getWidth(): number; + getChars(): string; + getCode(): number; + setFromCharData(value: CharData): void; + getAsCharData(): CharData; +} + +/** + * Interface for a line in the terminal buffer. + */ +export interface IBufferLine { + length: number; + isWrapped: boolean; + get(index: number): CharData; + set(index: number, value: CharData): void; + loadCell(index: number, cell: ICellData): ICellData; + setCell(index: number, cell: ICellData): void; + setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void; + addCodepointToCell(index: number, codePoint: number): void; + insertCells(pos: number, n: number, ch: ICellData): void; + deleteCells(pos: number, n: number, fill: ICellData): void; + replaceCells(start: number, end: number, fill: ICellData): void; + resize(cols: number, fill: ICellData): void; + fill(fillCellData: ICellData): void; + copyFrom(line: IBufferLine): void; + clone(): IBufferLine; + getTrimmedLength(): number; + translateToString(trimRight?: boolean, startCol?: number, endCol?: number): string; + + /* direct access to cell attrs */ + getWidth(index: number): number; + hasWidth(index: number): number; + getFg(index: number): number; + getBg(index: number): number; + hasContent(index: number): number; + getCodePoint(index: number): number; + isCombined(index: number): number; + getString(index: number): string; +} diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 9286421e2..5cf60fa62 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -3,7 +3,8 @@ * @license MIT */ -import { ITerminal, IBufferLine } from '../Types'; +import { ITerminal } from '../Types'; +import { IBufferLine } from '../core/Types'; import { ICircularList } from '../common/Types'; import { C0 } from '../common/data/EscapeSequences'; diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index ace1f6781..8b1e27c59 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -4,12 +4,12 @@ */ import { IRenderLayer, IColorSet, IRenderDimensions } from './Types'; -import { ITerminal, ICellData } from '../Types'; +import { ITerminal } from '../Types'; +import { ICellData } from '../core/Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier, DEFAULT_COLOR } from './atlas/Types'; import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; -import { CellData, AttributeData } from '../BufferLine'; -import { WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../Buffer'; +import { CellData, AttributeData, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../BufferLine'; import { JoinedCellData } from './CharacterJoinerRegistry'; export abstract class BaseRenderLayer implements IRenderLayer { diff --git a/src/renderer/CharacterJoinerRegistry.test.ts b/src/renderer/CharacterJoinerRegistry.test.ts index 2ccfd1978..590d6a5f5 100644 --- a/src/renderer/CharacterJoinerRegistry.test.ts +++ b/src/renderer/CharacterJoinerRegistry.test.ts @@ -1,3 +1,8 @@ +/** + * Copyright (c) 2018 The xterm.js authors. All rights reserved. + * @license MIT + */ + import { assert } from 'chai'; import { MockTerminal, MockBuffer } from '../TestUtils.test'; @@ -6,7 +11,7 @@ import { CircularList } from '../common/CircularList'; import { ICharacterJoinerRegistry } from './Types'; import { CharacterJoinerRegistry } from './CharacterJoinerRegistry'; import { BufferLine, CellData } from '../BufferLine'; -import { IBufferLine } from '../Types'; +import { IBufferLine } from '../core/Types'; describe('CharacterJoinerRegistry', () => { let registry: ICharacterJoinerRegistry; diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 7a3bb8e05..33cd89360 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -1,7 +1,12 @@ -import { ITerminal, IBufferLine, ICellData, CharData } from '../Types'; +/** + * Copyright (c) 2018 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { ITerminal } from '../Types'; +import { IBufferLine, ICellData, CharData } from '../core/Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData, Content, AttributeData } from '../BufferLine'; -import { WHITESPACE_CELL_CHAR } from '../Buffer'; +import { CellData, Content, AttributeData, WHITESPACE_CELL_CHAR } from '../BufferLine'; export class JoinedCellData extends AttributeData implements ICellData { private _width: number; diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index c3b751fa9..72aaa4471 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -5,7 +5,8 @@ import { IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { ITerminal, ICellData } from '../Types'; +import { ITerminal } from '../Types'; +import { ICellData } from '../core/Types'; import { CellData } from '../BufferLine'; interface ICursorState { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index d54008b8a..90c7e2677 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -3,12 +3,12 @@ * @license MIT */ -import { NULL_CELL_CODE } from '../Buffer'; import { IColorSet, IRenderDimensions, ICharacterJoinerRegistry } from './Types'; -import { CharData, ITerminal, ICellData } from '../Types'; +import { ITerminal } from '../Types'; +import { CharData, ICellData } from '../core/Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { CellData, AttributeData, Content } from '../BufferLine'; +import { CellData, AttributeData, Content, NULL_CELL_CODE } from '../BufferLine'; import { JoinedCellData } from './CharacterJoinerRegistry'; /** diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index 076f5d6a3..c795c5aea 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -6,9 +6,10 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { DomRendererRowFactory } from './DomRendererRowFactory'; -import { DEFAULT_ATTR, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR_DATA } from '../../Buffer'; -import { BufferLine, CellData, FgFlags, BgFlags, Attributes } from '../../BufferLine'; -import { IBufferLine, ITerminalOptions } from '../../Types'; +import { DEFAULT_ATTR, DEFAULT_ATTR_DATA } from '../../Buffer'; +import { BufferLine, CellData, FgFlags, BgFlags, Attributes, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '../../BufferLine'; +import { ITerminalOptions } from '../../Types'; +import { IBufferLine } from '../../core/Types'; describe('DomRendererRowFactory', () => { let dom: jsdom.JSDOM; diff --git a/src/renderer/dom/DomRendererRowFactory.ts b/src/renderer/dom/DomRendererRowFactory.ts index 60e2d5098..481d096ef 100644 --- a/src/renderer/dom/DomRendererRowFactory.ts +++ b/src/renderer/dom/DomRendererRowFactory.ts @@ -3,10 +3,10 @@ * @license MIT */ -import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../Buffer'; -import { IBufferLine, ITerminalOptions } from '../../Types'; +import { ITerminalOptions } from '../../Types'; +import { IBufferLine } from '../../core/Types'; import { INVERTED_DEFAULT_COLOR } from '../atlas/Types'; -import { CellData, AttributeData } from '../../BufferLine'; +import { CellData, AttributeData, NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../BufferLine'; export const BOLD_CLASS = 'xterm-bold'; export const DIM_CLASS = 'xterm-dim'; From 7b7fc53157c807f1389f8cfed6570c27966dfde4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 22:10:07 -0700 Subject: [PATCH 31/37] Move more BufferLine dependencies into core --- src/Buffer.test.ts | 4 ++-- src/Buffer.ts | 7 +------ src/BufferLine.test.ts | 3 +-- src/BufferLine.ts | 4 ++++ src/InputHandler.test.ts | 3 +-- src/InputHandler.ts | 3 +-- src/Terminal.test.ts | 3 +-- src/Terminal.ts | 7 +++---- src/common/Types.ts | 2 ++ src/renderer/BaseRenderLayer.ts | 3 ++- src/renderer/atlas/CharAtlasUtils.ts | 3 ++- src/renderer/atlas/StaticCharAtlas.ts | 3 ++- src/renderer/atlas/Types.ts | 1 - src/renderer/dom/DomRendererRowFactory.test.ts | 3 +-- 14 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index d866fd569..618a97954 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -5,10 +5,10 @@ import { assert, expect } from 'chai'; import { ITerminal } from './Types'; -import { Buffer, DEFAULT_ATTR_DATA } from './Buffer'; +import { Buffer } from './Buffer'; import { CircularList } from './common/CircularList'; import { MockTerminal, TestTerminal } from './TestUtils.test'; -import { BufferLine, CellData } from './BufferLine'; +import { BufferLine, CellData, DEFAULT_ATTR_DATA } from './BufferLine'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/Buffer.ts b/src/Buffer.ts index db02fd0d6..7e986a6c0 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -7,16 +7,11 @@ import { CircularList, IInsertEvent } from './common/CircularList'; import { ITerminal, IBuffer, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult } from './Types'; import { IBufferLine, ICellData, IAttributeData } from './core/Types'; import { IMarker } from 'xterm'; -import { BufferLine, CellData, AttributeData, 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 './BufferLine'; +import { BufferLine, CellData, 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, DEFAULT_ATTR_DATA } from './BufferLine'; import { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from './BufferReflow'; -import { DEFAULT_COLOR } from './renderer/atlas/Types'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; import { Disposable } from '../lib/common/Lifecycle'; -export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); - -export const DEFAULT_ATTR_DATA = new AttributeData(); - export const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1 /** diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index 82e9610dc..b9e40491d 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -3,9 +3,8 @@ * @license MIT */ import * as chai from 'chai'; -import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; +import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './BufferLine'; import { CharData, IBufferLine } from './core/Types'; -import { DEFAULT_ATTR } from './Buffer'; class TestBufferLine extends BufferLine { diff --git a/src/BufferLine.ts b/src/BufferLine.ts index 92ed1de4e..39b6116d2 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -4,7 +4,9 @@ */ import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from './core/Types'; import { stringFromCodePoint } from './core/input/TextDecoder'; +import { DEFAULT_COLOR } from './common/Types'; +export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); export const CHAR_DATA_ATTR_INDEX = 0; export const CHAR_DATA_CHAR_INDEX = 1; @@ -215,6 +217,8 @@ export class AttributeData implements IAttributeData { } } +export const DEFAULT_ATTR_DATA = new AttributeData(); + /** * CellData - represents a single Cell in the terminal buffer. */ diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 3089aa0aa..c02867799 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -6,10 +6,9 @@ import { assert, expect } from 'chai'; import { InputHandler } from './InputHandler'; import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test'; -import { DEFAULT_ATTR_DATA } from './Buffer'; import { Terminal } from './Terminal'; import { IBufferLine } from './core/Types'; -import { CellData, Attributes, AttributeData } from './BufferLine'; +import { CellData, Attributes, AttributeData, DEFAULT_ATTR_DATA } from './BufferLine'; describe('InputHandler', () => { describe('save and restore cursor', () => { diff --git a/src/InputHandler.ts b/src/InputHandler.ts index dc2e5eb2c..ebdc9d0d1 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -7,14 +7,13 @@ import { IInputHandler, IDcsHandler, IEscapeSequenceParser, IInputHandlingTerminal } from './Types'; import { C0, C1 } from './common/data/EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets'; -import { DEFAULT_ATTR_DATA } from './Buffer'; import { wcwidth } from './CharWidth'; import { EscapeSequenceParser } from './EscapeSequenceParser'; import { IDisposable } from 'xterm'; import { Disposable } from './common/Lifecycle'; import { concat } from './common/TypedArrayUtils'; import { StringToUtf32, stringFromCodePoint, utf32ToString } from './core/input/TextDecoder'; -import { CellData, Attributes, FgFlags, BgFlags, AttributeData, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; +import { CellData, Attributes, FgFlags, BgFlags, AttributeData, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR_DATA } from './BufferLine'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; /** diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 69fbb8e2e..06a02d68d 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -6,8 +6,7 @@ import { assert, expect } from 'chai'; import { Terminal } from './Terminal'; import { MockViewport, MockCompositionHelper, MockRenderer } from './TestUtils.test'; -import { DEFAULT_ATTR_DATA } from './Buffer'; -import { CellData } from './BufferLine'; +import { CellData, DEFAULT_ATTR_DATA } from './BufferLine'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/Terminal.ts b/src/Terminal.ts index 3653efc7d..0ff21b88a 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -22,10 +22,9 @@ */ import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IMouseZoneManager } from './Types'; -import { IBufferLine, IAttributeData } from './core/Types'; import { IRenderer } from './renderer/Types'; import { BufferSet } from './BufferSet'; -import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer'; +import { Buffer, MAX_BUFFER_SIZE } from './Buffer'; import { CompositionHelper } from './CompositionHelper'; import { EventEmitter } from './common/EventEmitter'; import { Viewport } from './Viewport'; @@ -49,10 +48,10 @@ import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache'; import { DomRenderer } from './renderer/dom/DomRenderer'; import { IKeyboardEvent } from './common/Types'; import { evaluateKeyboardEvent } from './core/input/Keyboard'; -import { KeyboardResultType, ICharset } from './core/Types'; +import { KeyboardResultType, ICharset, IBufferLine, IAttributeData } from './core/Types'; import { clone } from './common/Clone'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; -import { Attributes } from './BufferLine'; +import { Attributes, DEFAULT_ATTR_DATA } from './BufferLine'; import { applyWindowsMode } from './WindowsMode'; // Let it work inside Node.js for automated testing purposes. diff --git a/src/common/Types.ts b/src/common/Types.ts index b2111bfc7..717de359d 100644 --- a/src/common/Types.ts +++ b/src/common/Types.ts @@ -6,6 +6,8 @@ import { IEvent, EventEmitter2 } from './EventEmitter2'; import { IDeleteEvent, IInsertEvent } from './CircularList'; +export const DEFAULT_COLOR = 256; + export interface IDisposable { dispose(): void; } diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 8b1e27c59..63846155b 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -6,7 +6,8 @@ import { IRenderLayer, IColorSet, IRenderDimensions } from './Types'; import { ITerminal } from '../Types'; import { ICellData } from '../core/Types'; -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier, DEFAULT_COLOR } from './atlas/Types'; +import { DEFAULT_COLOR } from '../common/Types'; +import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/Types'; import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { CellData, AttributeData, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../BufferLine'; diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/renderer/atlas/CharAtlasUtils.ts index 5b1add396..c2eb2e1ef 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/renderer/atlas/CharAtlasUtils.ts @@ -5,7 +5,8 @@ import { ITerminal } from '../../Types'; import { IColorSet } from '../Types'; -import { DEFAULT_COLOR, ICharAtlasConfig } from './Types'; +import { ICharAtlasConfig } from './Types'; +import { DEFAULT_COLOR } from '../../common/Types'; export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig { // null out some fields that don't matter diff --git a/src/renderer/atlas/StaticCharAtlas.ts b/src/renderer/atlas/StaticCharAtlas.ts index b54c833ef..66beb363f 100644 --- a/src/renderer/atlas/StaticCharAtlas.ts +++ b/src/renderer/atlas/StaticCharAtlas.ts @@ -3,10 +3,11 @@ * @license MIT */ -import { DIM_OPACITY, IGlyphIdentifier, DEFAULT_COLOR, ICharAtlasConfig, CHAR_ATLAS_CELL_SPACING } from './Types'; +import { DIM_OPACITY, IGlyphIdentifier, ICharAtlasConfig, CHAR_ATLAS_CELL_SPACING } from './Types'; import { generateStaticCharAtlasTexture } from './CharAtlasGenerator'; import BaseCharAtlas from './BaseCharAtlas'; import { is256Color } from './CharAtlasUtils'; +import { DEFAULT_COLOR } from '../../common/Types'; export default class StaticCharAtlas extends BaseCharAtlas { private _texture: HTMLCanvasElement | ImageBitmap; diff --git a/src/renderer/atlas/Types.ts b/src/renderer/atlas/Types.ts index 38923b2f5..2459c72ff 100644 --- a/src/renderer/atlas/Types.ts +++ b/src/renderer/atlas/Types.ts @@ -6,7 +6,6 @@ import { FontWeight } from 'xterm'; import { IColorSet } from '../Types'; -export const DEFAULT_COLOR = 256; export const INVERTED_DEFAULT_COLOR = 257; export const DIM_OPACITY = 0.5; diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index c795c5aea..f009407d4 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -6,8 +6,7 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { DomRendererRowFactory } from './DomRendererRowFactory'; -import { DEFAULT_ATTR, DEFAULT_ATTR_DATA } from '../../Buffer'; -import { BufferLine, CellData, FgFlags, BgFlags, Attributes, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR } from '../../BufferLine'; +import { BufferLine, CellData, FgFlags, BgFlags, Attributes, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, DEFAULT_ATTR_DATA } from '../../BufferLine'; import { ITerminalOptions } from '../../Types'; import { IBufferLine } from '../../core/Types'; From 228ec7b818dc81bca10dce2e7aacfa5e4e078059 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 22:15:32 -0700 Subject: [PATCH 32/37] Move BufferLine into core --- src/Buffer.test.ts | 2 +- src/Buffer.ts | 2 +- src/BufferLine.test.ts | 3 +-- src/BufferReflow.test.ts | 2 +- src/BufferReflow.ts | 2 +- src/CharWidth.test.ts | 2 +- src/InputHandler.test.ts | 2 +- src/InputHandler.ts | 2 +- src/Linkifier.test.ts | 2 +- src/SelectionManager.test.ts | 2 +- src/SelectionManager.ts | 2 +- src/Terminal.integration.ts | 2 +- src/Terminal.test.ts | 2 +- src/Terminal.ts | 2 +- src/TestUtils.test.ts | 2 +- src/WindowsMode.ts | 2 +- src/{ => core/buffer}/BufferLine.ts | 20 +++++++++---------- src/renderer/BaseRenderLayer.ts | 2 +- src/renderer/CharacterJoinerRegistry.test.ts | 2 +- src/renderer/CharacterJoinerRegistry.ts | 2 +- src/renderer/CursorRenderLayer.ts | 2 +- src/renderer/TextRenderLayer.ts | 2 +- .../dom/DomRendererRowFactory.test.ts | 2 +- src/renderer/dom/DomRendererRowFactory.ts | 2 +- 24 files changed, 32 insertions(+), 35 deletions(-) rename src/{ => core/buffer}/BufferLine.ts (97%) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 618a97954..087d0ae52 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -8,7 +8,7 @@ import { ITerminal } from './Types'; import { Buffer } from './Buffer'; import { CircularList } from './common/CircularList'; import { MockTerminal, TestTerminal } from './TestUtils.test'; -import { BufferLine, CellData, DEFAULT_ATTR_DATA } from './BufferLine'; +import { BufferLine, CellData, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/Buffer.ts b/src/Buffer.ts index 7e986a6c0..14bf53aaf 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -7,7 +7,7 @@ import { CircularList, IInsertEvent } from './common/CircularList'; import { ITerminal, IBuffer, BufferIndex, IBufferStringIterator, IBufferStringIteratorResult } from './Types'; import { IBufferLine, ICellData, IAttributeData } from './core/Types'; import { IMarker } from 'xterm'; -import { BufferLine, CellData, 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, DEFAULT_ATTR_DATA } from './BufferLine'; +import { BufferLine, CellData, 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, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; import { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from './BufferReflow'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; import { Disposable } from '../lib/common/Lifecycle'; diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index b9e40491d..87a4e6316 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -3,10 +3,9 @@ * @license MIT */ import * as chai from 'chai'; -import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './BufferLine'; +import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './core/buffer/BufferLine'; import { CharData, IBufferLine } from './core/Types'; - class TestBufferLine extends BufferLine { public get combined(): {[index: number]: string} { return this._combined; diff --git a/src/BufferReflow.test.ts b/src/BufferReflow.test.ts index 9a2f3906e..91454e2aa 100644 --- a/src/BufferReflow.test.ts +++ b/src/BufferReflow.test.ts @@ -3,7 +3,7 @@ * @license MIT */ import { assert } from 'chai'; -import { BufferLine, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './BufferLine'; +import { BufferLine, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE } from './core/buffer/BufferLine'; import { reflowSmallerGetNewLineLengths } from './BufferReflow'; describe('BufferReflow', () => { diff --git a/src/BufferReflow.ts b/src/BufferReflow.ts index 7c53de7a4..c10689671 100644 --- a/src/BufferReflow.ts +++ b/src/BufferReflow.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { BufferLine } from './BufferLine'; +import { BufferLine } from './core/buffer/BufferLine'; import { CircularList } from './common/CircularList'; import { IBufferLine, ICellData } from './core/Types'; diff --git a/src/CharWidth.test.ts b/src/CharWidth.test.ts index 0821d8645..17822fa28 100644 --- a/src/CharWidth.test.ts +++ b/src/CharWidth.test.ts @@ -7,7 +7,7 @@ import { TestTerminal } from './TestUtils.test'; import { assert } from 'chai'; import { getStringCellWidth, wcwidth } from './CharWidth'; import { IBuffer } from './Types'; -import { CellData, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './BufferLine'; +import { CellData, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './core/buffer/BufferLine'; describe('getStringCellWidth', function(): void { diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index c02867799..f2e8d93e9 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -8,7 +8,7 @@ import { InputHandler } from './InputHandler'; import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test'; import { Terminal } from './Terminal'; import { IBufferLine } from './core/Types'; -import { CellData, Attributes, AttributeData, DEFAULT_ATTR_DATA } from './BufferLine'; +import { CellData, Attributes, AttributeData, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; describe('InputHandler', () => { describe('save and restore cursor', () => { diff --git a/src/InputHandler.ts b/src/InputHandler.ts index ebdc9d0d1..b5b98dd96 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -13,7 +13,7 @@ import { IDisposable } from 'xterm'; import { Disposable } from './common/Lifecycle'; import { concat } from './common/TypedArrayUtils'; import { StringToUtf32, stringFromCodePoint, utf32ToString } from './core/input/TextDecoder'; -import { CellData, Attributes, FgFlags, BgFlags, AttributeData, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR_DATA } from './BufferLine'; +import { CellData, Attributes, FgFlags, BgFlags, AttributeData, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; /** diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index d22244c9f..6a2f0ee92 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -9,7 +9,7 @@ import { IBufferLine } from './core/Types'; import { Linkifier } from './Linkifier'; import { MockBuffer, MockTerminal, TestTerminal } from './TestUtils.test'; import { CircularList } from './common/CircularList'; -import { BufferLine, CellData } from './BufferLine'; +import { BufferLine, CellData } from './core/buffer/BufferLine'; class TestLinkifier extends Linkifier { constructor(terminal: ITerminal) { diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 07bbe8be1..24ba01005 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -11,7 +11,7 @@ import { BufferSet } from './BufferSet'; import { ITerminal, IBuffer } from './Types'; import { IBufferLine } from './core/Types'; import { MockTerminal } from './TestUtils.test'; -import { BufferLine, CellData } from './BufferLine'; +import { BufferLine, CellData } from './core/buffer/BufferLine'; class TestMockTerminal extends MockTerminal { emit(event: string, data: any): void {} diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 2d6513480..dabcc9a4d 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -10,7 +10,7 @@ import * as Browser from './common/Platform'; import { CharMeasure } from './CharMeasure'; import { SelectionModel } from './SelectionModel'; import { AltClickHandler } from './handlers/AltClickHandler'; -import { CellData } from './BufferLine'; +import { CellData } from './core/buffer/BufferLine'; import { IDisposable } from 'xterm'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; diff --git a/src/Terminal.integration.ts b/src/Terminal.integration.ts index b03627dfc..5e12d2a30 100644 --- a/src/Terminal.integration.ts +++ b/src/Terminal.integration.ts @@ -14,7 +14,7 @@ import * as pty from 'node-pty'; import { assert } from 'chai'; import { Terminal } from './Terminal'; import { IViewport } from './Types'; -import { CellData, WHITESPACE_CELL_CHAR } from './BufferLine'; +import { CellData, WHITESPACE_CELL_CHAR } from './core/buffer/BufferLine'; class TestTerminal extends Terminal { innerWrite(): void { this._innerWrite(); } diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 06a02d68d..9b5fa9c8b 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -6,7 +6,7 @@ import { assert, expect } from 'chai'; import { Terminal } from './Terminal'; import { MockViewport, MockCompositionHelper, MockRenderer } from './TestUtils.test'; -import { CellData, DEFAULT_ATTR_DATA } from './BufferLine'; +import { CellData, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; const INIT_COLS = 80; const INIT_ROWS = 24; diff --git a/src/Terminal.ts b/src/Terminal.ts index 0ff21b88a..6da60458e 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -51,7 +51,7 @@ import { evaluateKeyboardEvent } from './core/input/Keyboard'; import { KeyboardResultType, ICharset, IBufferLine, IAttributeData } from './core/Types'; import { clone } from './common/Clone'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; -import { Attributes, DEFAULT_ATTR_DATA } from './BufferLine'; +import { Attributes, DEFAULT_ATTR_DATA } from './core/buffer/BufferLine'; import { applyWindowsMode } from './WindowsMode'; // Let it work inside Node.js for automated testing purposes. diff --git a/src/TestUtils.test.ts b/src/TestUtils.test.ts index 8170681d8..1d5008c8b 100644 --- a/src/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -11,7 +11,7 @@ import { Buffer } from './Buffer'; import * as Browser from './common/Platform'; import { ITheme, IDisposable, IMarker, IEvent } from 'xterm'; import { Terminal } from './Terminal'; -import { AttributeData } from './BufferLine'; +import { AttributeData } from './core/buffer/BufferLine'; export class TestTerminal extends Terminal { writeSync(data: string): void { diff --git a/src/WindowsMode.ts b/src/WindowsMode.ts index 1e58c50ce..d7b4bcaec 100644 --- a/src/WindowsMode.ts +++ b/src/WindowsMode.ts @@ -5,7 +5,7 @@ import { IDisposable } from 'xterm'; import { ITerminal } from './Types'; -import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './BufferLine'; +import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './core/buffer/BufferLine'; export function applyWindowsMode(terminal: ITerminal): IDisposable { // Winpty does not support wraparound mode which means that lines will never diff --git a/src/BufferLine.ts b/src/core/buffer/BufferLine.ts similarity index 97% rename from src/BufferLine.ts rename to src/core/buffer/BufferLine.ts index 39b6116d2..154cc5984 100644 --- a/src/BufferLine.ts +++ b/src/core/buffer/BufferLine.ts @@ -2,9 +2,9 @@ * Copyright (c) 2018 The xterm.js authors. All rights reserved. * @license MIT */ -import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from './core/Types'; -import { stringFromCodePoint } from './core/input/TextDecoder'; -import { DEFAULT_COLOR } from './common/Types'; +import { CharData, IBufferLine, ICellData, IColorRGB, IAttributeData } from '../Types'; +import { stringFromCodePoint } from '../input/TextDecoder'; +import { DEFAULT_COLOR } from '../../common/Types'; export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); @@ -325,17 +325,15 @@ export class CellData extends AttributeData implements ICellData { * memory allocs / GC pressure can be greatly reduced by reusing the CellData object. */ export class BufferLine implements IBufferLine { - protected _data: Uint32Array | null = null; + protected _data: Uint32Array; protected _combined: {[index: number]: string} = {}; public length: number; constructor(cols: number, fillCellData?: ICellData, public isWrapped: boolean = false) { - if (cols) { - this._data = new Uint32Array(cols * CELL_SIZE); - const cell = fillCellData || CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); - for (let i = 0; i < cols; ++i) { - this.setCell(i, cell); - } + this._data = new Uint32Array(cols * CELL_SIZE); + const cell = fillCellData || CellData.fromCharData([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); + for (let i = 0; i < cols; ++i) { + this.setCell(i, cell); } this.length = cols; } @@ -573,7 +571,7 @@ export class BufferLine implements IBufferLine { } } } else { - this._data = null; + this._data = new Uint32Array(0); this._combined = {}; } } diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 63846155b..ce50a6511 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -10,7 +10,7 @@ import { DEFAULT_COLOR } from '../common/Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, IGlyphIdentifier } from './atlas/Types'; import BaseCharAtlas from './atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; -import { CellData, AttributeData, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../BufferLine'; +import { CellData, AttributeData, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from '../core/buffer/BufferLine'; import { JoinedCellData } from './CharacterJoinerRegistry'; export abstract class BaseRenderLayer implements IRenderLayer { diff --git a/src/renderer/CharacterJoinerRegistry.test.ts b/src/renderer/CharacterJoinerRegistry.test.ts index 590d6a5f5..948985a46 100644 --- a/src/renderer/CharacterJoinerRegistry.test.ts +++ b/src/renderer/CharacterJoinerRegistry.test.ts @@ -10,7 +10,7 @@ import { CircularList } from '../common/CircularList'; import { ICharacterJoinerRegistry } from './Types'; import { CharacterJoinerRegistry } from './CharacterJoinerRegistry'; -import { BufferLine, CellData } from '../BufferLine'; +import { BufferLine, CellData } from '../core/buffer/BufferLine'; import { IBufferLine } from '../core/Types'; describe('CharacterJoinerRegistry', () => { diff --git a/src/renderer/CharacterJoinerRegistry.ts b/src/renderer/CharacterJoinerRegistry.ts index 33cd89360..3302c3121 100644 --- a/src/renderer/CharacterJoinerRegistry.ts +++ b/src/renderer/CharacterJoinerRegistry.ts @@ -6,7 +6,7 @@ import { ITerminal } from '../Types'; import { IBufferLine, ICellData, CharData } from '../core/Types'; import { ICharacterJoinerRegistry, ICharacterJoiner } from './Types'; -import { CellData, Content, AttributeData, WHITESPACE_CELL_CHAR } from '../BufferLine'; +import { CellData, Content, AttributeData, WHITESPACE_CELL_CHAR } from '../core/buffer/BufferLine'; export class JoinedCellData extends AttributeData implements ICellData { private _width: number; diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 72aaa4471..3e8af02de 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -7,7 +7,7 @@ import { IColorSet, IRenderDimensions } from './Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { ITerminal } from '../Types'; import { ICellData } from '../core/Types'; -import { CellData } from '../BufferLine'; +import { CellData } from '../core/buffer/BufferLine'; interface ICursorState { x: number; diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 90c7e2677..8be5665c4 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -8,7 +8,7 @@ import { ITerminal } from '../Types'; import { CharData, ICellData } from '../core/Types'; import { GridCache } from './GridCache'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { CellData, AttributeData, Content, NULL_CELL_CODE } from '../BufferLine'; +import { CellData, AttributeData, Content, NULL_CELL_CODE } from '../core/buffer/BufferLine'; import { JoinedCellData } from './CharacterJoinerRegistry'; /** diff --git a/src/renderer/dom/DomRendererRowFactory.test.ts b/src/renderer/dom/DomRendererRowFactory.test.ts index f009407d4..b25305952 100644 --- a/src/renderer/dom/DomRendererRowFactory.test.ts +++ b/src/renderer/dom/DomRendererRowFactory.test.ts @@ -6,7 +6,7 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; import { DomRendererRowFactory } from './DomRendererRowFactory'; -import { BufferLine, CellData, FgFlags, BgFlags, Attributes, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, DEFAULT_ATTR_DATA } from '../../BufferLine'; +import { BufferLine, CellData, FgFlags, BgFlags, Attributes, NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, DEFAULT_ATTR_DATA } from '../../core/buffer/BufferLine'; import { ITerminalOptions } from '../../Types'; import { IBufferLine } from '../../core/Types'; diff --git a/src/renderer/dom/DomRendererRowFactory.ts b/src/renderer/dom/DomRendererRowFactory.ts index 481d096ef..85ef586e2 100644 --- a/src/renderer/dom/DomRendererRowFactory.ts +++ b/src/renderer/dom/DomRendererRowFactory.ts @@ -6,7 +6,7 @@ import { ITerminalOptions } from '../../Types'; import { IBufferLine } from '../../core/Types'; import { INVERTED_DEFAULT_COLOR } from '../atlas/Types'; -import { CellData, AttributeData, NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../BufferLine'; +import { CellData, AttributeData, NULL_CELL_CODE, WHITESPACE_CELL_CHAR } from '../../core/buffer/BufferLine'; export const BOLD_CLASS = 'xterm-bold'; export const DIM_CLASS = 'xterm-dim'; From 59aec69379c67d114e4d1bdf0f5e28e00cba72b3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 9 May 2019 22:19:33 -0700 Subject: [PATCH 33/37] Add BufferLine into core and strict null check --- src/{ => core/buffer}/BufferLine.test.ts | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) rename src/{ => core/buffer}/BufferLine.test.ts (95%) diff --git a/src/BufferLine.test.ts b/src/core/buffer/BufferLine.test.ts similarity index 95% rename from src/BufferLine.test.ts rename to src/core/buffer/BufferLine.test.ts index 87a4e6316..c42b372e2 100644 --- a/src/BufferLine.test.ts +++ b/src/core/buffer/BufferLine.test.ts @@ -3,8 +3,8 @@ * @license MIT */ import * as chai from 'chai'; -import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './core/buffer/BufferLine'; -import { CharData, IBufferLine } from './core/Types'; +import { BufferLine, CellData, Content, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, DEFAULT_ATTR } from './BufferLine'; +import { CharData, IBufferLine } from '../Types'; class TestBufferLine extends BufferLine { public get combined(): {[index: number]: string} { @@ -55,7 +55,7 @@ describe('BufferLine', function(): void { chai.expect(line.length).equals(10); chai.expect(line.loadCell(0, new CellData()).getAsCharData()).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); chai.expect(line.isWrapped).equals(false); - line = new TestBufferLine(10, null, true); + line = new TestBufferLine(10, undefined, true); chai.expect(line.length).equals(10); chai.expect(line.loadCell(0, new CellData()).getAsCharData()).eql([0, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]); chai.expect(line.isWrapped).equals(true); @@ -125,7 +125,7 @@ describe('BufferLine', function(): void { ]); }); it('clone', function(): void { - const line = new TestBufferLine(5, null, true); + const line = new TestBufferLine(5, undefined, true); line.setCell(0, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); line.setCell(1, CellData.fromCharData([2, 'b', 0, 'b'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([3, 'c', 0, 'c'.charCodeAt(0)])); @@ -165,27 +165,27 @@ describe('BufferLine', function(): void { it('enlarge(false)', function(): void { const line = new TestBufferLine(5, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)]), false); line.resize(10, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); - chai.expect(line.toArray()).eql(Array(10).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + chai.expect(line.toArray()).eql((Array(10) as any).fill([1, 'a', 0, 'a'.charCodeAt(0)])); }); it('enlarge(true)', function(): void { const line = new TestBufferLine(5, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)]), false); line.resize(10, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); - chai.expect(line.toArray()).eql(Array(10).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + chai.expect(line.toArray()).eql((Array(10) as any).fill([1, 'a', 0, 'a'.charCodeAt(0)])); }); it('shrink(true) - should apply new size', function(): void { const line = new TestBufferLine(10, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)]), false); line.resize(5, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); - chai.expect(line.toArray()).eql(Array(5).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + chai.expect(line.toArray()).eql((Array(5) as any).fill([1, 'a', 0, 'a'.charCodeAt(0)])); }); it('shrink to 0 length', function(): void { const line = new TestBufferLine(10, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)]), false); line.resize(0, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); - chai.expect(line.toArray()).eql(Array(0).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + chai.expect(line.toArray()).eql((Array(0) as any).fill([1, 'a', 0, 'a'.charCodeAt(0)])); }); it('should remove combining data on replaced cells after shrinking then enlarging', () => { const line = new TestBufferLine(10, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)]), false); - line.set(2, [ null, '😁', 1, '😁'.charCodeAt(0) ]); - line.set(9, [ null, '😁', 1, '😁'.charCodeAt(0) ]); + line.set(2, [ 0, '😁', 1, '😁'.charCodeAt(0) ]); + line.set(9, [ 0, '😁', 1, '😁'.charCodeAt(0) ]); chai.expect(line.translateToString()).eql('aa😁aaaaaa😁'); chai.expect(Object.keys(line.combined).length).eql(2); line.resize(5, CellData.fromCharData([1, 'a', 0, 'a'.charCodeAt(0)])); @@ -222,7 +222,7 @@ describe('BufferLine', function(): void { const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); - line.setCell(3, CellData.fromCharData([0, '', 0, undefined])); + line.setCell(3, CellData.fromCharData([0, '', 0, 0])); chai.expect(line.getTrimmedLength()).equal(4); // also counts null cell after fullwidth }); }); @@ -282,11 +282,11 @@ describe('BufferLine', function(): void { const line = new TestBufferLine(10, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); line.setCell(0, CellData.fromCharData([1, 'a', 1, 'a'.charCodeAt(0)])); line.setCell(2, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); - line.setCell(3, CellData.fromCharData([0, '', 0, undefined])); + line.setCell(3, CellData.fromCharData([0, '', 0, 0])); line.setCell(5, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); - line.setCell(6, CellData.fromCharData([0, '', 0, undefined])); + line.setCell(6, CellData.fromCharData([0, '', 0, 0])); line.setCell(7, CellData.fromCharData([1, '1', 2, '1'.charCodeAt(0)])); - line.setCell(8, CellData.fromCharData([0, '', 0, undefined])); + line.setCell(8, CellData.fromCharData([0, '', 0, 0])); chai.expect(line.translateToString(false)).equal('a 1 11 '); chai.expect(line.translateToString(true)).equal('a 1 11'); chai.expect(line.translateToString(false, 0, 7)).equal('a 1 1'); From d735196a305bbce8ae05404d747fc4642f1439b9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 May 2019 07:39:42 -0700 Subject: [PATCH 34/37] Make sure beta builds are always on patch version 0 --- bin/publish.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/publish.js b/bin/publish.js index 3b13d6a5a..9df2e982d 100644 --- a/bin/publish.js +++ b/bin/publish.js @@ -39,7 +39,7 @@ function getNextBetaVersion() { } const tag = 'beta'; const stableVersion = packageJson.version.split('.'); - const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.${stableVersion[2]}`; + const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.0`; const publishedVersions = getPublishedVersions(nextStableVersion, tag); if (publishedVersions.length === 0) { return `${nextStableVersion}-${tag}1`; @@ -54,7 +54,7 @@ function getNextBetaVersion() { } function getPublishedVersions(version, tag) { - const versionsProcess = cp.spawnSync('npm', ['view', 'xterm', 'versions', '--json']); + const versionsProcess = cp.spawnSync('npm', ['view', packageJson.name, 'versions', '--json']); const versionsJson = JSON.parse(versionsProcess.stdout); if (tag) { return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`))); From b658baf921d1f8e4e26af868744c43082684d825 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 May 2019 16:26:48 -0700 Subject: [PATCH 35/37] Add typings for windowsMode --- fixtures/typings-test/typings-test.ts | 8 +++++--- typings/xterm.d.ts | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fixtures/typings-test/typings-test.ts b/fixtures/typings-test/typings-test.ts index 87d911c2a..65c478c61 100644 --- a/fixtures/typings-test/typings-test.ts +++ b/fixtures/typings-test/typings-test.ts @@ -21,7 +21,7 @@ namespace constructor { 'disableStdin': false, 'rows': 1, 'scrollback': 10, - 'tabStopWidth': 2, + 'tabStopWidth': 2 }); } } @@ -119,8 +119,8 @@ namespace methods_core { const t: Terminal = new Terminal(); t.attachCustomKeyEventHandler((e: KeyboardEvent) => true); t.attachCustomKeyEventHandler((e: KeyboardEvent) => false); - const d1: IDisposable = t.addCsiHandler("x", - (params: number[], collect: string): boolean => params[0]===1); + const d1: IDisposable = t.addCsiHandler('x', + (params: number[], collect: string): boolean => params[0] === 1); d1.dispose(); const d2: IDisposable = t.addOscHandler(199, (data: string): boolean => true); @@ -155,6 +155,7 @@ namespace methods_core { const r25: string = t.getOption('fontWeightBold'); const r26: boolean = t.getOption('allowTransparency'); const r27: boolean = t.getOption('rightClickSelectsWord'); + const r28: boolean = t.getOption('windowsMode'); } { const t: Terminal = new Terminal(); @@ -177,6 +178,7 @@ namespace methods_core { t.setOption('useFlowControl', true); t.setOption('allowTransparency', true); t.setOption('visualBell', true); + t.setOption('windowsMode', true); t.setOption('colors', ['a', 'b']); t.setOption('letterSpacing', 1); t.setOption('cols', 1); diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 9f1fbe62d..d610d6846 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -747,7 +747,7 @@ declare module 'xterm' { * Retrieves an option's value from the terminal. * @param key The option key. */ - getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; + getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode'): boolean; /** * Retrieves an option's value from the terminal. * @param key The option key. @@ -798,7 +798,7 @@ declare module 'xterm' { * @param key The option key. * @param value The option value. */ - setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'rightClickSelectsWord' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void; + setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'rightClickSelectsWord' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode', value: boolean): void; /** * Sets an option on the terminal. * @param key The option key. From c04ebe974fa6d584c1c0c7af524ace204a706b53 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 May 2019 20:51:18 -0700 Subject: [PATCH 36/37] Fix bad import from lib Related #1996 --- src/Buffer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Buffer.ts b/src/Buffer.ts index c1c08c85a..c42b97269 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -10,7 +10,7 @@ import { BufferLine, CellData, AttributeData } from './BufferLine'; import { reflowLargerApplyNewLayout, reflowLargerCreateNewLayout, reflowLargerGetLinesToRemove, reflowSmallerGetNewLineLengths, getWrappedLineTrimmedLength } from './BufferReflow'; import { DEFAULT_COLOR } from './renderer/atlas/Types'; import { EventEmitter2, IEvent } from './common/EventEmitter2'; -import { Disposable } from '../lib/common/Lifecycle'; +import { Disposable } from './common/Lifecycle'; export const DEFAULT_ATTR = (0 << 18) | (DEFAULT_COLOR << 9) | (256 << 0); From 23bdb2a6c20d1df074ad54a92550ef4862b6669f Mon Sep 17 00:00:00 2001 From: Nick Mitchell Date: Sat, 11 May 2019 00:59:59 -0400 Subject: [PATCH 37/37] fix: don't use Math.floor in DomRenderer charWidth computation Fixes #2063 --- src/renderer/dom/DomRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/dom/DomRenderer.ts b/src/renderer/dom/DomRenderer.ts index 01d5c7dce..c192034c0 100644 --- a/src/renderer/dom/DomRenderer.ts +++ b/src/renderer/dom/DomRenderer.ts @@ -101,7 +101,7 @@ export class DomRenderer extends Disposable implements IRenderer { } private _updateDimensions(): void { - this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio); + this.dimensions.scaledCharWidth = this._terminal.charMeasure.width * window.devicePixelRatio; this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio); this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing); this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);