diff --git a/addons/xterm-addon-search/package.json b/addons/xterm-addon-search/package.json
index 1913f177..445f70c9 100644
--- a/addons/xterm-addon-search/package.json
+++ b/addons/xterm-addon-search/package.json
@@ -1,6 +1,6 @@
{
"name": "xterm-addon-search",
- "version": "0.5.0",
+ "version": "0.6.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
diff --git a/addons/xterm-addon-serialize/package.json b/addons/xterm-addon-serialize/package.json
index fbf1614e..4b52e814 100644
--- a/addons/xterm-addon-serialize/package.json
+++ b/addons/xterm-addon-serialize/package.json
@@ -1,6 +1,6 @@
{
"name": "xterm-addon-serialize",
- "version": "0.1.2",
+ "version": "0.2.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
diff --git a/addons/xterm-addon-web-links/package.json b/addons/xterm-addon-web-links/package.json
index 6167de74..febcfab4 100644
--- a/addons/xterm-addon-web-links/package.json
+++ b/addons/xterm-addon-web-links/package.json
@@ -1,6 +1,6 @@
{
"name": "xterm-addon-web-links",
- "version": "0.2.1",
+ "version": "0.3.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
diff --git a/addons/xterm-addon-web-links/src/WebLinkProvider.ts b/addons/xterm-addon-web-links/src/WebLinkProvider.ts
index 23dc8560..5f6460bf 100644
--- a/addons/xterm-addon-web-links/src/WebLinkProvider.ts
+++ b/addons/xterm-addon-web-links/src/WebLinkProvider.ts
@@ -3,7 +3,7 @@
* @license MIT
*/
-import { ILinkProvider, IBufferCellPosition, ILink, Terminal, IBuffer } from 'xterm';
+import { ILinkProvider, IBufferCellPosition, ILink, Terminal } from 'xterm';
export class WebLinkProvider implements ILinkProvider {
diff --git a/addons/xterm-addon-web-links/src/WebLinksAddon.ts b/addons/xterm-addon-web-links/src/WebLinksAddon.ts
index dbc664a8..4e700b57 100644
--- a/addons/xterm-addon-web-links/src/WebLinksAddon.ts
+++ b/addons/xterm-addon-web-links/src/WebLinksAddon.ts
@@ -3,7 +3,7 @@
* @license MIT
*/
-import { Terminal, ILinkMatcherOptions, ITerminalAddon, ILinkProvider, IDisposable } from 'xterm';
+import { Terminal, ILinkMatcherOptions, ITerminalAddon, IDisposable } from 'xterm';
import { WebLinkProvider } from './WebLinkProvider';
const protocolClause = '(https?:\\/\\/)';
diff --git a/addons/xterm-addon-webgl/package.json b/addons/xterm-addon-webgl/package.json
index ca49e795..7a1a9ee5 100644
--- a/addons/xterm-addon-webgl/package.json
+++ b/addons/xterm-addon-webgl/package.json
@@ -1,6 +1,6 @@
{
"name": "xterm-addon-webgl",
- "version": "0.5.1",
+ "version": "0.6.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.api.ts b/addons/xterm-addon-webgl/src/WebglRenderer.api.ts
index 591d7fff..daf7f6fc 100644
--- a/addons/xterm-addon-webgl/src/WebglRenderer.api.ts
+++ b/addons/xterm-addon-webgl/src/WebglRenderer.api.ts
@@ -341,10 +341,6 @@ describe('WebGL Renderer Integration Tests', async () => {
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
- const cssColor = COLORS_16_TO_255[y * 16 + x];
- const r = parseInt(cssColor.substr(1, 2), 16);
- const g = parseInt(cssColor.substr(3, 2), 16);
- const b = parseInt(cssColor.substr(5, 2), 16);
await pollFor(page, () => getCellColor(x + 1, y + 1), [0, 0, 0, 255]);
}
}
@@ -670,7 +666,6 @@ describe('WebGL Renderer Integration Tests', async () => {
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
- const i = y * 16 + x;
await pollFor(page, () => getCellColor(x + 1, y + 1), [0, 0, 0, 255]);
}
}
diff --git a/bin/extract_vtfeatures.js b/bin/extract_vtfeatures.js
index e575aeab..63d09684 100644
--- a/bin/extract_vtfeatures.js
+++ b/bin/extract_vtfeatures.js
@@ -1,7 +1,7 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
- *
+ *
* Script to extract vt features documented in docstrings.
*/
const fs = require('fs');
@@ -265,7 +265,7 @@ To denote the sequences the tables use the same abbreviations as xterm does:
function hideDetailSections() {
for (let section of document.getElementsByClassName('sequence-details')) section.style.display = 'none';
}
-
+
function decorateDetailLinks() {
for (let link of document.getElementsByClassName('link-details')) {
link.addEventListener("click", toggleDetails, false);
@@ -344,11 +344,11 @@ function applyMacros(s) {
return s;
}
-function replaceStatus(s) {
- if (s === 'supported') return '✓';
- if (s === 'unsupported') return '✗';
- return s;
-}
+// function replaceStatus(s) {
+// if (s === 'supported') return '✓';
+// if (s === 'unsupported') return '✗';
+// return s;
+// }
function createAnchorSlug(s) {
return s.toLowerCase().split(' ').join('-');
diff --git a/package.json b/package.json
index b177851a..df6208c8 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
- "version": "4.4.0",
+ "version": "4.5.0",
"main": "lib/xterm.js",
"style": "css/xterm.css",
"types": "typings/xterm.d.ts",
diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts
index 60861112..3e304bcf 100644
--- a/src/browser/TestUtils.test.ts
+++ b/src/browser/TestUtils.test.ts
@@ -4,7 +4,9 @@
*/
import { IEvent, EventEmitter } from 'common/EventEmitter';
-import { ICharSizeService, IMouseService } from 'browser/services/Services';
+import { ICharSizeService, IMouseService, IRenderService } from 'browser/services/Services';
+import { IRenderDimensions, IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types';
+import { IColorSet } from 'browser/Types';
export class MockCharSizeService implements ICharSizeService {
serviceBrand: any;
@@ -24,3 +26,72 @@ export class MockMouseService implements IMouseService {
throw new Error('Not implemented');
}
}
+
+export class MockRenderService implements IRenderService {
+ serviceBrand: any;
+ onDimensionsChange: IEvent = new EventEmitter().event;
+ onRender: IEvent<{ start: number, end: number }, void> = new EventEmitter<{ start: number, end: number }>().event;
+ onRefreshRequest: IEvent<{ start: number, end: number}, void> = new EventEmitter<{ start: number, end: number }>().event;
+ dimensions: IRenderDimensions = {
+ scaledCharWidth: 0,
+ scaledCharHeight: 0,
+ scaledCellWidth: 0,
+ scaledCellHeight: 0,
+ scaledCharLeft: 0,
+ scaledCharTop: 0,
+ scaledCanvasWidth: 0,
+ scaledCanvasHeight: 0,
+ canvasWidth: 0,
+ canvasHeight: 0,
+ actualCellWidth: 0,
+ actualCellHeight: 0
+ };
+ refreshRows(start: number, end: number): void {
+ throw new Error('Method not implemented.');
+ }
+ resize(cols: number, rows: number): void {
+ throw new Error('Method not implemented.');
+ }
+ changeOptions(): void {
+ throw new Error('Method not implemented.');
+ }
+ setRenderer(renderer: IRenderer): void {
+ throw new Error('Method not implemented.');
+ }
+ setColors(colors: IColorSet): void {
+ throw new Error('Method not implemented.');
+ }
+ onDevicePixelRatioChange(): void {
+ throw new Error('Method not implemented.');
+ }
+ onResize(cols: number, rows: number): void {
+ throw new Error('Method not implemented.');
+ }
+ onCharSizeChanged(): void {
+ throw new Error('Method not implemented.');
+ }
+ onBlur(): void {
+ throw new Error('Method not implemented.');
+ }
+ onFocus(): void {
+ throw new Error('Method not implemented.');
+ }
+ onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void {
+ throw new Error('Method not implemented.');
+ }
+ onCursorMove(): void {
+ throw new Error('Method not implemented.');
+ }
+ clear(): void {
+ throw new Error('Method not implemented.');
+ }
+ registerCharacterJoiner(handler: CharacterJoinerHandler): number {
+ throw new Error('Method not implemented.');
+ }
+ deregisterCharacterJoiner(joinerId: number): boolean {
+ throw new Error('Method not implemented.');
+ }
+ dispose(): void {
+ throw new Error('Method not implemented.');
+ }
+}
diff --git a/src/browser/input/MoveToCell.ts b/src/browser/input/MoveToCell.ts
index d8f5a498..25e1844d 100644
--- a/src/browser/input/MoveToCell.ts
+++ b/src/browser/input/MoveToCell.ts
@@ -105,11 +105,6 @@ function moveToRequestedCol(startX: number, startY: number, targetX: number, tar
).length, sequence(direction, applicationCursor));
}
-function moveHorizontallyOnly(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
- const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);
- return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));
-}
-
/**
* Utility functions
*/
diff --git a/src/browser/services/SelectionService.test.ts b/src/browser/services/SelectionService.test.ts
index 62ca3819..cd787531 100644
--- a/src/browser/services/SelectionService.test.ts
+++ b/src/browser/services/SelectionService.test.ts
@@ -10,16 +10,18 @@ import { IBufferLine } from 'common/Types';
import { MockBufferService, MockOptionsService, MockCoreService } from 'common/TestUtils.test';
import { BufferLine } from 'common/buffer/BufferLine';
import { IBufferService, IOptionsService } from 'common/services/Services';
-import { MockCharSizeService, MockMouseService } from 'browser/TestUtils.test';
+import { MockMouseService, MockRenderService } from 'browser/TestUtils.test';
import { CellData } from 'common/buffer/CellData';
import { IBuffer } from 'common/buffer/Types';
+import { IRenderService } from 'browser/services/Services';
class TestSelectionService extends SelectionService {
constructor(
bufferService: IBufferService,
- optionsService: IOptionsService
+ optionsService: IOptionsService,
+ renderService: IRenderService
) {
- super(() => {}, null!, null!, new MockCharSizeService(10, 10), bufferService, new MockCoreService(), new MockMouseService(), optionsService);
+ super(() => {}, null!, null!, bufferService, new MockCoreService(), new MockMouseService(), optionsService, renderService);
}
public get model(): SelectionModel { return this._model; }
@@ -46,7 +48,10 @@ describe('SelectionService', () => {
optionsService = new MockOptionsService();
bufferService = new MockBufferService(20, 20, optionsService);
buffer = bufferService.buffer;
- selectionService = new TestSelectionService(bufferService, optionsService);
+ const renderService = new MockRenderService();
+ renderService.dimensions.canvasHeight = 10 * 20;
+ renderService.dimensions.canvasWidth = 10 * 20;
+ selectionService = new TestSelectionService(bufferService, optionsService, renderService);
});
function stringToRow(text: string): IBufferLine {
diff --git a/src/browser/services/SelectionService.ts b/src/browser/services/SelectionService.ts
index f2f46a94..45424d16 100644
--- a/src/browser/services/SelectionService.ts
+++ b/src/browser/services/SelectionService.ts
@@ -10,7 +10,7 @@ import * as Browser from 'common/Platform';
import { SelectionModel } from 'browser/selection/SelectionModel';
import { CellData } from 'common/buffer/CellData';
import { EventEmitter, IEvent } from 'common/EventEmitter';
-import { ICharSizeService, IMouseService, ISelectionService } from 'browser/services/Services';
+import { ICharSizeService, IMouseService, ISelectionService, IRenderService } from 'browser/services/Services';
import { IBufferService, IOptionsService, ICoreService } from 'common/services/Services';
import { getCoordsRelativeToElement } from 'browser/input/Mouse';
import { moveToCellSequence } from 'browser/input/MoveToCell';
@@ -116,11 +116,11 @@ export class SelectionService implements ISelectionService {
private readonly _scrollLines: (amount: number, suppressEvent: boolean) => void,
private readonly _element: HTMLElement,
private readonly _screenElement: HTMLElement,
- @ICharSizeService private readonly _charSizeService: ICharSizeService,
@IBufferService private readonly _bufferService: IBufferService,
@ICoreService private readonly _coreService: ICoreService,
@IMouseService private readonly _mouseService: IMouseService,
- @IOptionsService private readonly _optionsService: IOptionsService
+ @IOptionsService private readonly _optionsService: IOptionsService,
+ @IRenderService private readonly _renderService: IRenderService
) {
// Init listeners
this._mouseMoveListener = event => this._onMouseMove(event);
@@ -374,7 +374,7 @@ export class SelectionService implements ISelectionService {
*/
private _getMouseEventScrollAmount(event: MouseEvent): number {
let offset = getCoordsRelativeToElement(event, this._screenElement)[1];
- const terminalHeight = this._bufferService.rows * Math.ceil(this._charSizeService.height * this._optionsService.options.lineHeight);
+ const terminalHeight = this._renderService.dimensions.canvasHeight;
if (offset >= 0 && offset <= terminalHeight) {
return 0;
}
diff --git a/src/common/input/Keyboard.test.ts b/src/common/input/Keyboard.test.ts
index a304923e..0bb0e24c 100644
--- a/src/common/input/Keyboard.test.ts
+++ b/src/common/input/Keyboard.test.ts
@@ -86,6 +86,12 @@ describe('Keyboard', () => {
it('should return \\x1b[3;3~ for alt+delete', () => {
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~');
});
+ it('should return \\x1b\\r for alt+enter', () => {
+ assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 13 }).key, '\x1b\r');
+ });
+ it('should return \\x1b\\x1b for alt+esc', () => {
+ assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 27 }).key, '\x1b\x1b');
+ });
it('should return \\x1b[5D for ctrl+left', () => {
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
});
@@ -141,6 +147,10 @@ describe('Keyboard', () => {
it('should return \\x1ba for alt+a', () => {
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: true, macOptionIsMeta: true }).key, '\x1ba');
});
+
+ it('should return \\x1b\\x1b for alt+enter', () => {
+ assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 13 }, { isMac: true, macOptionIsMeta: true }).key, '\x1b\r');
+ });
});
it('should return \\x1b[5A for alt+up', () => {
diff --git a/src/common/input/Keyboard.ts b/src/common/input/Keyboard.ts
index 1bf378c1..fdb777b4 100644
--- a/src/common/input/Keyboard.ts
+++ b/src/common/input/Keyboard.ts
@@ -103,12 +103,15 @@ export function evaluateKeyboardEvent(
break;
case 13:
// return/enter
- result.key = C0.CR;
+ result.key = ev.altKey ? C0.ESC + C0.CR : C0.CR;
result.cancel = true;
break;
case 27:
// escape
result.key = C0.ESC;
+ if (ev.altKey) {
+ result.key = C0.ESC + C0.ESC;
+ }
result.cancel = true;
break;
case 37:
diff --git a/src/common/services/CoreService.ts b/src/common/services/CoreService.ts
index bc58a688..cc35d5b5 100644
--- a/src/common/services/CoreService.ts
+++ b/src/common/services/CoreService.ts
@@ -5,7 +5,7 @@
import { ICoreService, ILogService, IOptionsService, IBufferService } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
-import { IDecPrivateModes, ICharset } from 'common/Types';
+import { IDecPrivateModes } from 'common/Types';
import { clone } from 'common/Clone';
const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({