Merge branch 'master' into more_naming_conventions

This commit is contained in:
Daniel Imms
2018-06-03 07:23:14 -07:00
committed by GitHub
59 changed files with 3506 additions and 336 deletions
+2 -1
View File
@@ -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/xtermjs/xterm.js/badge.svg?branch=master)](https://coveralls.io/github/xtermjs/xterm.js?branch=master) [![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/xtermjs/xterm.js/badge.svg?branch=master)](https://coveralls.io/github/xtermjs/xterm.js?branch=master) [![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.
@@ -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.
+1
View File
@@ -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",
+57
View File
@@ -48,6 +48,63 @@ 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();
(<any> 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();
(<any> 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();
(<any> 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();
(<any> buffer.lines.get(11)).isWrapped = true;
(<any> buffer.lines.get(12)).isWrapped = true;
(<any> buffer.lines.get(13)).isWrapped = true;
(<any> 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();
(<any> 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();
(<any> 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();
(<any> buffer.lines.get(buffer.lines.length - 1)).isWrapped = true;
assert.deepEqual(buffer.getWrappedRangeForLine(buffer.lines.length - 2), { first: 22, last: 23 });
});
});
});
describe('resize', () => {
describe('column size is reduced', () => {
it('should not trim the data in the buffer', () => {
+16 -1
View File
@@ -8,6 +8,7 @@ import { LineData, CharData, ITerminal, IBuffer } from './Types';
import { EventEmitter } from './EventEmitter';
import { IDisposable, IMarker } from 'xterm';
export const DEFAULT_ATTR = (0 << 18) | (257 << 9) | (256 << 0);
export const CHAR_DATA_ATTR_INDEX = 0;
export const CHAR_DATA_CHAR_INDEX = 1;
export const CHAR_DATA_WIDTH_INDEX = 2;
@@ -116,7 +117,7 @@ export class Buffer implements IBuffer {
if (this.lines.length > 0) {
// Deal with columns increasing (we don't do anything when columns reduce)
if (this._terminal.cols < newCols) {
const ch: CharData = [this._terminal.defAttr, ' ', 1, 32]; // does xterm use the default attr?
const ch: CharData = [DEFAULT_ATTR, ' ', 1, 32]; // does xterm use the default attr?
for (let i = 0; i < this.lines.length; i++) {
while (this.lines.get(i).length < newCols) {
this.lines.get(i).push(ch);
@@ -259,6 +260,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 && (<any>this.lines.get(first)).isWrapped) {
first--;
}
// Scan downwards for wrapped lines
while (last + 1 < this.lines.length && (<any>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.
+1 -1
View File
@@ -161,7 +161,7 @@ export const wcwidth = (function(opts: {nul: number, control: number}): (ucs: nu
if (num < 127) {
return 1;
}
let t = table || initTable();
const t = table || initTable();
if (num < 65536) {
return t[num >> 4] >> ((num & 15) << 1) & 3;
}
+33 -32
View File
@@ -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(<CompositionEvent><CompositionEvent>{ 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(<CompositionEvent><CompositionEvent>{ 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(<CompositionEvent>{ data: 'ㅇ' });
textarea.value = 'ㅇ';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: '아' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
textarea.value = '아';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: '앙' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'ㅇ' });
textarea.value = '앙ㅇ';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: '아' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
textarea.value = '앙아';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: '앙' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'ㅇ' });
textarea.value = 'ㅇ';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: '아' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: '아' });
textarea.value = '아';
setTimeout(() => { // wait for any textarea updates
// Start second character '아' in first character
compositionHelper.compositionupdate({ data: '앙' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: '앙' });
textarea.value = '앙';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionend();
compositionHelper.compositionstart();
compositionHelper.compositionupdate({ data: '아' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'd' });
textarea.value = 'd';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: 'だ' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だ' });
textarea.value = 'だ';
setTimeout(() => { // wait for any textarea updates
// Second character 'あ'
compositionHelper.compositionupdate({ data: 'だあ' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'd' });
textarea.value = 'd';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: 'だ' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だ' });
textarea.value = 'だ';
setTimeout(() => { // wait for any textarea updates
// Second character 'ー'
compositionHelper.compositionupdate({ data: 'だー' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'だー' });
textarea.value = 'だー';
setTimeout(() => { // wait for any textarea updates
// Convert to katakana 'ダー'
compositionHelper.compositionupdate({ data: 'ダー' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'い' });
textarea.value = 'い';
setTimeout(() => { // wait for any textarea updates
// Second character 'ま'
compositionHelper.compositionupdate({ data: 'いm' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'いm' });
textarea.value = 'いm';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionupdate({ data: 'いま' });
compositionHelper.compositionupdate(<CompositionEvent>{ data: 'いま' });
textarea.value = 'いま';
setTimeout(() => { // wait for any textarea updates
// Convert to kanji '今'
compositionHelper.compositionupdate({ data: '今' });
compositionHelper.compositionupdate(<CompositionEvent>{ 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(<CompositionEvent>{ data: 'ㅇ' });
textarea.value = 'ㅇ';
setTimeout(() => { // wait for any textarea updates
compositionHelper.compositionend();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+71
View File
@@ -77,3 +77,74 @@ export namespace C0 {
/** Delete (Caret = ^?) */
export const DEL = '\x7f';
}
/**
* C1 control codes
* See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes
*/
export namespace C1 {
/** padding character */
export const PAD = '\x80';
/** High Octet Preset */
export const HOP = '\x81';
/** Break Permitted Here */
export const BPH = '\x82';
/** No Break Here */
export const NBH = '\x83';
/** Index */
export const IND = '\x84';
/** Next Line */
export const NEL = '\x85';
/** Start of Selected Area */
export const SSA = '\x86';
/** End of Selected Area */
export const ESA = '\x87';
/** Horizontal Tabulation Set */
export const HTS = '\x88';
/** Horizontal Tabulation With Justification */
export const HTJ = '\x89';
/** Vertical Tabulation Set */
export const VTS = '\x8a';
/** Partial Line Down */
export const PLD = '\x8b';
/** Partial Line Up */
export const PLU = '\x8c';
/** Reverse Index */
export const RI = '\x8d';
/** Single-Shift 2 */
export const SS2 = '\x8e';
/** Single-Shift 3 */
export const SS3 = '\x8f';
/** Device Control String */
export const DCS = '\x90';
/** Private Use 1 */
export const PU1 = '\x91';
/** Private Use 2 */
export const PU2 = '\x92';
/** Set Transmit State */
export const STS = '\x93';
/** Destructive backspace, intended to eliminate ambiguity about meaning of BS. */
export const CCH = '\x94';
/** Message Waiting */
export const MW = '\x95';
/** Start of Protected Area */
export const SPA = '\x96';
/** End of Protected Area */
export const EPA = '\x97';
/** Start of String */
export const SOS = '\x98';
/** Single Graphic Character Introducer */
export const SGCI = '\x99';
/** Single Character Introducer */
export const SCI = '\x9a';
/** Control Sequence Introducer */
export const CSI = '\x9b';
/** String Terminator */
export const ST = '\x9c';
/** Operating System Command */
export const OSC = '\x9d';
/** Privacy Message */
export const PM = '\x9e';
/** Application Program Command */
export const APC = '\x9f';
}
+2 -2
View File
@@ -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);
}
+17 -16
View File
@@ -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,55 +27,56 @@ 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]);
inputHandler.setCursorStyle([0], collect);
assert.equal(terminal.options['cursorStyle'], 'block');
assert.equal(terminal.options['cursorBlink'], true);
terminal.options = {};
inputHandler.setCursorStyle([1]);
inputHandler.setCursorStyle([1], collect);
assert.equal(terminal.options['cursorStyle'], 'block');
assert.equal(terminal.options['cursorBlink'], true);
terminal.options = {};
inputHandler.setCursorStyle([2]);
inputHandler.setCursorStyle([2], collect);
assert.equal(terminal.options['cursorStyle'], 'block');
assert.equal(terminal.options['cursorBlink'], false);
terminal.options = {};
inputHandler.setCursorStyle([3]);
inputHandler.setCursorStyle([3], collect);
assert.equal(terminal.options['cursorStyle'], 'underline');
assert.equal(terminal.options['cursorBlink'], true);
terminal.options = {};
inputHandler.setCursorStyle([4]);
inputHandler.setCursorStyle([4], collect);
assert.equal(terminal.options['cursorStyle'], 'underline');
assert.equal(terminal.options['cursorBlink'], false);
terminal.options = {};
inputHandler.setCursorStyle([5]);
inputHandler.setCursorStyle([5], collect);
assert.equal(terminal.options['cursorStyle'], 'bar');
assert.equal(terminal.options['cursorBlink'], true);
terminal.options = {};
inputHandler.setCursorStyle([6]);
inputHandler.setCursorStyle([6], collect);
assert.equal(terminal.options['cursorStyle'], 'bar');
assert.equal(terminal.options['cursorBlink'], false);
});
});
describe('setMode', () => {
it('should toggle Terminal.bracketedPasteMode', () => {
let terminal = new MockInputHandlingTerminal();
terminal.prefix = '?';
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]);
inputHandler.setMode([2004], collect);
assert.equal(terminal.bracketedPasteMode, true);
// Reset bracketed paste mode
inputHandler.resetMode([2004]);
inputHandler.resetMode([2004], collect);
assert.equal(terminal.bracketedPasteMode, false);
});
});
+583 -114
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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)]);
}
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -232,7 +232,7 @@ export class Parser {
if (ch in normalStateHandler) {
normalStateHandler[ch](this, this._inputHandler);
} else {
this._inputHandler.addChar(ch, code);
// this._inputHandler.addChar(ch, code);
}
break;
case ParserState.ESCAPED:
+11 -1
View File
@@ -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)]);
}
@@ -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');
(<any>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', () => {
+6 -4
View File
@@ -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();
@@ -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;
}
}
+20 -14
View File
@@ -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;
@@ -24,8 +29,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 +50,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';
@@ -87,21 +92,21 @@ 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 = <IViewport>{
syncScrollArea: () => {}
};
});
// 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,21 +123,22 @@ 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(){};
// Perform a synchronous .write(data)
xterm.writeBuffer.push(fromPty);
xterm._innerWrite();
xterm.innerWrite();
let fromEmulator = terminalToString(xterm);
const fromEmulator = terminalToString(xterm);
console.log = consoleLog;
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 +161,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'));
+37 -37
View File
@@ -77,13 +77,13 @@ describe('term.js addons', () => {
});
describe('attachCustomKeyEventHandler', () => {
let evKeyDown = <KeyboardEvent>{
const evKeyDown = <KeyboardEvent>{
preventDefault: () => {},
stopPropagation: () => {},
type: 'keydown',
keyCode: 77
};
let evKeyPress = <KeyboardEvent>{
const evKeyPress = <KeyboardEvent>{
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);
@@ -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');
@@ -302,7 +302,7 @@ describe('term.js addons', () => {
(<any>term)._evaluateKeyEscapeSequence = () => {
return { key: 'a' };
};
let event = <KeyboardEvent>{
const event = <KeyboardEvent>{
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;
});
@@ -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 = () => {};
@@ -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);
+26 -35
View File
@@ -25,14 +25,14 @@ import { ICharset, IInputHandlingTerminal, IViewport, ICompositionHelper, ITermi
import { IMouseZoneManager } from './input/Types';
import { IRenderer } from './renderer/Types';
import { BufferSet } from './BufferSet';
import { Buffer, MAX_BUFFER_SIZE } from './Buffer';
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR } from './Buffer';
import { CompositionHelper } from './CompositionHelper';
import { EventEmitter } from './EventEmitter';
import { Viewport } from './Viewport';
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard';
import { C0 } from './EscapeSequences';
import { InputHandler } from './InputHandler';
import { Parser } from './Parser';
// import { Parser } from './Parser';
import { Renderer } from './renderer/Renderer';
import { Linkifier } from './Linkifier';
import { SelectionManager } from './SelectionManager';
@@ -49,9 +49,10 @@ import { AccessibilityManager } from './AccessibilityManager';
import { ScreenDprMonitor } from './utils/ScreenDprMonitor';
import { ITheme, ILocalizableStrings, IMarker, IDisposable } from 'xterm';
import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache';
import { DomRenderer } from './renderer/dom/DomRenderer';
// 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', '!'],
@@ -123,7 +124,8 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
allowTransparency: false,
tabStopWidth: 8,
theme: null,
rightClickSelectsWord: Browser.isMac
rightClickSelectsWord: Browser.isMac,
rendererType: 'canvas'
};
export class Terminal extends EventEmitter implements ITerminal, IDisposable, IInputHandlingTerminal {
@@ -190,13 +192,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
private _refreshEnd: number;
public savedCols: number;
public defAttr: number;
public curAttr: number;
public params: (string | number)[];
public currentParam: string | number;
public prefix: string;
public postfix: string;
// user input states
public writeBuffer: string[];
@@ -218,7 +217,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
private _inputHandler: InputHandler;
public soundManager: SoundManager;
private _parser: Parser;
public renderer: IRenderer;
public selectionManager: SelectionManager;
public linkifier: ILinkifier;
@@ -280,8 +278,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;
@@ -316,13 +312,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// TODO: Can this be just []?
this.charsets = [null];
this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
this.curAttr = (0 << 18) | (257 << 9) | (256 << 0);
this.curAttr = DEFAULT_ATTR;
this.params = [];
this.currentParam = 0;
this.prefix = '';
this.postfix = '';
// user input states
this.writeBuffer = [];
@@ -333,7 +326,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this._userScrolling = false;
this._inputHandler = new InputHandler(this);
this._parser = new Parser(this._inputHandler, this);
// Reuse renderer if the Terminal is being recreated via a reset call.
this.renderer = this.renderer || null;
this.selectionManager = this.selectionManager || null;
@@ -364,8 +356,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
* back_color_erase feature for xterm.
*/
public eraseAttr(): number {
// if (this.is('screen')) return this.defAttr;
return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
// if (this.is('screen')) return DEFAULT_ATTR;
return (DEFAULT_ATTR & ~0x1ff) | (this.curAttr & 0x1ff);
}
/**
@@ -390,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];
}
/**
@@ -468,7 +456,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
}
break;
}
this[key] = value;
this.options[key] = value;
switch (key) {
case 'fontFamily':
@@ -567,7 +554,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);
@@ -706,7 +693,11 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// Performance: Add viewport and helper elements from the fragment
this.element.appendChild(fragment);
this.renderer = new Renderer(this, this.options.theme);
switch (this.options.rendererType) {
case 'canvas': this.renderer = new Renderer(this, this.options.theme); break;
case 'dom': this.renderer = new DomRenderer(this, this.options.theme); break;
default: throw new Error(`Unrecognized rendererType "${this.options.rendererType}"`);
}
this.options.theme = null;
this.viewport = new Viewport(this, this._viewportElement, this._viewportScrollArea, this.charMeasure);
this.viewport.onThemeChanged(this.renderer.colorManager.colors);
@@ -719,7 +710,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// dprchange should handle this case, we need this as well for browsers that don't support the
// matchMedia query.
this._disposables.push(Dom.addDisposableListener(window, 'resize', () => this.renderer.onWindowResize(window.devicePixelRatio)));
this.charMeasure.on('charsizechanged', () => this.renderer.onResize(this.cols, this.rows));
this.charMeasure.on('charsizechanged', () => this.renderer.onCharSizeChanged());
this.renderer.on('resize', (dimensions) => this.viewport.syncScrollArea());
this.selectionManager = new SelectionManager(this, this.charMeasure);
@@ -833,7 +824,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
@@ -944,7 +935,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
return;
}
let data: number[] = [];
const data: number[] = [];
encode(data, button);
encode(data, pos.x);
@@ -1151,7 +1142,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.
@@ -1298,7 +1289,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();
@@ -1318,8 +1309,8 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// middle of parsing escape sequence in two chunks. For some reason the
// state of the parser resets to 0 after exiting parser.parse. This change
// just sets the state back based on the correct return statement.
const state = this._parser.parse(data);
this._parser.setState(state);
this._inputHandler.parse(data);
this.updateRange(this.buffer.y);
this.refresh(this._refreshStart, this._refreshEnd);
@@ -2063,7 +2054,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
* set, the terminal's current column count would be used.
*/
public blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData {
const attr = cur ? this.eraseAttr() : this.defAttr;
const attr = cur ? this.eraseAttr() : DEFAULT_ATTR;
const ch: CharData = [attr, ' ', 1, 32 /* ' '.charCodeAt(0) */]; // width defaults to 1 halfwidth character
const line: LineData = [];
@@ -2083,14 +2074,14 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
}
/**
* If cur return the back color xterm feature attribute. Else return defAttr.
* If cur return the back color xterm feature attribute. Else return default attribute.
* @param cur
*/
public ch(cur?: boolean): CharData {
if (cur) {
return [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */];
}
return [this.defAttr, ' ', 1, 32 /* ' '.charCodeAt(0) */];
return [DEFAULT_ATTR, ' ', 1, 32 /* ' '.charCodeAt(0) */];
}
/**

Some files were not shown because too many files have changed in this diff Show More