From 5ef399df6f6100b71578ec81c700d4158424cbb2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 16 May 2018 13:44:46 -0700 Subject: [PATCH 01/13] Add VSTS build badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f7eb6bd..874578d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [![xterm.js logo](logo-full.png)](https://xtermjs.org) -[![xterm.js build status](https://api.travis-ci.org/xtermjs/xterm.js.svg)](https://travis-ci.org/xtermjs/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/xterm/badge?style=rounded)](https://www.jsdelivr.com/package/npm/xterm) +[![Travis CI build status](https://api.travis-ci.org/xtermjs/xterm.js.svg)](https://travis-ci.org/xtermjs/xterm.js) [![VSTS Build status](https://xtermjs.visualstudio.com/_apis/public/build/definitions/3e323cf7-5760-460d-af64-ee5675baf366/1/badge)](https://xtermjs.visualstudio.com/xterm.js/_build/index?definitionId=1) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/xterm/badge?style=rounded)](https://www.jsdelivr.com/package/npm/xterm) Xterm.js is a terminal front-end component written in JavaScript that works in the browser. From 7db0b181bc96e2ba106fdbbd443dd133a6e74a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E9=9B=AA=E7=8F=82?= Date: Tue, 29 May 2018 13:03:48 +0800 Subject: [PATCH 02/13] add a project to real-world uses list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6ba671a2..39c80a46 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ computational environment for Jupyter, supporting interactive data science and s - [**Fluent Terminal**](https://github.com/felixse/FluentTerminal): A terminal emulator based on UWP and web technologies. - [**Hyper**](https://hyper.is): A terminal built on web technologies - [**Diag**](https://diag.ai): A better way to troubleshoot problems faster. Capture, share and reapply troubleshooting knowledge so you can focus on solving problems that matter. +- [**GoTTY**](https://github.com/yudai/gotty): A simple command line tool that shares your terminal as a web application based on xterm.js. Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list. From 8989a09853b7eb7be540e425b847cdb7560efde5 Mon Sep 17 00:00:00 2001 From: Lukas Geiger Date: Wed, 30 May 2018 19:47:28 +0200 Subject: [PATCH 03/13] Prefer const vs let for variables that are only declared once Requires that variable declarations use `const` instead of `let` and `var` if possible. This is mostly for code readability, performance wins are debatable. --- src/CharWidth.ts | 2 +- src/EscapeSequenceParser.test.ts | 108 +++++++++++++-------------- src/EscapeSequenceParser.ts | 18 ++--- src/EventEmitter.ts | 4 +- src/InputHandler.test.ts | 12 +-- src/InputHandler.ts | 14 ++-- src/Linkifier.test.ts | 2 +- src/Linkifier.ts | 4 +- src/SelectionManager.test.ts | 2 +- src/SelectionManager.ts | 4 +- src/Terminal.integration.ts | 26 +++---- src/Terminal.test.ts | 62 +++++++-------- src/Terminal.ts | 6 +- src/Viewport.ts | 2 +- src/addons/attach/attach.ts | 2 +- src/addons/webLinks/webLinks.test.ts | 4 +- src/handlers/AltClickHandler.ts | 20 ++--- src/handlers/Clipboard.ts | 2 +- src/renderer/ColorManager.test.ts | 2 +- src/renderer/ColorManager.ts | 4 +- src/utils/CircularList.ts | 2 +- tslint.json | 3 +- 22 files changed, 153 insertions(+), 152 deletions(-) diff --git a/src/CharWidth.ts b/src/CharWidth.ts index 90673b2b..2165d9ba 100644 --- a/src/CharWidth.ts +++ b/src/CharWidth.ts @@ -161,7 +161,7 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu if (num < 127) { return 1; } - let t = table || init_table(); + const t = table || init_table(); if (num < 65536) { return t[num >> 4] >> ((num & 15) << 1) & 3; } diff --git a/src/EscapeSequenceParser.test.ts b/src/EscapeSequenceParser.test.ts index 2d85c466..d9ea64ce 100644 --- a/src/EscapeSequenceParser.test.ts +++ b/src/EscapeSequenceParser.test.ts @@ -9,7 +9,7 @@ import * as chai from 'chai'; function r(a: number, b: number): string[] { let c = b - a; - let arr = new Array(c); + const arr = new Array(c); while (c--) { arr[c] = String.fromCharCode(--b); } @@ -42,7 +42,7 @@ class TestEscapeSequenceParser extends EscapeSequenceParser { } // test object to collect parser actions and compare them with expected values -let testTerminal: any = { +const testTerminal: any = { calls: [], clear: function (): void { this.calls = []; @@ -89,7 +89,7 @@ class DcsTest implements IDcsHandler { } } -let states: number[] = [ +const states: number[] = [ ParserState.GROUND, ParserState.ESCAPE, ParserState.ESCAPE_INTERMEDIATE, @@ -108,7 +108,7 @@ let states: number[] = [ let state: any; // parser with Uint8Array based transition table -let parserUint = new TestEscapeSequenceParser(VT500_TRANSITION_TABLE); +const parserUint = new TestEscapeSequenceParser(VT500_TRANSITION_TABLE); parserUint.setPrintHandler(testTerminal.print.bind(testTerminal)); parserUint.setCsiHandlerFallback((collect: string, params: number[], flag: number) => { testTerminal.actionCSI(collect, params, String.fromCharCode(flag)); @@ -126,14 +126,14 @@ parserUint.setOscHandlerFallback((identifier: number, data: string) => { parserUint.setDcsHandlerFallback(new DcsTest()); // array based transition table -let VT500_TRANSITION_TABLE_ARRAY = new TransitionTable(VT500_TRANSITION_TABLE.table.length); +const VT500_TRANSITION_TABLE_ARRAY = new TransitionTable(VT500_TRANSITION_TABLE.table.length); VT500_TRANSITION_TABLE_ARRAY.table = new Array(VT500_TRANSITION_TABLE.table.length); for (let i = 0; i < VT500_TRANSITION_TABLE.table.length; ++i) { VT500_TRANSITION_TABLE_ARRAY.table[i] = VT500_TRANSITION_TABLE.table[i]; } // parser with array based transition table -let parserArray = new TestEscapeSequenceParser(VT500_TRANSITION_TABLE_ARRAY); +const parserArray = new TestEscapeSequenceParser(VT500_TRANSITION_TABLE_ARRAY); parserArray.setPrintHandler(testTerminal.print.bind(testTerminal)); parserArray.setCsiHandlerFallback((collect: string, params: number[], flag: number) => { testTerminal.actionCSI(collect, params, String.fromCharCode(flag)); @@ -172,7 +172,7 @@ describe('EscapeSequenceParser', function (): void { chai.expect(p.transitions).equal(VT500_TRANSITION_TABLE); p = new EscapeSequenceParser(VT500_TRANSITION_TABLE); chai.expect(p.transitions).equal(VT500_TRANSITION_TABLE); - let tansitions: TransitionTable = new TransitionTable(10); + const tansitions: TransitionTable = new TransitionTable(10); p = new EscapeSequenceParser(tansitions); chai.expect(p.transitions).equal(tansitions); }); @@ -205,7 +205,7 @@ describe('EscapeSequenceParser', function (): void { it('state GROUND execute action', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -220,7 +220,7 @@ describe('EscapeSequenceParser', function (): void { it('state GROUND print action', function (): void { parser.reset(); testTerminal.clear(); - let printables = r(0x20, 0x7f); // NOTE: DEL excluded + const printables = r(0x20, 0x7f); // NOTE: DEL excluded for (let i = 0; i < printables.length; ++i) { parser.currentState = ParserState.GROUND; parser.parse(printables[i]); @@ -231,13 +231,13 @@ describe('EscapeSequenceParser', function (): void { } }); it('trans ANYWHERE --> GROUND with actions', function (): void { - let exes = [ + const exes = [ '\x18', '\x1a', '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', '\x99', '\x9a' ]; - let exceptions = { + const exceptions = { 8: { '\x18': [], '\x1a': [] } // simply abort osc state }; parser.reset(); @@ -276,7 +276,7 @@ describe('EscapeSequenceParser', function (): void { it('state ESCAPE execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -301,7 +301,7 @@ describe('EscapeSequenceParser', function (): void { it('trans ESCAPE --> GROUND with ecs_dispatch action', function (): void { parser.reset(); testTerminal.clear(); - let dispatches = r(0x30, 0x50); + const dispatches = r(0x30, 0x50); dispatches.concat(r(0x51, 0x58)); dispatches.concat(['\x59', '\x5a', '\x5c']); dispatches.concat(r(0x60, 0x7f)); @@ -316,7 +316,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans ESCAPE --> ESCAPE_INTERMEDIATE with collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.ESCAPE; parser.parse(collect[i]); @@ -328,7 +328,7 @@ describe('EscapeSequenceParser', function (): void { it('state ESCAPE_INTERMEDIATE execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -352,7 +352,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state ESCAPE_INTERMEDIATE collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.ESCAPE_INTERMEDIATE; parser.parse(collect[i]); @@ -364,7 +364,7 @@ describe('EscapeSequenceParser', function (): void { it('trans ESCAPE_INTERMEDIATE --> GROUND with esc_dispatch action', function (): void { parser.reset(); testTerminal.clear(); - let collect = r(0x30, 0x7f); + const collect = r(0x30, 0x7f); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.ESCAPE_INTERMEDIATE; parser.parse(collect[i]); @@ -404,7 +404,7 @@ describe('EscapeSequenceParser', function (): void { it('state CSI_ENTRY execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -428,7 +428,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_ENTRY --> GROUND with csi_dispatch action', function (): void { parser.reset(); - let dispatches = r(0x40, 0x7f); + const dispatches = r(0x40, 0x7f); for (let i = 0; i < dispatches.length; ++i) { parser.currentState = ParserState.CSI_ENTRY; parser.parse(dispatches[i]); @@ -440,8 +440,8 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_ENTRY --> CSI_PARAM with param/collect actions', function (): void { parser.reset(); - let params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; - let collect = ['\x3c', '\x3d', '\x3e', '\x3f']; + const params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; + const collect = ['\x3c', '\x3d', '\x3e', '\x3f']; for (let i = 0; i < params.length; ++i) { parser.currentState = ParserState.CSI_ENTRY; parser.parse(params[i]); @@ -465,7 +465,7 @@ describe('EscapeSequenceParser', function (): void { it('state CSI_PARAM execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -479,7 +479,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state CSI_PARAM param action', function (): void { parser.reset(); - let params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; + const params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; for (let i = 0; i < params.length; ++i) { parser.currentState = ParserState.CSI_PARAM; parser.parse(params[i]); @@ -505,7 +505,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_PARAM --> GROUND with csi_dispatch action', function (): void { parser.reset(); - let dispatches = r(0x40, 0x7f); + const dispatches = r(0x40, 0x7f); for (let i = 0; i < dispatches.length; ++i) { parser.currentState = ParserState.CSI_PARAM; parser.params = [0, 1]; @@ -518,7 +518,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_ENTRY --> CSI_INTERMEDIATE with collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.CSI_ENTRY; parser.parse(collect[i]); @@ -529,7 +529,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_PARAM --> CSI_INTERMEDIATE with collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.CSI_PARAM; parser.parse(collect[i]); @@ -541,7 +541,7 @@ describe('EscapeSequenceParser', function (): void { it('state CSI_INTERMEDIATE execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -555,7 +555,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state CSI_INTERMEDIATE collect', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.CSI_INTERMEDIATE; parser.parse(collect[i]); @@ -576,7 +576,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_INTERMEDIATE --> GROUND with csi_dispatch action', function (): void { parser.reset(); - let dispatches = r(0x40, 0x7f); + const dispatches = r(0x40, 0x7f); for (let i = 0; i < dispatches.length; ++i) { parser.currentState = ParserState.CSI_INTERMEDIATE; parser.params = [0, 1]; @@ -596,7 +596,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_PARAM --> CSI_IGNORE', function (): void { parser.reset(); - let chars = ['\x3a', '\x3c', '\x3d', '\x3e', '\x3f']; + const chars = ['\x3a', '\x3c', '\x3d', '\x3e', '\x3f']; for (let i = 0; i < chars.length; ++i) { parser.currentState = ParserState.CSI_PARAM; parser.parse('\x3b' + chars[i]); @@ -607,7 +607,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_INTERMEDIATE --> CSI_IGNORE', function (): void { parser.reset(); - let chars = r(0x30, 0x40); + const chars = r(0x30, 0x40); for (let i = 0; i < chars.length; ++i) { parser.currentState = ParserState.CSI_INTERMEDIATE; parser.parse(chars[i]); @@ -619,7 +619,7 @@ describe('EscapeSequenceParser', function (): void { it('state CSI_IGNORE execute rules', function (): void { parser.reset(); testTerminal.clear(); - let exes = r(0x00, 0x18); + const exes = r(0x00, 0x18); exes.concat(['\x19']); exes.concat(r(0x1c, 0x20)); for (let i = 0; i < exes.length; ++i) { @@ -634,7 +634,7 @@ describe('EscapeSequenceParser', function (): void { it('state CSI_IGNORE ignore', function (): void { parser.reset(); testTerminal.clear(); - let ignored = r(0x20, 0x40); + const ignored = r(0x20, 0x40); ignored.concat(['\x7f']); for (let i = 0; i < ignored.length; ++i) { parser.currentState = ParserState.CSI_IGNORE; @@ -647,7 +647,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans CSI_IGNORE --> GROUND', function (): void { parser.reset(); - let dispatches = r(0x40, 0x7f); + const dispatches = r(0x40, 0x7f); for (let i = 0; i < dispatches.length; ++i) { parser.currentState = ParserState.CSI_IGNORE; parser.params = [0, 1]; @@ -680,7 +680,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state SOS_PM_APC_STRING ignore rules', function (): void { parser.reset(); - let ignored = r(0x00, 0x18); + const ignored = r(0x00, 0x18); ignored.concat(['\x19']); ignored.concat(r(0x1c, 0x20)); ignored.concat(r(0x20, 0x80)); @@ -707,7 +707,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state OSC_STRING ignore rules', function (): void { parser.reset(); - let ignored = [ + const ignored = [ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', /*'\x07',*/ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x19', '\x1c', '\x1d', '\x1e', '\x1f']; @@ -721,7 +721,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state OSC_STRING put action', function (): void { parser.reset(); - let puts = r(0x20, 0x80); + const puts = r(0x20, 0x80); for (let i = 0; i < puts.length; ++i) { parser.currentState = ParserState.OSC_STRING; parser.parse(puts[i]); @@ -746,7 +746,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_ENTRY ignore rules', function (): void { parser.reset(); - let ignored = [ + const ignored = [ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x19', '\x1c', '\x1d', '\x1e', '\x1f', '\x7f']; @@ -759,8 +759,8 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_ENTRY --> DCS_PARAM with param/collect actions', function (): void { parser.reset(); - let params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; - let collect = ['\x3c', '\x3d', '\x3e', '\x3f']; + const params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; + const collect = ['\x3c', '\x3d', '\x3e', '\x3f']; for (let i = 0; i < params.length; ++i) { parser.currentState = ParserState.DCS_ENTRY; parser.parse(params[i]); @@ -783,7 +783,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_PARAM ignore rules', function (): void { parser.reset(); - let ignored = [ + const ignored = [ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x19', '\x1c', '\x1d', '\x1e', '\x1f', '\x7f']; @@ -796,7 +796,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_PARAM param action', function (): void { parser.reset(); - let params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; + const params = ['\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39']; for (let i = 0; i < params.length; ++i) { parser.currentState = ParserState.DCS_PARAM; parser.parse(params[i]); @@ -819,7 +819,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans DCS_PARAM --> DCS_IGNORE', function (): void { parser.reset(); - let chars = ['\x3a', '\x3c', '\x3d', '\x3e', '\x3f']; + const chars = ['\x3a', '\x3c', '\x3d', '\x3e', '\x3f']; for (let i = 0; i < chars.length; ++i) { parser.currentState = ParserState.DCS_PARAM; parser.parse('\x3b' + chars[i]); @@ -830,7 +830,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans DCS_INTERMEDIATE --> DCS_IGNORE', function (): void { parser.reset(); - let chars = r(0x30, 0x40); + const chars = r(0x30, 0x40); for (let i = 0; i < chars.length; ++i) { parser.currentState = ParserState.DCS_INTERMEDIATE; parser.parse(chars[i]); @@ -840,7 +840,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_IGNORE ignore rules', function (): void { parser.reset(); - let ignored = [ + const ignored = [ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x19', '\x1c', '\x1d', '\x1e', '\x1f', '\x7f']; @@ -854,7 +854,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans DCS_ENTRY --> DCS_INTERMEDIATE with collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_ENTRY; parser.parse(collect[i]); @@ -865,7 +865,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans DCS_PARAM --> DCS_INTERMEDIATE with collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_PARAM; parser.parse(collect[i]); @@ -876,7 +876,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_INTERMEDIATE ignore rules', function (): void { parser.reset(); - let ignored = [ + const ignored = [ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x19', '\x1c', '\x1d', '\x1e', '\x1f', '\x7f']; @@ -889,7 +889,7 @@ describe('EscapeSequenceParser', function (): void { }); it('state DCS_INTERMEDIATE collect action', function (): void { parser.reset(); - let collect = r(0x20, 0x30); + const collect = r(0x20, 0x30); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_INTERMEDIATE; parser.parse(collect[i]); @@ -900,7 +900,7 @@ describe('EscapeSequenceParser', function (): void { }); it('trans DCS_INTERMEDIATE --> DCS_IGNORE', function (): void { parser.reset(); - let chars = r(0x30, 0x40); + const chars = r(0x30, 0x40); for (let i = 0; i < chars.length; ++i) { parser.currentState = ParserState.DCS_INTERMEDIATE; parser.parse('\x20' + chars[i]); @@ -912,7 +912,7 @@ describe('EscapeSequenceParser', function (): void { it('trans DCS_ENTRY --> DCS_PASSTHROUGH with hook', function (): void { parser.reset(); testTerminal.clear(); - let collect = r(0x40, 0x7f); + const collect = r(0x40, 0x7f); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_ENTRY; parser.parse(collect[i]); @@ -925,7 +925,7 @@ describe('EscapeSequenceParser', function (): void { it('trans DCS_PARAM --> DCS_PASSTHROUGH with hook', function (): void { parser.reset(); testTerminal.clear(); - let collect = r(0x40, 0x7f); + const collect = r(0x40, 0x7f); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_PARAM; parser.parse(collect[i]); @@ -938,7 +938,7 @@ describe('EscapeSequenceParser', function (): void { it('trans DCS_INTERMEDIATE --> DCS_PASSTHROUGH with hook', function (): void { parser.reset(); testTerminal.clear(); - let collect = r(0x40, 0x7f); + const collect = r(0x40, 0x7f); for (let i = 0; i < collect.length; ++i) { parser.currentState = ParserState.DCS_INTERMEDIATE; parser.parse(collect[i]); @@ -951,7 +951,7 @@ describe('EscapeSequenceParser', function (): void { it('state DCS_PASSTHROUGH put action', function (): void { parser.reset(); testTerminal.clear(); - let puts = r(0x00, 0x18); + const puts = r(0x00, 0x18); puts.concat(['\x19']); puts.concat(r(0x1c, 0x20)); puts.concat(r(0x20, 0x7f)); diff --git a/src/EscapeSequenceParser.ts b/src/EscapeSequenceParser.ts index dea87f8d..71a06138 100644 --- a/src/EscapeSequenceParser.ts +++ b/src/EscapeSequenceParser.ts @@ -12,7 +12,7 @@ import { ParserState, ParserAction, IParsingState, IDcsHandler, IEscapeSequenceP */ function r(low: number, high: number): number[] { let c = high - low; - let arr = new Array(c); + const arr = new Array(c); while (c--) { arr[c] = --high; } @@ -62,8 +62,8 @@ export class TransitionTable { /** * Default definitions for the VT500_TRANSITION_TABLE. */ -let PRINTABLES = r(0x20, 0x7f); -let EXECUTABLES = r(0x00, 0x18); +const PRINTABLES = r(0x20, 0x7f); +const EXECUTABLES = r(0x00, 0x18); EXECUTABLES.push(0x19); EXECUTABLES.concat(r(0x1c, 0x20)); const DEFAULT_TRANSITION = ParserAction.ERROR << 4 | ParserState.GROUND; @@ -73,9 +73,9 @@ const DEFAULT_TRANSITION = ParserAction.ERROR << 4 | ParserState.GROUND; * Taken from https://vt100.net/emu/dec_ansi_parser. */ export const VT500_TRANSITION_TABLE = (function (): TransitionTable { - let table: TransitionTable = new TransitionTable(4095); + const table: TransitionTable = new TransitionTable(4095); - let states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1); + const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1); let state: any; // table with default transition [any] --> DEFAULT_TRANSITION @@ -421,7 +421,7 @@ export class EscapeSequenceParser implements IEscapeSequenceParser { } // if we end up here a real error happened if (error) { - let inject: IParsingState = this._errorHandler( + const inject: IParsingState = this._errorHandler( { position: i, code, @@ -499,15 +499,15 @@ export class EscapeSequenceParser implements IEscapeSequenceParser { if (osc && code !== 0x18 && code !== 0x1a) { // NOTE: OSC subparsing is not part of the original parser // we do basic identifier parsing here to offer a jump table for OSC as well - let idx = osc.indexOf(';'); + const idx = osc.indexOf(';'); if (idx === -1) { this._oscHandlerFb(-1, osc); // this is an error (malformed OSC) } else { // Note: NaN is not handled here // either catch it with the fallback handler // or with an explicit NaN OSC handler - let identifier = parseInt(osc.substring(0, idx)); - let content = osc.substring(idx + 1); + const identifier = parseInt(osc.substring(0, idx)); + const content = osc.substring(idx + 1); callback = this._oscHandlers[identifier]; if (callback) callback(content); else this._oscHandlerFb(identifier, content); diff --git a/src/EventEmitter.ts b/src/EventEmitter.ts index 0698386e..9ce31bb5 100644 --- a/src/EventEmitter.ts +++ b/src/EventEmitter.ts @@ -44,7 +44,7 @@ export class EventEmitter implements IEventEmitter, IDisposable { return; } - let obj = this._events[type]; + const obj = this._events[type]; let i = obj.length; while (i--) { @@ -65,7 +65,7 @@ export class EventEmitter implements IEventEmitter, IDisposable { if (!this._events[type]) { return; } - let obj = this._events[type]; + const obj = this._events[type]; for (let i = 0; i < obj.length; i++) { obj[i].apply(this, args); } diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index ddb16786..6dc043db 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -9,10 +9,10 @@ import { MockInputHandlingTerminal } from './utils/TestUtils.test'; describe('InputHandler', () => { describe('save and restore cursor', () => { - let terminal = new MockInputHandlingTerminal(); + const terminal = new MockInputHandlingTerminal(); terminal.buffer.x = 1; terminal.buffer.y = 2; - let inputHandler = new InputHandler(terminal); + const inputHandler = new InputHandler(terminal); // Save cursor position inputHandler.saveCursor([]); assert.equal(terminal.buffer.x, 1); @@ -27,8 +27,8 @@ describe('InputHandler', () => { }); describe('setCursorStyle', () => { it('should call Terminal.setOption with correct params', () => { - let terminal = new MockInputHandlingTerminal(); - let inputHandler = new InputHandler(terminal); + const terminal = new MockInputHandlingTerminal(); + const inputHandler = new InputHandler(terminal); const collect = ' '; inputHandler.setCursorStyle([0], collect); @@ -68,10 +68,10 @@ describe('InputHandler', () => { }); describe('setMode', () => { it('should toggle Terminal.bracketedPasteMode', () => { - let terminal = new MockInputHandlingTerminal(); + const terminal = new MockInputHandlingTerminal(); const collect = '?'; terminal.bracketedPasteMode = false; - let inputHandler = new InputHandler(terminal); + const inputHandler = new InputHandler(terminal); // Set bracketed paste mode inputHandler.setMode([2004], collect); assert.equal(terminal.bracketedPasteMode, true); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 7b12b6de..f5db133f 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -70,7 +70,7 @@ class DECRQSS implements IDcsHandler { case '"p': // DECSCL return this._terminal.send(`${C0.ESC}P1$r61"p${C0.ESC}\\`); case 'r': // DECSTBM - let pt = '' + (this._terminal.buffer.scrollTop + 1) + + const pt = '' + (this._terminal.buffer.scrollTop + 1) + ';' + (this._terminal.buffer.scrollBottom + 1) + 'r'; return this._terminal.send(`${C0.ESC}P1$r${pt}${C0.ESC}\\`); case 'm': // SGR @@ -259,7 +259,7 @@ export class InputHandler implements IInputHandler { this._parser.setEscHandler('~', () => this.setgLevel(1)); this._parser.setEscHandler('%@', () => this.selectDefaultCharset()); this._parser.setEscHandler('%G', () => this.selectDefaultCharset()); - for (let flag in CHARSETS) { + for (const flag in CHARSETS) { this._parser.setEscHandler('(' + flag, () => this.selectCharset('(' + flag)); this._parser.setEscHandler(')' + flag, () => this.selectCharset(')' + flag)); this._parser.setEscHandler('*' + flag, () => this.selectCharset('*' + flag)); @@ -416,7 +416,7 @@ export class InputHandler implements IInputHandler { for (let moves = 0; moves < chWidth; ++moves) { // remove last cell // if it's width is 0, we have to adjust the second last cell as well - let removed = bufferRow.pop(); + const removed = bufferRow.pop(); if (removed[CHAR_DATA_WIDTH_INDEX] === 0 && bufferRow[this._terminal.cols - 2] && bufferRow[this._terminal.cols - 2][CHAR_DATA_WIDTH_INDEX] === 2) { @@ -786,10 +786,10 @@ export class InputHandler implements IInputHandler { // make buffer local for faster access const buffer = this._terminal.buffer; - let row: number = buffer.y + buffer.ybase; + const row: number = buffer.y + buffer.ybase; - let scrollBottomRowsOffset = this._terminal.rows - 1 - buffer.scrollBottom; - let scrollBottomAbsolute = this._terminal.rows - 1 + buffer.ybase - scrollBottomRowsOffset + 1; + const scrollBottomRowsOffset = this._terminal.rows - 1 - buffer.scrollBottom; + const scrollBottomAbsolute = this._terminal.rows - 1 + buffer.ybase - scrollBottomRowsOffset + 1; while (param--) { // test: echo -e '\e[44m\e[1L\e[0m' // blankLine(true) - xterm/linux behavior @@ -1107,7 +1107,7 @@ export class InputHandler implements IInputHandler { * http://vt100.net/annarbor/aaa-ug/section6.html */ public tabClear(params: number[]): void { - let param = params[0]; + const param = params[0]; if (param <= 0) { delete this._terminal.buffer.tabs[this._terminal.buffer.x]; } else if (param === 3) { diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts index 61245296..12d40bfe 100644 --- a/src/Linkifier.test.ts +++ b/src/Linkifier.test.ts @@ -47,7 +47,7 @@ describe('Linkifier', () => { }); function stringToRow(text: string): LineData { - let result: LineData = []; + const result: LineData = []; for (let i = 0; i < text.length; i++) { result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); } diff --git a/src/Linkifier.ts b/src/Linkifier.ts index 2a19c8d8..ee7c2626 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -199,11 +199,11 @@ export class Linkifier extends EventEmitter implements ILinkifier { */ private _doLinkifyRow(rowIndex: number, text: string, matcher: ILinkMatcher, offset: number = 0): void { // Find the first match - let match = text.match(matcher.regex); + const match = text.match(matcher.regex); if (!match || match.length === 0) { return; } - let uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; + const uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex]; // Get index, match.index is for the outer match which includes negated chars const index = text.indexOf(uri); diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 8d0b04aa..06cea766 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -51,7 +51,7 @@ describe('SelectionManager', () => { }); function stringToRow(text: string): LineData { - let result: LineData = []; + const result: LineData = []; for (let i = 0; i < text.length; i++) { result.push([0, text.charAt(i), 1, text.charCodeAt(i)]); } diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 93da887a..c150554f 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -179,7 +179,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager // Get first row const startRowEndCol = start[1] === end[1] ? end[0] : null; - let result: string[] = []; + const result: string[] = []; result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol)); // Get middle rows @@ -586,7 +586,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param event The mouseup event. */ private _onMouseUp(event: MouseEvent): void { - let timeElapsed = event.timeStamp - this._mouseDownTimeStamp; + const timeElapsed = event.timeStamp - this._mouseDownTimeStamp; this._removeMouseDownListeners(); diff --git a/src/Terminal.integration.ts b/src/Terminal.integration.ts index fdf27acf..54e76518 100644 --- a/src/Terminal.integration.ts +++ b/src/Terminal.integration.ts @@ -24,8 +24,8 @@ let primitivePty: any; function ptyWriteRead(data: string, cb: (result: string) => void): void { fs.writeSync(primitivePty.slave, data); setTimeout(() => { - let b = new Buffer(64000); - let bytes = fs.readSync(primitivePty.master, b, 0, 64000, null); + const b = new Buffer(64000); + const bytes = fs.readSync(primitivePty.master, b, 0, 64000, null); cb(b.toString('utf8', 0, bytes)); }); } @@ -45,7 +45,7 @@ function formatError(input: string, output: string, expected: string): string { return '\x1b[33m' + (' ' + counter).slice(-2) + color + s; }; } - let line80 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890'; + const line80 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890'; let s = ''; s += '\n\x1b[34m' + JSON.stringify(input); s += '\n\x1b[33m ' + line80 + '\n'; @@ -74,11 +74,11 @@ function terminalToString(term: Terminal): string { // Skip tests on Windows since pty.open isn't supported if (os.platform() !== 'win32') { - let CONSOLE_LOG = console.log; + const CONSOLE_LOG = console.log; // expect files need terminal at 80x25! - let COLS = 80; - let ROWS = 25; + const COLS = 80; + const ROWS = 25; /** some helpers for pty interaction */ // we need a pty in between to get the termios decorations @@ -99,9 +99,9 @@ if (os.platform() !== 'win32') { // omit stack trace for escape sequence files Error.stackTraceLimit = 0; - let files = glob.sync('**/escape_sequence_files/*.in', { cwd: path.join(__dirname, '..')}); + const files = glob.sync('**/escape_sequence_files/*.in', { cwd: path.join(__dirname, '..')}); // only successful tests for now - let skip = [ + const skip = [ 10, 16, 17, 19, 32, 33, 34, 35, 36, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, @@ -118,7 +118,7 @@ if (os.platform() !== 'win32') { ((filename: string) => { it(filename.split('/').slice(-1)[0], done => { ptyReset(() => { - let inFile = fs.readFileSync(filename, 'utf8'); + const inFile = fs.readFileSync(filename, 'utf8'); ptyWriteRead(inFile, fromPty => { // uncomment this to get log from terminal // console.log = function(){}; @@ -127,12 +127,12 @@ if (os.platform() !== 'win32') { xterm.writeBuffer.push(fromPty); xterm._innerWrite(); - let fromEmulator = terminalToString(xterm); + const fromEmulator = terminalToString(xterm); console.log = CONSOLE_LOG; - let expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8'); + const expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8'); // Some of the tests have whitespace on the right of lines, we trim all the linex // from xterm.js so ignore this for now at least. - let expectedRightTrimmed = expected.split('\n').map(l => l.replace(/\s+$/, '')).join('\n'); + const expectedRightTrimmed = expected.split('\n').map(l => l.replace(/\s+$/, '')).join('\n'); if (fromEmulator !== expectedRightTrimmed) { // uncomment to get noisy output throw new Error(formatError(inFile, fromEmulator, expected)); @@ -155,7 +155,7 @@ describe('typings', () => { tsc += '.cmd'; } const fixtureDir = path.join(__dirname, '..', 'fixtures', 'typings-test'); - let result = cp.spawnSync(tsc, { cwd: fixtureDir }); + const result = cp.spawnSync(tsc, { cwd: fixtureDir }); assert.equal(result.status, 0, `build did not succeed:\nstdout: ${result.stdout.toString()}\nstderr: ${result.stderr.toString()}\n`); // Clean up fs.unlinkSync(path.join(fixtureDir, 'typings-test.js')); diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 5a604379..5b7039e9 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -77,13 +77,13 @@ describe('term.js addons', () => { }); describe('attachCustomKeyEventHandler', () => { - let evKeyDown = { + const evKeyDown = { preventDefault: () => {}, stopPropagation: () => {}, type: 'keydown', keyCode: 77 }; - let evKeyPress = { + const evKeyPress = { preventDefault: () => {}, stopPropagation: () => {}, type: 'keypress', @@ -131,7 +131,7 @@ describe('term.js addons', () => { describe('clear', () => { it('should clear a buffer equal to rows', () => { - let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + const promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); term.clear(); assert.equal(term.buffer.y, 0); assert.equal(term.buffer.ybase, 0); @@ -148,7 +148,7 @@ describe('term.js addons', () => { term.write('test\n'); } - let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + const promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); term.clear(); assert.equal(term.buffer.y, 0); assert.equal(term.buffer.ybase, 0); @@ -160,7 +160,7 @@ describe('term.js addons', () => { } }); it('should not break the prompt when cleared twice', () => { - let promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); + const promptLine = term.buffer.lines.get(term.buffer.ybase + term.buffer.y); term.clear(); term.clear(); assert.equal(term.buffer.y, 0); @@ -302,7 +302,7 @@ describe('term.js addons', () => { (term)._evaluateKeyEscapeSequence = () => { return { key: 'a' }; }; - let event = { + const event = { type: 'keydown', keyCode: 0, preventDefault: () => {}, @@ -322,7 +322,7 @@ describe('term.js addons', () => { for (let i = 0; i < term.rows * 3; i++) { term.writeln('test'); } - let startYDisp = (term.rows * 2) + 1; + const startYDisp = (term.rows * 2) + 1; term.attachCustomKeyEventHandler(() => { return false; }); @@ -784,11 +784,11 @@ describe('term.js addons', () => { }); it('should emit key with alt + key on keyPress', (done) => { - let keys = ['@', '@', '\\', '\\', '|', '|']; + const keys = ['@', '@', '\\', '\\', '|', '|']; term.on('keypress', (key) => { if (key) { - let index = keys.indexOf(key); + const index = keys.indexOf(key); assert(index !== -1, 'Emitted wrong key: ' + key); keys.splice(index, 1); } @@ -850,11 +850,11 @@ describe('term.js addons', () => { }); it('should emit key with alt + ctrl + key on keyPress', (done) => { - let keys = ['@', '@', '\\', '\\', '|', '|']; + const keys = ['@', '@', '\\', '\\', '|', '|']; term.on('keypress', (key) => { if (key) { - let index = keys.indexOf(key); + const index = keys.indexOf(key); assert(index !== -1, 'Emitted wrong key: ' + key); keys.splice(index, 1); } @@ -895,10 +895,10 @@ describe('term.js addons', () => { describe('unicode - surrogates', () => { it('2 characters per cell', function (): void { this.timeout(10000); // This is needed because istanbul patches code and slows it down - let high = String.fromCharCode(0xD800); + const high = String.fromCharCode(0xD800); for (let i = 0xDC00; i <= 0xDCFF; ++i) { term.write(high + String.fromCharCode(i)); - let tchar = term.buffer.lines.get(0)[0]; + const tchar = term.buffer.lines.get(0)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); @@ -907,7 +907,7 @@ describe('term.js addons', () => { } }); it('2 characters at last cell', () => { - let high = String.fromCharCode(0xD800); + const high = String.fromCharCode(0xD800); for (let i = 0xDC00; i <= 0xDCFF; ++i) { term.buffer.x = term.cols - 1; term.write(high + String.fromCharCode(i)); @@ -918,7 +918,7 @@ describe('term.js addons', () => { } }); it('2 characters per cell over line end with autowrap', () => { - let high = String.fromCharCode(0xD800); + const high = String.fromCharCode(0xD800); for (let i = 0xDC00; i <= 0xDCFF; ++i) { term.buffer.x = term.cols - 1; term.wraparoundMode = true; @@ -931,7 +931,7 @@ describe('term.js addons', () => { } }); it('2 characters per cell over line end without autowrap', () => { - let high = String.fromCharCode(0xD800); + const high = String.fromCharCode(0xD800); for (let i = 0xDC00; i <= 0xDCFF; ++i) { term.buffer.x = term.cols - 1; term.wraparoundMode = false; @@ -944,11 +944,11 @@ describe('term.js addons', () => { } }); it('splitted surrogates', () => { - let high = String.fromCharCode(0xD800); + const high = String.fromCharCode(0xD800); for (let i = 0xDC00; i <= 0xDCFF; ++i) { term.write(high); term.write(String.fromCharCode(i)); - let tchar = term.buffer.lines.get(0)[0]; + const tchar = term.buffer.lines.get(0)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(high + String.fromCharCode(i)); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); @@ -979,12 +979,12 @@ describe('term.js addons', () => { term.wraparoundMode = true; term.write(Array(100).join('e\u0301')); for (let i = 0; i < term.cols; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); } - let tchar = term.buffer.lines.get(1)[0]; + const tchar = term.buffer.lines.get(1)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('e\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); @@ -993,12 +993,12 @@ describe('term.js addons', () => { term.wraparoundMode = true; term.write(Array(100).join('\uD800\uDC00\u0301')); for (let i = 0; i < term.cols; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\uD800\uDC00\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); } - let tchar = term.buffer.lines.get(1)[0]; + const tchar = term.buffer.lines.get(1)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\uD800\uDC00\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(1); @@ -1021,7 +1021,7 @@ describe('term.js addons', () => { term.wraparoundMode = true; term.write(Array(50).join('¥')); for (let i = 0; i < term.cols; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (i % 2) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1032,7 +1032,7 @@ describe('term.js addons', () => { expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); } } - let tchar = term.buffer.lines.get(1)[0]; + const tchar = term.buffer.lines.get(1)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(1); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); @@ -1042,7 +1042,7 @@ describe('term.js addons', () => { term.buffer.x = 1; term.write(Array(50).join('¥')); for (let i = 1; i < term.cols - 1; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (!(i % 2)) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1067,7 +1067,7 @@ describe('term.js addons', () => { term.buffer.x = 1; term.write(Array(50).join('¥\u0301')); for (let i = 1; i < term.cols - 1; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (!(i % 2)) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1091,7 +1091,7 @@ describe('term.js addons', () => { term.wraparoundMode = true; term.write(Array(50).join('¥\u0301')); for (let i = 0; i < term.cols; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (i % 2) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1102,7 +1102,7 @@ describe('term.js addons', () => { expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); } } - let tchar = term.buffer.lines.get(1)[0]; + const tchar = term.buffer.lines.get(1)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('¥\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(2); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); @@ -1112,7 +1112,7 @@ describe('term.js addons', () => { term.buffer.x = 1; term.write(Array(50).join('\ud843\ude6d\u0301')); for (let i = 1; i < term.cols - 1; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (!(i % 2)) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1136,7 +1136,7 @@ describe('term.js addons', () => { term.wraparoundMode = true; term.write(Array(50).join('\ud843\ude6d\u0301')); for (let i = 0; i < term.cols; ++i) { - let tchar = term.buffer.lines.get(0)[i]; + const tchar = term.buffer.lines.get(0)[i]; if (i % 2) { expect(tchar[CHAR_DATA_CHAR_INDEX]).eql(''); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(0); @@ -1147,7 +1147,7 @@ describe('term.js addons', () => { expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); } } - let tchar = term.buffer.lines.get(1)[0]; + const tchar = term.buffer.lines.get(1)[0]; expect(tchar[CHAR_DATA_CHAR_INDEX]).eql('\ud843\ude6d\u0301'); expect(tchar[CHAR_DATA_CHAR_INDEX].length).eql(3); expect(tchar[CHAR_DATA_WIDTH_INDEX]).eql(2); diff --git a/src/Terminal.ts b/src/Terminal.ts index 2cae7b56..63f7efdb 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -827,7 +827,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< function sendMove(ev: MouseEvent): void { let button = pressed; - let pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.options.lineHeight, self.cols, self.rows); + const pos = self.mouseHelper.getRawByteCoords(ev, self.screenElement, self.charMeasure, self.options.lineHeight, self.cols, self.rows); if (!pos) return; // buttons marked as motions @@ -938,7 +938,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II return; } - let data: number[] = []; + const data: number[] = []; encode(data, button); encode(data, pos.x); @@ -1145,7 +1145,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II public scroll(isWrapped?: boolean): void { const newLine = this.blankLine(undefined, isWrapped); const topRow = this.buffer.ybase + this.buffer.scrollTop; - let bottomRow = this.buffer.ybase + this.buffer.scrollBottom; + const bottomRow = this.buffer.ybase + this.buffer.scrollBottom; if (this.buffer.scrollTop === 0) { // Determine whether the buffer is going to be trimmed after insertion. diff --git a/src/Viewport.ts b/src/Viewport.ts index c951d6b5..f690c348 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -180,7 +180,7 @@ export class Viewport implements IViewport { * @param ev The touch event. */ public onTouchMove(ev: TouchEvent): void { - let deltaY = this._lastTouchY - ev.touches[0].pageY; + const deltaY = this._lastTouchY - ev.touches[0].pageY; this._lastTouchY = ev.touches[0].pageY; if (deltaY === 0) { return; diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index 4a9668de..731739f4 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -51,7 +51,7 @@ export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean str = myTextDecoder.decode(ev.data); displayData(str); } else { - let fileReader = new FileReader(); + const fileReader = new FileReader(); fileReader.addEventListener('load', () => { str = myTextDecoder.decode(this.result); diff --git a/src/addons/webLinks/webLinks.test.ts b/src/addons/webLinks/webLinks.test.ts index b3c76703..c84ee1a5 100644 --- a/src/addons/webLinks/webLinks.test.ts +++ b/src/addons/webLinks/webLinks.test.ts @@ -34,8 +34,8 @@ describe('webLinks addon', () => { const row = ' http://foo.com/a~b#c~d?e~f '; - let match = row.match(term.regex); - let 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'); }); diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 7f2e4f05..8f1cf2df 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -28,7 +28,7 @@ export class AltClickHandler { this._startCol = this._terminal.buffer.x; this._startRow = this._terminal.buffer.y; - let coordinates = this._terminal.mouseHelper.getCoords( + const coordinates = this._terminal.mouseHelper.getCoords( this._mouseEvent, this._terminal.element, this._terminal.charMeasure, @@ -89,10 +89,10 @@ export class AltClickHandler { * ignoring wrapped rows */ private _moveToRequestedRow(): string { - let startRow = this._startRow - this._wrappedRowsForRow(this._startRow); - let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); + const startRow = this._startRow - this._wrappedRowsForRow(this._startRow); + const endRow = this._endRow - this._wrappedRowsForRow(this._endRow); - let rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount(); + const rowsToMove = Math.abs(startRow - endRow) - this._wrappedRowsCount(); return repeat(rowsToMove, this._sequence(this._verticalDirection())); } @@ -108,8 +108,8 @@ export class AltClickHandler { startRow = this._startRow; } - let endRow = this._endRow; - let direction = this._horizontalDirection(); + const endRow = this._endRow; + const direction = this._horizontalDirection(); return repeat(this._bufferLine( this._startCol, startRow, this._endCol, endRow, @@ -118,7 +118,7 @@ export class AltClickHandler { } private _moveHorizontallyOnly(): string { - let direction = this._horizontalDirection(); + const direction = this._horizontalDirection(); return repeat(Math.abs(this._startCol - this._endCol), this._sequence(direction)); } @@ -132,11 +132,11 @@ export class AltClickHandler { */ private _wrappedRowsCount(): number { let wrappedRows = 0; - let startRow = this._startRow - this._wrappedRowsForRow(this._startRow); - let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); + const startRow = this._startRow - this._wrappedRowsForRow(this._startRow); + const endRow = this._endRow - this._wrappedRowsForRow(this._endRow); for (let i = 0; i < Math.abs(startRow - endRow); i++) { - let direction = this._verticalDirection() === Direction.UP ? -1 : 1; + const direction = this._verticalDirection() === Direction.UP ? -1 : 1; if ((this._lines.get(startRow + (direction * i))).isWrapped) { wrappedRows++; diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 23925007..bbb8302c 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -58,7 +58,7 @@ export function pasteHandler(ev: ClipboardEvent, term: ITerminal): void { let text: string; - let dispatchPaste = function(text: string): void { + const dispatchPaste = function(text: string): void { text = prepareTextForTerminal(text); text = bracketTextForPaste(text, term.bracketedPasteMode); term.handler(text); diff --git a/src/renderer/ColorManager.test.ts b/src/renderer/ColorManager.test.ts index 724bc758..0012c1ed 100644 --- a/src/renderer/ColorManager.test.ts +++ b/src/renderer/ColorManager.test.ts @@ -33,7 +33,7 @@ describe('ColorManager', () => { describe('constructor', () => { it('should fill all colors with values', () => { - for (let key of Object.keys(cm.colors)) { + for (const key of Object.keys(cm.colors)) { if (key !== 'ansi') { // A #rrggbb or rgba(...) assert.ok(cm.colors[key].css.length >= 7); diff --git a/src/renderer/ColorManager.ts b/src/renderer/ColorManager.ts index 9ab60750..d169f266 100644 --- a/src/renderer/ColorManager.ts +++ b/src/renderer/ColorManager.ts @@ -42,7 +42,7 @@ export const DEFAULT_ANSI_COLORS = (() => { // Fill in the remaining 240 ANSI colors. // Generate colors (16-231) - let v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; for (let i = 0; i < 216; i++) { const r = v[(i / 36) % 6 | 0]; const g = v[(i / 6) % 6 | 0]; @@ -75,7 +75,7 @@ function fromHex(css: string): IColor { } function toPaddedHex(c: number): string { - let s = c.toString(16); + const s = c.toString(16); return s.length < 2 ? '0' + s : s; } diff --git a/src/utils/CircularList.ts b/src/utils/CircularList.ts index 1f00ea09..ca83d6e1 100644 --- a/src/utils/CircularList.ts +++ b/src/utils/CircularList.ts @@ -36,7 +36,7 @@ export class CircularList extends EventEmitter implements ICircularList { // Reconstruct array, starting at index 0. Only transfer values from the // indexes 0 to length. - let newArray = new Array(newMaxLength); + const newArray = new Array(newMaxLength); for (let i = 0; i < Math.min(newMaxLength, this.length); i++) { newArray[i] = this._array[this._getCyclicIndex(i)]; } diff --git a/tslint.json b/tslint.json index 67dc7955..8b364077 100644 --- a/tslint.json +++ b/tslint.json @@ -101,6 +101,7 @@ }, "prefer-const-enum": [ true - ] + ], + "prefer-const": true } } From 90b9a487cd417eaf928cb7e75586c6465c8146e5 Mon Sep 17 00:00:00 2001 From: Oleksandr Andriienko Date: Fri, 1 Jun 2018 13:41:35 +0300 Subject: [PATCH 04/13] Minor: clean up build logs for source code without tests. Signed-off-by: Oleksandr Andriienko --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index e56930e6..2e7404e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,8 @@ "noUnusedLocals": true }, "include": [ - "src/**/*" + "src/**/*", + "typings/xterm.d.ts" ], "exclude": [ "src/addons/**/*" From d5af79fc5fde99bd2a01350d80f3d99e1d80feb8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 1 Jun 2018 08:55:22 -0700 Subject: [PATCH 05/13] Include typings in addons as well --- src/addons/attach/attach.ts | 2 -- src/addons/attach/tsconfig.json | 6 +++++- src/addons/fit/fit.ts | 2 -- src/addons/fit/tsconfig.json | 6 +++++- src/addons/fullscreen/fullscreen.ts | 2 -- src/addons/fullscreen/tsconfig.json | 6 +++++- src/addons/search/search.ts | 2 -- src/addons/search/tsconfig.json | 6 +++++- src/addons/terminado/terminado.ts | 2 -- src/addons/terminado/tsconfig.json | 6 +++++- src/addons/webLinks/tsconfig.json | 6 +++++- src/addons/webLinks/webLinks.ts | 2 -- src/addons/winptyCompat/tsconfig.json | 6 +++++- src/addons/winptyCompat/winptyCompat.ts | 2 -- src/addons/zmodem/tsconfig.json | 6 +++++- src/addons/zmodem/zmodem.ts | 2 -- 16 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index 731739f4..d0e8bd4b 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -5,8 +5,6 @@ * Implements the attach method, that attaches the terminal to a WebSocket stream. */ -/// - import { Terminal } from 'xterm'; import { IAttachAddonTerminal } from './Interfaces'; diff --git a/src/addons/attach/tsconfig.json b/src/addons/attach/tsconfig.json index a4e8e78b..19954249 100644 --- a/src/addons/attach/tsconfig.json +++ b/src/addons/attach/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/fit/fit.ts b/src/addons/fit/fit.ts index f6f593dc..68e4cfd5 100644 --- a/src/addons/fit/fit.ts +++ b/src/addons/fit/fit.ts @@ -13,8 +13,6 @@ * row and truncate its width with the current number of columns). */ -/// - import { Terminal } from 'xterm'; export interface IGeometry { diff --git a/src/addons/fit/tsconfig.json b/src/addons/fit/tsconfig.json index 78b3c410..e1dce37f 100644 --- a/src/addons/fit/tsconfig.json +++ b/src/addons/fit/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/fullscreen/fullscreen.ts b/src/addons/fullscreen/fullscreen.ts index 47440667..297a7f5b 100644 --- a/src/addons/fullscreen/fullscreen.ts +++ b/src/addons/fullscreen/fullscreen.ts @@ -3,8 +3,6 @@ * @license MIT */ -/// - import { Terminal } from 'xterm'; /** diff --git a/src/addons/fullscreen/tsconfig.json b/src/addons/fullscreen/tsconfig.json index 35ecb7ce..5a06c490 100644 --- a/src/addons/fullscreen/tsconfig.json +++ b/src/addons/fullscreen/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/search/search.ts b/src/addons/search/search.ts index 5c0b2b96..a1dd766f 100644 --- a/src/addons/search/search.ts +++ b/src/addons/search/search.ts @@ -3,8 +3,6 @@ * @license MIT */ -/// - import { SearchHelper } from './SearchHelper'; import { Terminal } from 'xterm'; import { ISearchAddonTerminal } from './Interfaces'; diff --git a/src/addons/search/tsconfig.json b/src/addons/search/tsconfig.json index d1c3d7e0..d833bb28 100644 --- a/src/addons/search/tsconfig.json +++ b/src/addons/search/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/terminado/terminado.ts b/src/addons/terminado/terminado.ts index 4acf9dd8..136eea8e 100644 --- a/src/addons/terminado/terminado.ts +++ b/src/addons/terminado/terminado.ts @@ -6,8 +6,6 @@ * WebSocket stream. */ -/// - import { Terminal } from 'xterm'; import { ITerminadoAddonTerminal } from './Interfaces'; diff --git a/src/addons/terminado/tsconfig.json b/src/addons/terminado/tsconfig.json index 84e3ac32..2c795b99 100644 --- a/src/addons/terminado/tsconfig.json +++ b/src/addons/terminado/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/webLinks/tsconfig.json b/src/addons/webLinks/tsconfig.json index 7549370b..b34f544d 100644 --- a/src/addons/webLinks/tsconfig.json +++ b/src/addons/webLinks/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/webLinks/webLinks.ts b/src/addons/webLinks/webLinks.ts index 7ff87c60..a007bbd6 100644 --- a/src/addons/webLinks/webLinks.ts +++ b/src/addons/webLinks/webLinks.ts @@ -3,8 +3,6 @@ * @license MIT */ -/// - import { Terminal, ILinkMatcherOptions } from 'xterm'; const protocolClause = '(https?:\\/\\/)'; diff --git a/src/addons/winptyCompat/tsconfig.json b/src/addons/winptyCompat/tsconfig.json index a51f7332..fdca3e3d 100644 --- a/src/addons/winptyCompat/tsconfig.json +++ b/src/addons/winptyCompat/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/winptyCompat/winptyCompat.ts b/src/addons/winptyCompat/winptyCompat.ts index 61524e12..9cde62e0 100644 --- a/src/addons/winptyCompat/winptyCompat.ts +++ b/src/addons/winptyCompat/winptyCompat.ts @@ -3,8 +3,6 @@ * @license MIT */ -/// - import { Terminal } from 'xterm'; import { IWinptyCompatAddonTerminal } from './Interfaces'; diff --git a/src/addons/zmodem/tsconfig.json b/src/addons/zmodem/tsconfig.json index abae1238..f5693801 100644 --- a/src/addons/zmodem/tsconfig.json +++ b/src/addons/zmodem/tsconfig.json @@ -7,5 +7,9 @@ "sourceMap": true, "removeComments": true, "declaration": true - } + }, + "include": [ + "**/*.ts", + "../../../typings/xterm.d.ts" + ] } diff --git a/src/addons/zmodem/zmodem.ts b/src/addons/zmodem/zmodem.ts index 4f2f4a91..4683538f 100644 --- a/src/addons/zmodem/zmodem.ts +++ b/src/addons/zmodem/zmodem.ts @@ -3,8 +3,6 @@ * @license MIT */ -/// - import { Terminal } from 'xterm'; /** From 5acc45f08bb5981ee3425efa59d6f4d7cf26da9f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 12:22:05 -0700 Subject: [PATCH 06/13] Add basic fit readme Fixes #664 --- src/addons/fit/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/addons/fit/README.md diff --git a/src/addons/fit/README.md b/src/addons/fit/README.md new file mode 100644 index 00000000..68f01589 --- /dev/null +++ b/src/addons/fit/README.md @@ -0,0 +1,3 @@ +## fit addon + +The fit addon adjusts the dimensions of the terminal to match best fit its parent element container. `fit` will only work when the element is visible. From 285911cd98d13d9a3226f9429567dac0e2b42ce5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 17:53:35 -0700 Subject: [PATCH 07/13] Implement IBuffer.getWrappedRangeForLine Part of #1456 --- src/Buffer.test.ts | 47 +++++++++++++++++++++++++++++++++++++ src/Buffer.ts | 14 +++++++++++ src/Types.ts | 1 + src/utils/TestUtils.test.ts | 3 +++ 4 files changed, 65 insertions(+) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 44687f0e..09d22c5d 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -48,6 +48,53 @@ describe('Buffer', () => { }); }); + describe('getWrappedRangeForLine', () => { + describe('non-wrapped', () => { + it('should return a single row for the first row', () => { + buffer.fillViewportRows(); + assert.deepEqual(buffer.getWrappedRangeForLine(0), { first: 0, last: 0 }); + }); + it('should return a single row for a middle row', () => { + buffer.fillViewportRows(); + assert.deepEqual(buffer.getWrappedRangeForLine(12), { first: 12, last: 12 }); + }); + it('should return a single row for the last row', () => { + buffer.fillViewportRows(); + assert.deepEqual(buffer.getWrappedRangeForLine(buffer.lines.length - 1), { first: 23, last: 23 }); + }); + }); + describe('wrapped', () => { + it('should return a range for the first row', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(1)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(0), { first: 0, last: 1 }); + }); + it('should return a range for a middle row wrapping upwards', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(12)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(12), { first: 11, last: 12 }); + }); + it('should return a range for a middle row wrapping downwards', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(13)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(12), { first: 12, last: 13 }); + }); + it('should return a range for a middle row wrapping both ways', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(11)).isWrapped = true; + ( buffer.lines.get(12)).isWrapped = true; + ( buffer.lines.get(13)).isWrapped = true; + ( buffer.lines.get(14)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(12), { first: 10, last: 14 }); + }); + it('should return a range for the last row', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(23)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(buffer.lines.length - 1), { first: 22, last: 23 }); + }); + }); + }); + describe('resize', () => { describe('column size is reduced', () => { it('should not trim the data in the buffer', () => { diff --git a/src/Buffer.ts b/src/Buffer.ts index 1ea303b2..235411c3 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -259,6 +259,20 @@ export class Buffer implements IBuffer { return lineString.substring(startIndex, endIndex); } + public getWrappedRangeForLine(y: number): { first: number, last: number } { + let first = y; + let last = y; + // Scan upwards for wrapped lines + while (first > 0 && (this.lines.get(first)).isWrapped) { + first--; + } + // Scan downwards for wrapped lines + while (last + 1 < this.lines.length - 1 && (this.lines.get(last + 1)).isWrapped) { + last++; + } + return { first, last }; + } + /** * Setup the tab stops. * @param i The index to start setting up tab stops from. diff --git a/src/Types.ts b/src/Types.ts index 5075daa9..45f1039b 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -284,6 +284,7 @@ export interface IBuffer { savedX: number; isCursorInViewport: boolean; translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string; + getWrappedRangeForLine(y: number): { first: number, last: number }; nextStop(x?: number): number; prevStop(x?: number): number; } diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index e3ae89d3..6cb8d42e 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -302,6 +302,9 @@ export class MockBuffer implements IBuffer { translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string { return Buffer.prototype.translateBufferLineToString.apply(this, arguments); } + getWrappedRangeForLine(y: number): { first: number; last: number; } { + throw new Error('Method not implemented.'); + } nextStop(x?: number): number { throw new Error('Method not implemented.'); } From cd3418517e091f9a7dc06335dabe760a1f17f508 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 17:56:44 -0700 Subject: [PATCH 08/13] Select the whole wrapped line when triple clicking Fixes #1456 --- src/SelectionManager.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index c150554f..1b056e83 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -803,7 +803,9 @@ export class SelectionManager extends EventEmitter implements ISelectionManager * @param line The line index. */ protected _selectLineAt(line: number): void { - this._model.selectionStart = [0, line]; - this._model.selectionStartLength = this._terminal.cols; + const wrappedRange = this._buffer.getWrappedRangeForLine(line); + this._model.selectionStart = [0, wrappedRange.first]; + this._model.selectionEnd = [this._terminal.cols, wrappedRange.last]; + this._model.selectionStartLength = 0; } } From 956b7734218429b9883835b74465e2eebe00ea4e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 18:07:49 -0700 Subject: [PATCH 09/13] Add more tests, fix boundary bug --- src/Buffer.test.ts | 12 +++++++++++- src/Buffer.ts | 2 +- src/SelectionManager.test.ts | 10 ++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Buffer.test.ts b/src/Buffer.test.ts index 09d22c5d..82aa0224 100644 --- a/src/Buffer.test.ts +++ b/src/Buffer.test.ts @@ -89,9 +89,19 @@ describe('Buffer', () => { }); it('should return a range for the last row', () => { buffer.fillViewportRows(); - ( buffer.lines.get(23)).isWrapped = true; + ( buffer.lines.get(23)).isWrapped = true; assert.deepEqual(buffer.getWrappedRangeForLine(buffer.lines.length - 1), { first: 22, last: 23 }); }); + it('should return a range for a row that wraps upward to first row', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(1)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(1), { first: 0, last: 1 }); + }); + it('should return a range for a row that wraps downward to last row', () => { + buffer.fillViewportRows(); + ( buffer.lines.get(buffer.lines.length - 1)).isWrapped = true; + assert.deepEqual(buffer.getWrappedRangeForLine(buffer.lines.length - 2), { first: 22, last: 23 }); + }); }); }); diff --git a/src/Buffer.ts b/src/Buffer.ts index 235411c3..379214ae 100644 --- a/src/Buffer.ts +++ b/src/Buffer.ts @@ -267,7 +267,7 @@ export class Buffer implements IBuffer { first--; } // Scan downwards for wrapped lines - while (last + 1 < this.lines.length - 1 && (this.lines.get(last + 1)).isWrapped) { + while (last + 1 < this.lines.length && (this.lines.get(last + 1)).isWrapped) { last++; } return { first, last }; diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts index 06cea766..8e89ea3f 100644 --- a/src/SelectionManager.test.ts +++ b/src/SelectionManager.test.ts @@ -298,6 +298,16 @@ describe('SelectionManager', () => { assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 0], 'The actual selection spans the entire column'); }); + it('should select the entire wrapped line', () => { + buffer.lines.set(0, stringToRow('foo')); + const line2 = stringToRow('bar'); + (line2).isWrapped = true; + buffer.lines.set(1, line2); + selectionManager.selectLineAt(0); + assert.equal(selectionManager.selectionText, 'foobar', 'The selected text is correct'); + assert.deepEqual(selectionManager.model.finalSelectionStart, [0, 0]); + assert.deepEqual(selectionManager.model.finalSelectionEnd, [terminal.cols, 1], 'The actual selection spans the entire column'); + }); }); describe('selectAll', () => { From b79ab7212c1c566e373e3e5f6b17375042b29750 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 18:39:05 -0700 Subject: [PATCH 10/13] Remove a bunch of implicit anys --- src/EscapeSequenceParser.test.ts | 26 +++++++++++++------------- src/Terminal.test.ts | 12 ++++++------ src/Terminal.ts | 2 +- src/Types.ts | 1 + src/addons/attach/attach.ts | 4 ++-- src/renderer/ColorManager.test.ts | 2 +- src/renderer/atlas/CharAtlasUtils.ts | 2 +- src/renderer/atlas/LRUMap.ts | 2 +- src/shared/atlas/CharAtlasGenerator.ts | 2 +- src/utils/Clone.test.ts | 2 +- 10 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/EscapeSequenceParser.test.ts b/src/EscapeSequenceParser.test.ts index d9ea64ce..dffbccbc 100644 --- a/src/EscapeSequenceParser.test.ts +++ b/src/EscapeSequenceParser.test.ts @@ -237,7 +237,7 @@ describe('EscapeSequenceParser', function (): void { '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', '\x99', '\x9a' ]; - const exceptions = { + const exceptions: { [key: number]: { [key: string]: any[] } } = { 8: { '\x18': [], '\x1a': [] } // simply abort osc state }; parser.reset(); @@ -247,7 +247,7 @@ describe('EscapeSequenceParser', function (): void { parser.currentState = state; parser.parse(exes[i]); chai.expect(parser.currentState).equal(ParserState.GROUND); - testTerminal.compare(((exceptions[state]) ? exceptions[state][exes[i]] : 0) || [['exe', exes[i]]]); + testTerminal.compare((state in exceptions ? exceptions[state][exes[i]] : 0) || [['exe', exes[i]]]); parser.reset(); testTerminal.clear(); } @@ -1099,20 +1099,20 @@ describe('EscapeSequenceParser', function (): void { describe('set/clear handler', function (): void { const INPUT = '\x1b[1;31mhello \x1b%Gwor\x1bEld!\x1b[0m\r\n$>\x1b]1;foo=bar\x1b\\'; - let parser2 = null; + let parser2: TestEscapeSequenceParser = null; let print = ''; - let esc = []; - let csi = []; - let exe = []; - let osc = []; - let dcs = []; + const esc: string[] = []; + const csi: [string, number[], string][] = []; + const exe: string[] = []; + const osc: [number, string][] = []; + const dcs: ([string] | [string, string] | [string, string, number[], number])[] = []; function clearAccu(): void { print = ''; - esc = []; - csi = []; - exe = []; - osc = []; - dcs = []; + esc.length = 0; + csi.length = 0; + exe.length = 0; + osc.length = 0; + dcs.length = 0; } beforeEach(function (): void { parser2 = new TestEscapeSequenceParser(); diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 5b7039e9..f6cbad52 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -176,7 +176,7 @@ describe('term.js addons', () => { describe('scroll', () => { describe('scrollLines', () => { - let startYDisp; + let startYDisp: number; beforeEach(() => { for (let i = 0; i < term.rows * 2; i++) { term.writeln('test'); @@ -211,7 +211,7 @@ describe('term.js addons', () => { }); describe('scrollPages', () => { - let startYDisp; + let startYDisp: number; beforeEach(() => { for (let i = 0; i < term.rows * 3; i++) { term.writeln('test'); @@ -248,7 +248,7 @@ describe('term.js addons', () => { }); describe('scrollToBottom', () => { - let startYDisp; + let startYDisp: number; beforeEach(() => { for (let i = 0; i < term.rows * 3; i++) { term.writeln('test'); @@ -269,7 +269,7 @@ describe('term.js addons', () => { }); describe('scrollToLine', () => { - let startYDisp; + let startYDisp: number; beforeEach(() => { for (let i = 0; i < term.rows * 3; i++) { term.writeln('test'); @@ -712,8 +712,8 @@ describe('term.js addons', () => { }); describe('Third level shift', () => { - let evKeyDown; - let evKeyPress; + let evKeyDown: any; + let evKeyPress: any; beforeEach(() => { term.handler = () => {}; diff --git a/src/Terminal.ts b/src/Terminal.ts index 63f7efdb..568cd977 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -561,7 +561,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II } copyHandler(event, this, this.selectionManager); }); - const pasteHandlerWrapper = event => pasteHandler(event, this); + const pasteHandlerWrapper = (event: ClipboardEvent) => pasteHandler(event, this); on(this.textarea, 'paste', pasteHandlerWrapper); on(this.element, 'paste', pasteHandlerWrapper); diff --git a/src/Types.ts b/src/Types.ts index 5075daa9..97a6f9e4 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -261,6 +261,7 @@ export interface ICharMeasure { // TODO: The options that are not in the public API should be reviewed export interface ITerminalOptions extends IPublicTerminalOptions { + [key: string]: any; cancelEvents?: boolean; convertEol?: boolean; debug?: boolean; diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index d0e8bd4b..f8d8657c 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -36,10 +36,10 @@ export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean } }; - let myTextDecoder; + let myTextDecoder: TextDecoder; addonTerminal.__getMessage = function(ev: MessageEvent): void { - let str; + let str: string; if (typeof ev.data === 'object') { if (!myTextDecoder) { diff --git a/src/renderer/ColorManager.test.ts b/src/renderer/ColorManager.test.ts index 0012c1ed..26fb2895 100644 --- a/src/renderer/ColorManager.test.ts +++ b/src/renderer/ColorManager.test.ts @@ -36,7 +36,7 @@ describe('ColorManager', () => { for (const key of Object.keys(cm.colors)) { if (key !== 'ansi') { // A #rrggbb or rgba(...) - assert.ok(cm.colors[key].css.length >= 7); + assert.ok((cm.colors)[key].css.length >= 7); } } assert.equal(cm.colors.ansi.length, 256); diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/renderer/atlas/CharAtlasUtils.ts index 39284d32..59ac07df 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/renderer/atlas/CharAtlasUtils.ts @@ -9,7 +9,7 @@ import { ICharAtlasConfig } from '../../shared/atlas/Types'; export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig { // null out some fields that don't matter - const clonedColors = { + const clonedColors = { foreground: colors.foreground, background: colors.background, cursor: null, diff --git a/src/renderer/atlas/LRUMap.ts b/src/renderer/atlas/LRUMap.ts index 4a03f2aa..eccfbfea 100644 --- a/src/renderer/atlas/LRUMap.ts +++ b/src/renderer/atlas/LRUMap.ts @@ -11,7 +11,7 @@ interface ILinkedListNode { } export default class LRUMap { - private _map = {}; + private _map: { [key: string]: ILinkedListNode } = {}; private _head: ILinkedListNode = null; private _tail: ILinkedListNode = null; private _nodePool: ILinkedListNode[] = []; diff --git a/src/shared/atlas/CharAtlasGenerator.ts b/src/shared/atlas/CharAtlasGenerator.ts index e0cfbcf7..f78a6d41 100644 --- a/src/shared/atlas/CharAtlasGenerator.ts +++ b/src/shared/atlas/CharAtlasGenerator.ts @@ -106,7 +106,7 @@ export function generateStaticCharAtlasTexture(context: Window, canvasFactory: ( return canvas; } // Transfer to an ImageBitmap is this is an OffscreenCanvas - return new Promise(r => r(canvas.transferToImageBitmap())); + return new Promise((r: (bitmap: ImageBitmap) => void) => r(canvas.transferToImageBitmap())); } const charAtlasImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); diff --git a/src/utils/Clone.test.ts b/src/utils/Clone.test.ts index f5708a9e..b24452c8 100644 --- a/src/utils/Clone.test.ts +++ b/src/utils/Clone.test.ts @@ -39,7 +39,7 @@ describe('clone', () => { }); it('should clone null values', () => { - const test = { + const test: any = { a: null }; From 918ee16f868cc03e9545486094adb232b1433eb0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 18:46:29 -0700 Subject: [PATCH 11/13] Don't set options on terminaol object itself --- src/Terminal.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 568cd977..ad33f684 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -277,8 +277,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II if (this.options[key] == null) { this.options[key] = DEFAULT_OPTIONS[key]; } - // TODO: We should move away from duplicate options on the Terminal object - this[key] = this.options[key]; }); // this.context = options.context || window; @@ -384,11 +382,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II throw new Error('No option with key "' + key + '"'); } - if (typeof this.options[key] !== 'undefined') { - return this.options[key]; - } - - return this[key]; + return this.options[key]; } /** @@ -462,7 +456,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II } break; } - this[key] = value; this.options[key] = value; switch (key) { case 'fontFamily': From fea8ba03b81022cca59598696e7ed8081ae180b5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 2 Jun 2018 19:02:54 -0700 Subject: [PATCH 12/13] Finish removing all implicit anys --- src/CompositionHelper.test.ts | 65 ++++++++++++++++++----------------- src/InputHandler.ts | 4 +-- src/Terminal.integration.ts | 13 ++++--- src/Terminal.ts | 4 +-- src/addons/attach/attach.ts | 3 +- tsconfig.json | 3 +- 6 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/CompositionHelper.test.ts b/src/CompositionHelper.test.ts index 02231723..053a0c29 100644 --- a/src/CompositionHelper.test.ts +++ b/src/CompositionHelper.test.ts @@ -5,13 +5,14 @@ import { assert } from 'chai'; import { CompositionHelper } from './CompositionHelper'; +import { ITerminal } from './Types'; describe('CompositionHelper', () => { - let terminal; - let compositionHelper; - let compositionView; - let textarea; - let handledText; + let terminal: ITerminal; + let compositionHelper: CompositionHelper; + let compositionView: HTMLElement; + let textarea: HTMLTextAreaElement; + let handledText: string; beforeEach(() => { compositionView = { @@ -27,14 +28,14 @@ describe('CompositionHelper', () => { top: 0 }, textContent: '' - }; + } as any; textarea = { value: '', style: { left: 0, top: 0 } - }; + } as any; terminal = { element: { querySelector: () => { @@ -54,7 +55,7 @@ describe('CompositionHelper', () => { options: { lineHeight: 1 } - }; + } as any; handledText = ''; compositionHelper = new CompositionHelper(textarea, compositionView, terminal); }); @@ -63,7 +64,7 @@ describe('CompositionHelper', () => { it('Should insert simple characters', (done) => { // First character 'ㅇ' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = 'ㅇ'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -71,7 +72,7 @@ describe('CompositionHelper', () => { assert.equal(handledText, 'ㅇ'); // Second character 'ㅇ' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = 'ㅇㅇ'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -87,13 +88,13 @@ describe('CompositionHelper', () => { it('Should insert complex characters', (done) => { // First character '앙' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = 'ㅇ'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: '아' }); + compositionHelper.compositionupdate({ data: '아' }); textarea.value = '아'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: '앙' }); + compositionHelper.compositionupdate({ data: '앙' }); textarea.value = '앙'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -101,13 +102,13 @@ describe('CompositionHelper', () => { assert.equal(handledText, '앙'); // Second character '앙' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = '앙ㅇ'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: '아' }); + compositionHelper.compositionupdate({ data: '아' }); textarea.value = '앙아'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: '앙' }); + compositionHelper.compositionupdate({ data: '앙' }); textarea.value = '앙앙'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -127,19 +128,19 @@ describe('CompositionHelper', () => { it('Should insert complex characters that change with following character', (done) => { // First character '아' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = 'ㅇ'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: '아' }); + compositionHelper.compositionupdate({ data: '아' }); textarea.value = '아'; setTimeout(() => { // wait for any textarea updates // Start second character '아' in first character - compositionHelper.compositionupdate({ data: '앙' }); + compositionHelper.compositionupdate({ data: '앙' }); textarea.value = '앙'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: '아' }); + compositionHelper.compositionupdate({ data: '아' }); textarea.value = '아아'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -156,14 +157,14 @@ describe('CompositionHelper', () => { it('Should insert multi-characters compositions', (done) => { // First character 'だ' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'd' }); + compositionHelper.compositionupdate({ data: 'd' }); textarea.value = 'd'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: 'だ' }); + compositionHelper.compositionupdate({ data: 'だ' }); textarea.value = 'だ'; setTimeout(() => { // wait for any textarea updates // Second character 'あ' - compositionHelper.compositionupdate({ data: 'だあ' }); + compositionHelper.compositionupdate({ data: 'だあ' }); textarea.value = 'だあ'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -179,18 +180,18 @@ describe('CompositionHelper', () => { it('Should insert multi-character compositions that are converted to other characters with the same length', (done) => { // First character 'だ' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'd' }); + compositionHelper.compositionupdate({ data: 'd' }); textarea.value = 'd'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: 'だ' }); + compositionHelper.compositionupdate({ data: 'だ' }); textarea.value = 'だ'; setTimeout(() => { // wait for any textarea updates // Second character 'ー' - compositionHelper.compositionupdate({ data: 'だー' }); + compositionHelper.compositionupdate({ data: 'だー' }); textarea.value = 'だー'; setTimeout(() => { // wait for any textarea updates // Convert to katakana 'ダー' - compositionHelper.compositionupdate({ data: 'ダー' }); + compositionHelper.compositionupdate({ data: 'ダー' }); textarea.value = 'ダー'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -207,18 +208,18 @@ describe('CompositionHelper', () => { it('Should insert multi-character compositions that are converted to other characters with different lengths', (done) => { // First character 'い' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'い' }); + compositionHelper.compositionupdate({ data: 'い' }); textarea.value = 'い'; setTimeout(() => { // wait for any textarea updates // Second character 'ま' - compositionHelper.compositionupdate({ data: 'いm' }); + compositionHelper.compositionupdate({ data: 'いm' }); textarea.value = 'いm'; setTimeout(() => { // wait for any textarea updates - compositionHelper.compositionupdate({ data: 'いま' }); + compositionHelper.compositionupdate({ data: 'いま' }); textarea.value = 'いま'; setTimeout(() => { // wait for any textarea updates // Convert to kanji '今' - compositionHelper.compositionupdate({ data: '今' }); + compositionHelper.compositionupdate({ data: '今' }); textarea.value = '今'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); @@ -235,7 +236,7 @@ describe('CompositionHelper', () => { it('Should insert non-composition characters input immediately after composition characters', (done) => { // First character 'ㅇ' compositionHelper.compositionstart(); - compositionHelper.compositionupdate({ data: 'ㅇ' }); + compositionHelper.compositionupdate({ data: 'ㅇ' }); textarea.value = 'ㅇ'; setTimeout(() => { // wait for any textarea updates compositionHelper.compositionend(); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index f5db133f..16fedea2 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -15,7 +15,7 @@ import { EscapeSequenceParser } from './EscapeSequenceParser'; /** * Map collect to glevel. Used in `selectCharset`. */ -const GLEVEL = {'(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2}; +const GLEVEL: {[key: string]: number} = {'(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2}; /** @@ -77,7 +77,7 @@ class DECRQSS implements IDcsHandler { // TODO: report real settings instead of 0m return this._terminal.send(`${C0.ESC}P1$r0m${C0.ESC}\\`); case ' q': // DECSCUSR - const STYLES = {'block': 2, 'underline': 4, 'bar': 6}; + const STYLES: {[key: string]: number} = {'block': 2, 'underline': 4, 'bar': 6}; let style = STYLES[this._terminal.getOption('cursorStyle')]; style -= this._terminal.getOption('cursorBlink'); return this._terminal.send(`${C0.ESC}P1$r${style} q${C0.ESC}\\`); diff --git a/src/Terminal.integration.ts b/src/Terminal.integration.ts index 54e76518..bb50d2d0 100644 --- a/src/Terminal.integration.ts +++ b/src/Terminal.integration.ts @@ -14,6 +14,11 @@ import * as pty from 'node-pty'; import { assert } from 'chai'; import { Terminal } from './Terminal'; import { CHAR_DATA_CHAR_INDEX } from './Buffer'; +import { IViewport } from './Types'; + +class TestTerminal extends Terminal { + innerWrite(): void { this._innerWrite(); } +} let primitivePty: any; @@ -87,12 +92,12 @@ if (os.platform() !== 'win32') { /** tests */ describe('xterm output comparison', () => { - let xterm; + let xterm: TestTerminal; beforeEach(() => { - xterm = new Terminal({ cols: COLS, rows: ROWS }); + xterm = new TestTerminal({ cols: COLS, rows: ROWS }); xterm.refresh = () => {}; - xterm.viewport = { + xterm.viewport = { syncScrollArea: () => {} }; }); @@ -125,7 +130,7 @@ if (os.platform() !== 'win32') { // Perform a synchronous .write(data) xterm.writeBuffer.push(fromPty); - xterm._innerWrite(); + xterm.innerWrite(); const fromEmulator = terminalToString(xterm); console.log = CONSOLE_LOG; diff --git a/src/Terminal.ts b/src/Terminal.ts index ad33f684..92ab39e1 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -51,7 +51,7 @@ import { ITheme, ILocalizableStrings, IMarker, IDisposable } from 'xterm'; import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache'; // reg + shift key mappings for digits and special chars -const KEYCODE_KEY_MAPPINGS = { +const KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = { // digits 0-9 48: ['0', ')'], 49: ['1', '!'], @@ -1285,7 +1285,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II } } - private _innerWrite(): void { + protected _innerWrite(): void { const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE); while (writeBatch.length > 0) { const data = writeBatch.shift(); diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index f8d8657c..e6d92b56 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -36,7 +36,8 @@ export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean } }; - let myTextDecoder: TextDecoder; + // TODO: This should be typed but there seem to be issues importing the type + let myTextDecoder: any; addonTerminal.__getMessage = function(ev: MessageEvent): void { let str: string; diff --git a/tsconfig.json b/tsconfig.json index 2e7404e2..c33793f5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "outDir": "lib", "sourceMap": true, "removeComments": true, - "noUnusedLocals": true + "noUnusedLocals": true, + "noImplicitAny": true }, "include": [ "src/**/*", From 4dff8283749f0a9da60972148136f3ed2a8c6043 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 07:15:45 +0100 Subject: [PATCH 13/13] Add @types/glob --- package.json | 1 + src/utils/TestUtils.test.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 44cc2e88..5c7574ee 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "license": "MIT", "devDependencies": { "@types/chai": "^3.4.34", + "@types/glob": "^5.0.35", "@types/jsdom": "^11.0.1", "@types/mocha": "^2.2.33", "@types/node": "6.0.108", diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts index e3ae89d3..42c4d974 100644 --- a/src/utils/TestUtils.test.ts +++ b/src/utils/TestUtils.test.ts @@ -267,7 +267,7 @@ export class MockInputHandlingTerminal implements IInputHandlingTerminal { throw new Error('Method not implemented.'); } setOption(key: string, value: any): void { - this.options[key] = value; + (this.options)[key] = value; } on(type: string, listener: XtermListener): void { throw new Error('Method not implemented.');