Merge pull request #1508 from Tyriar/layering
Start of improved layering
This commit is contained in:
+3
-3
@@ -170,7 +170,7 @@ function initOptions(term) {
|
|||||||
fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
||||||
fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']
|
fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']
|
||||||
};
|
};
|
||||||
var options = Object.keys(term.options);
|
var options = Object.keys(term._core.options);
|
||||||
var booleanOptions = [];
|
var booleanOptions = [];
|
||||||
var numberOptions = [];
|
var numberOptions = [];
|
||||||
options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => {
|
options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => {
|
||||||
@@ -241,8 +241,8 @@ function initOptions(term) {
|
|||||||
function updateTerminalSize() {
|
function updateTerminalSize() {
|
||||||
var cols = parseInt(document.getElementById(`opt-cols`).value, 10);
|
var cols = parseInt(document.getElementById(`opt-cols`).value, 10);
|
||||||
var rows = parseInt(document.getElementById(`opt-rows`).value, 10);
|
var rows = parseInt(document.getElementById(`opt-rows`).value, 10);
|
||||||
var width = (cols * term.renderer.dimensions.actualCellWidth + term.viewport.scrollBarWidth).toString() + 'px';
|
var width = (cols * term._core.renderer.dimensions.actualCellWidth + term._core.viewport.scrollBarWidth).toString() + 'px';
|
||||||
var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px';
|
var height = (rows * term._core.renderer.dimensions.actualCellHeight).toString() + 'px';
|
||||||
terminalContainer.style.width = width;
|
terminalContainer.style.width = width;
|
||||||
terminalContainer.style.height = height;
|
terminalContainer.style.height = height;
|
||||||
term.fit();
|
term.fit();
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "xterm",
|
"name": "xterm",
|
||||||
"description": "Full xterm terminal, in your browser",
|
"description": "Full xterm terminal, in your browser",
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"main": "lib/Terminal.js",
|
"main": "lib/public/Terminal.js",
|
||||||
"types": "typings/xterm.d.ts",
|
"types": "typings/xterm.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+4
-3
@@ -4,13 +4,14 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CharData, IInputHandler, IDcsHandler, IEscapeSequenceParser, IBuffer, ICharset } from './Types';
|
import { CharData, IInputHandler, IDcsHandler, IEscapeSequenceParser, IBuffer } from './Types';
|
||||||
import { C0, C1 } from './EscapeSequences';
|
import { C0, C1 } from './common/data/EscapeSequences';
|
||||||
import { CHARSETS, DEFAULT_CHARSET } from './Charsets';
|
import { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets';
|
||||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, DEFAULT_ATTR } from './Buffer';
|
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, DEFAULT_ATTR } from './Buffer';
|
||||||
import { FLAGS } from './renderer/Types';
|
import { FLAGS } from './renderer/Types';
|
||||||
import { wcwidth } from './CharWidth';
|
import { wcwidth } from './CharWidth';
|
||||||
import { EscapeSequenceParser } from './EscapeSequenceParser';
|
import { EscapeSequenceParser } from './EscapeSequenceParser';
|
||||||
|
import { ICharset } from './core/Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map collect to glevel. Used in `selectCharset`.
|
* Map collect to glevel. Used in `selectCharset`.
|
||||||
|
|||||||
+2
-2
@@ -4,9 +4,9 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { C0 } from './EscapeSequences';
|
import { C0 } from './common/data/EscapeSequences';
|
||||||
import { IInputHandler, IInputHandlingTerminal } from './Types';
|
import { IInputHandler, IInputHandlingTerminal } from './Types';
|
||||||
import { CHARSETS, DEFAULT_CHARSET } from './Charsets';
|
import { CHARSETS, DEFAULT_CHARSET } from './core/data/Charsets';
|
||||||
|
|
||||||
const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};
|
const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};
|
||||||
normalStateHandler[C0.BEL] = (parser, handler) => handler.bell();
|
normalStateHandler[C0.BEL] = (parser, handler) => handler.bell();
|
||||||
|
|||||||
+5
-260
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import { assert, expect } from 'chai';
|
import { assert, expect } from 'chai';
|
||||||
import { Terminal } from './Terminal';
|
import { Terminal } from './Terminal';
|
||||||
import * as attach from './addons/attach/attach';
|
|
||||||
import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test';
|
import { MockViewport, MockCompositionHelper, MockRenderer } from './utils/TestUtils.test';
|
||||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer';
|
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer';
|
||||||
|
|
||||||
@@ -13,7 +12,6 @@ const INIT_COLS = 80;
|
|||||||
const INIT_ROWS = 24;
|
const INIT_ROWS = 24;
|
||||||
|
|
||||||
class TestTerminal extends Terminal {
|
class TestTerminal extends Terminal {
|
||||||
public evaluateKeyEscapeSequence(ev: any): {cancel: boolean, key: string, scrollLines: number} { return this._evaluateKeyEscapeSequence(<KeyboardEvent>ev); }
|
|
||||||
public keyDown(ev: any): boolean { return this._keyDown(ev); }
|
public keyDown(ev: any): boolean { return this._keyDown(ev); }
|
||||||
public keyPress(ev: any): boolean { return this._keyPress(ev); }
|
public keyPress(ev: any): boolean { return this._keyPress(ev); }
|
||||||
}
|
}
|
||||||
@@ -53,13 +51,6 @@ describe('term.js addons', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply addons with Terminal.applyAddon', () => {
|
|
||||||
Terminal.applyAddon(attach);
|
|
||||||
// Test that addon was applied successfully, adding attach to Terminal's
|
|
||||||
// prototype.
|
|
||||||
assert.equal(typeof (<any>Terminal).prototype.attach, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getOption', () => {
|
describe('getOption', () => {
|
||||||
it('should retrieve the option correctly', () => {
|
it('should retrieve the option correctly', () => {
|
||||||
// In the `options` namespace.
|
// In the `options` namespace.
|
||||||
@@ -296,22 +287,19 @@ describe('term.js addons', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('keyDown', () => {
|
describe('keyPress', () => {
|
||||||
it('should scroll down, when a key is pressed and terminal is scrolled up', () => {
|
it('should scroll down, when a key is pressed and terminal is scrolled up', () => {
|
||||||
// Override _evaluateKeyEscapeSequence to return cancel code
|
|
||||||
(<any>term)._evaluateKeyEscapeSequence = () => {
|
|
||||||
return { key: 'a' };
|
|
||||||
};
|
|
||||||
const event = <KeyboardEvent>{
|
const event = <KeyboardEvent>{
|
||||||
type: 'keydown',
|
type: 'keydown',
|
||||||
keyCode: 0,
|
key: 'a',
|
||||||
|
keyCode: 65,
|
||||||
preventDefault: () => {},
|
preventDefault: () => {},
|
||||||
stopPropagation: () => {}
|
stopPropagation: () => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
term.buffer.ydisp = 0;
|
term.buffer.ydisp = 0;
|
||||||
term.buffer.ybase = 40;
|
term.buffer.ybase = 40;
|
||||||
term.keyDown(event);
|
term.keyPress(event);
|
||||||
|
|
||||||
// Ensure that now the terminal is scrolled to bottom
|
// Ensure that now the terminal is scrolled to bottom
|
||||||
assert.equal(term.buffer.ydisp, term.buffer.ybase);
|
assert.equal(term.buffer.ydisp, term.buffer.ybase);
|
||||||
@@ -330,7 +318,7 @@ describe('term.js addons', () => {
|
|||||||
assert.equal(term.buffer.ydisp, startYDisp);
|
assert.equal(term.buffer.ydisp, startYDisp);
|
||||||
term.scrollLines(-1);
|
term.scrollLines(-1);
|
||||||
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
||||||
term.keyDown(<KeyboardEvent>{ keyCode: 0 });
|
term.keyPress(<KeyboardEvent>{ keyCode: 0 });
|
||||||
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
assert.equal(term.buffer.ydisp, startYDisp - 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -468,249 +456,6 @@ describe('term.js addons', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('evaluateKeyEscapeSequence', () => {
|
|
||||||
it('should return the correct escape sequence for unmodified keys', () => {
|
|
||||||
// Backspace
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 8 }).key, '\x7f'); // ^?
|
|
||||||
// Tab
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 9 }).key, '\t');
|
|
||||||
// Return/enter
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 13 }).key, '\r'); // CR
|
|
||||||
// Escape
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 27 }).key, '\x1b');
|
|
||||||
// Page up, page down
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~
|
|
||||||
// End, Home
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 35 }).key, '\x1b[F'); // SS3 F
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 36 }).key, '\x1b[H'); // SS3 H
|
|
||||||
// Left, up, right, down arrows
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 37 }).key, '\x1b[D'); // CSI D
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 38 }).key, '\x1b[A'); // CSI A
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 39 }).key, '\x1b[C'); // CSI C
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 40 }).key, '\x1b[B'); // CSI B
|
|
||||||
// Insert
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~
|
|
||||||
// Delete
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~
|
|
||||||
// F1-F12
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 112 }).key, '\x1bOP'); // SS3 P
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 114 }).key, '\x1bOR'); // SS3 R
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 115 }).key, '\x1bOS'); // SS3 S
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~
|
|
||||||
});
|
|
||||||
it('should return \\x1b[3;5~ for ctrl+delete', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~');
|
|
||||||
});
|
|
||||||
it('should return \\x1b[3;2~ for shift+delete', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~');
|
|
||||||
});
|
|
||||||
it('should return \\x1b[3;3~ for alt+delete', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~');
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5D for ctrl+left', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5C for ctrl+right', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5A for ctrl+up', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5B for ctrl+down', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('On non-macOS platforms', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
term.browser.isMac = false;
|
|
||||||
});
|
|
||||||
// Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
|
|
||||||
// http://unix.stackexchange.com/a/108106
|
|
||||||
it('should return \\x1b[5D for alt+left', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5C for alt+right', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
|
|
||||||
});
|
|
||||||
it('should return \\x1ba for alt+a', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('On macOS platforms', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
term.browser.isMac = true;
|
|
||||||
});
|
|
||||||
it('should return \\x1bb for alt+left', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1bb'); // CSI 5 D
|
|
||||||
});
|
|
||||||
it('should return \\x1bf for alt+right', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C
|
|
||||||
});
|
|
||||||
it('should return undefined for alt+a', () => {
|
|
||||||
assert.strictEqual(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with macOptionIsMeta', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
term.browser.isMac = true;
|
|
||||||
term.setOption('macOptionIsMeta', true);
|
|
||||||
});
|
|
||||||
it('should return \\x1ba for alt+a', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return \\x1b[5A for alt+up', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
|
|
||||||
});
|
|
||||||
it('should return \\x1b[5B for alt+down', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
|
|
||||||
});
|
|
||||||
it('should return the correct escape sequence for modified F1-F12 keys', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~');
|
|
||||||
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Characters using ctrl+alt sequences
|
|
||||||
it('should return proper sequence for ctrl+alt+a', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, ctrlKey: true, keyCode: 65 }).key, '\x1b\x01');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Characters using alt sequences (numbers)
|
|
||||||
it('should return proper sequences for alt+0', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 48 }).key, '\x1b0');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 48 }).key, '\x1b)');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+1', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 49 }).key, '\x1b1');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 49 }).key, '\x1b!');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+2', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 50 }).key, '\x1b2');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 50 }).key, '\x1b@');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+3', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 51 }).key, '\x1b3');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 51 }).key, '\x1b#');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+4', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 52 }).key, '\x1b4');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 52 }).key, '\x1b$');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+5', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 53 }).key, '\x1b5');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 53 }).key, '\x1b%');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+6', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 54 }).key, '\x1b6');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 54 }).key, '\x1b^');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+7', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 55 }).key, '\x1b7');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 55 }).key, '\x1b&');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+8', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 56 }).key, '\x1b8');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 56 }).key, '\x1b*');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+9', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 57 }).key, '\x1b9');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 57 }).key, '\x1b(');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Characters using alt sequences (special chars)
|
|
||||||
it('should return proper sequences for alt+;', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 186 }).key, '\x1b;');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 186 }).key, '\x1b:');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+=', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 187 }).key, '\x1b=');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 187 }).key, '\x1b+');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+,', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 188 }).key, '\x1b,');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 188 }).key, '\x1b<');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+-', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 189 }).key, '\x1b-');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 189 }).key, '\x1b_');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+.', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 190 }).key, '\x1b.');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 190 }).key, '\x1b>');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+/', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 191 }).key, '\x1b/');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 191 }).key, '\x1b?');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+~', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 192 }).key, '\x1b`');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 192 }).key, '\x1b~');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+[', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 219 }).key, '\x1b[');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 219 }).key, '\x1b{');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+\\', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 220 }).key, '\x1b\\');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 220 }).key, '\x1b|');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+]', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 221 }).key, '\x1b]');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 221 }).key, '\x1b}');
|
|
||||||
});
|
|
||||||
it('should return proper sequences for alt+\'', () => {
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 222 }).key, '\x1b\'');
|
|
||||||
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 222 }).key, '\x1b"');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Third level shift', () => {
|
describe('Third level shift', () => {
|
||||||
let evKeyDown: any;
|
let evKeyDown: any;
|
||||||
let evKeyPress: any;
|
let evKeyPress: any;
|
||||||
|
|||||||
+24
-379
@@ -21,7 +21,7 @@
|
|||||||
* http://linux.die.net/man/7/urxvt
|
* http://linux.die.net/man/7/urxvt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ICharset, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharData, LineData } from './Types';
|
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharData, LineData } from './Types';
|
||||||
import { IMouseZoneManager } from './input/Types';
|
import { IMouseZoneManager } from './input/Types';
|
||||||
import { IRenderer } from './renderer/Types';
|
import { IRenderer } from './renderer/Types';
|
||||||
import { BufferSet } from './BufferSet';
|
import { BufferSet } from './BufferSet';
|
||||||
@@ -30,7 +30,7 @@ import { CompositionHelper } from './CompositionHelper';
|
|||||||
import { EventEmitter } from './EventEmitter';
|
import { EventEmitter } from './EventEmitter';
|
||||||
import { Viewport } from './Viewport';
|
import { Viewport } from './Viewport';
|
||||||
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard';
|
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard';
|
||||||
import { C0 } from './EscapeSequences';
|
import { C0 } from './common/data/EscapeSequences';
|
||||||
import { InputHandler } from './InputHandler';
|
import { InputHandler } from './InputHandler';
|
||||||
// import { Parser } from './Parser';
|
// import { Parser } from './Parser';
|
||||||
import { Renderer } from './renderer/Renderer';
|
import { Renderer } from './renderer/Renderer';
|
||||||
@@ -47,37 +47,12 @@ import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
|
|||||||
import { MouseZoneManager } from './input/MouseZoneManager';
|
import { MouseZoneManager } from './input/MouseZoneManager';
|
||||||
import { AccessibilityManager } from './AccessibilityManager';
|
import { AccessibilityManager } from './AccessibilityManager';
|
||||||
import { ScreenDprMonitor } from './utils/ScreenDprMonitor';
|
import { ScreenDprMonitor } from './utils/ScreenDprMonitor';
|
||||||
import { ITheme, ILocalizableStrings, IMarker, IDisposable } from 'xterm';
|
import { ITheme, IMarker, IDisposable } from 'xterm';
|
||||||
import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache';
|
import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache';
|
||||||
import { DomRenderer } from './renderer/dom/DomRenderer';
|
import { DomRenderer } from './renderer/dom/DomRenderer';
|
||||||
|
import { IKeyboardEvent } from './common/Types';
|
||||||
// reg + shift key mappings for digits and special chars
|
import { evaluateKeyboardEvent } from './core/input/Keyboard';
|
||||||
const KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {
|
import { KeyboardResultType, ICharset } from './core/Types';
|
||||||
// digits 0-9
|
|
||||||
48: ['0', ')'],
|
|
||||||
49: ['1', '!'],
|
|
||||||
50: ['2', '@'],
|
|
||||||
51: ['3', '#'],
|
|
||||||
52: ['4', '$'],
|
|
||||||
53: ['5', '%'],
|
|
||||||
54: ['6', '^'],
|
|
||||||
55: ['7', '&'],
|
|
||||||
56: ['8', '*'],
|
|
||||||
57: ['9', '('],
|
|
||||||
|
|
||||||
// special chars
|
|
||||||
186: [';', ':'],
|
|
||||||
187: ['=', '+'],
|
|
||||||
188: [',', '<'],
|
|
||||||
189: ['-', '_'],
|
|
||||||
190: ['.', '>'],
|
|
||||||
191: ['/', '?'],
|
|
||||||
192: ['`', '~'],
|
|
||||||
219: ['[', '{'],
|
|
||||||
220: ['\\', '|'],
|
|
||||||
221: [']', '}'],
|
|
||||||
222: ['\'', '"']
|
|
||||||
};
|
|
||||||
|
|
||||||
// Let it work inside Node.js for automated testing purposes.
|
// Let it work inside Node.js for automated testing purposes.
|
||||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||||
@@ -353,10 +328,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
|||||||
return this.buffers.active;
|
return this.buffers.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get strings(): ILocalizableStrings {
|
|
||||||
return Strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* back_color_erase feature for xterm.
|
* back_color_erase feature for xterm.
|
||||||
*/
|
*/
|
||||||
@@ -772,14 +743,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the provided addon on the `Terminal` class.
|
|
||||||
* @param addon The addon to apply.
|
|
||||||
*/
|
|
||||||
public static applyAddon(addon: any): void {
|
|
||||||
addon.apply(Terminal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XTerm mouse events
|
* XTerm mouse events
|
||||||
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
||||||
@@ -1436,19 +1399,19 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
|||||||
* - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent
|
* - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent
|
||||||
* @param {KeyboardEvent} ev The keydown event to be handled.
|
* @param {KeyboardEvent} ev The keydown event to be handled.
|
||||||
*/
|
*/
|
||||||
protected _keyDown(ev: KeyboardEvent): boolean {
|
protected _keyDown(event: KeyboardEvent): boolean {
|
||||||
if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {
|
if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._compositionHelper.keydown(ev)) {
|
if (!this._compositionHelper.keydown(event)) {
|
||||||
if (this.buffer.ybase !== this.buffer.ydisp) {
|
if (this.buffer.ybase !== this.buffer.ydisp) {
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this._evaluateKeyEscapeSequence(ev);
|
const result = evaluateKeyboardEvent(event, this.applicationCursor, this.browser.isMac, this.options.macOptionIsMeta);
|
||||||
|
|
||||||
// if (result.key === C0.DC3) { // XOFF
|
// if (result.key === C0.DC3) { // XOFF
|
||||||
// this._writeStopped = true;
|
// this._writeStopped = true;
|
||||||
@@ -1456,33 +1419,38 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
|||||||
// this._writeStopped = false;
|
// this._writeStopped = false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (result.scrollLines) {
|
if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) {
|
||||||
this.scrollLines(result.scrollLines);
|
const scrollCount = this.rows - 1;
|
||||||
return this.cancel(ev, true);
|
this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount);
|
||||||
|
return this.cancel(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._isThirdLevelShift(this.browser, ev)) {
|
if (result.type === KeyboardResultType.SELECT_ALL) {
|
||||||
|
this.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isThirdLevelShift(this.browser, event)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.cancel) {
|
if (result.cancel) {
|
||||||
// The event is canceled at the end already, is this necessary?
|
// The event is canceled at the end already, is this necessary?
|
||||||
this.cancel(ev, true);
|
this.cancel(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.key) {
|
if (!result.key) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('keydown', ev);
|
this.emit('keydown', event);
|
||||||
this.emit('key', result.key, ev);
|
this.emit('key', result.key, event);
|
||||||
this.showCursor();
|
this.showCursor();
|
||||||
this.handler(result.key);
|
this.handler(result.key);
|
||||||
|
|
||||||
return this.cancel(ev, true);
|
return this.cancel(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {
|
private _isThirdLevelShift(browser: IBrowser, ev: IKeyboardEvent): boolean {
|
||||||
const thirdLevelKey =
|
const thirdLevelKey =
|
||||||
(browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
|
(browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
|
||||||
(browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
|
(browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
|
||||||
@@ -1495,329 +1463,6 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
|||||||
return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
|
return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an object that determines how a KeyboardEvent should be handled. The key of the
|
|
||||||
* returned value is the new key code to pass to the PTY.
|
|
||||||
*
|
|
||||||
* Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
|
||||||
* @param ev The keyboard event to be translated to key escape sequence.
|
|
||||||
*/
|
|
||||||
protected _evaluateKeyEscapeSequence(ev: KeyboardEvent): {cancel: boolean, key: string, scrollLines: number} {
|
|
||||||
const result: {cancel: boolean, key: string, scrollLines: number} = {
|
|
||||||
// Whether to cancel event propogation (NOTE: this may not be needed since the event is
|
|
||||||
// canceled at the end of keyDown
|
|
||||||
cancel: false,
|
|
||||||
// The new key even to emit
|
|
||||||
key: undefined,
|
|
||||||
// The number of characters to scroll, if this is defined it will cancel the event
|
|
||||||
scrollLines: undefined
|
|
||||||
};
|
|
||||||
const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);
|
|
||||||
switch (ev.keyCode) {
|
|
||||||
case 0:
|
|
||||||
if (ev.key === 'UIKeyInputUpArrow') {
|
|
||||||
if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OA';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[A';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ev.key === 'UIKeyInputLeftArrow') {
|
|
||||||
if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OD';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[D';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ev.key === 'UIKeyInputRightArrow') {
|
|
||||||
if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OC';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[C';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ev.key === 'UIKeyInputDownArrow') {
|
|
||||||
if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OB';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[B';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
// backspace
|
|
||||||
if (ev.shiftKey) {
|
|
||||||
result.key = C0.BS; // ^H
|
|
||||||
break;
|
|
||||||
} else if (ev.altKey) {
|
|
||||||
result.key = C0.ESC + C0.DEL; // \e ^?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result.key = C0.DEL; // ^?
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
// tab
|
|
||||||
if (ev.shiftKey) {
|
|
||||||
result.key = C0.ESC + '[Z';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result.key = C0.HT;
|
|
||||||
result.cancel = true;
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
// return/enter
|
|
||||||
result.key = C0.CR;
|
|
||||||
result.cancel = true;
|
|
||||||
break;
|
|
||||||
case 27:
|
|
||||||
// escape
|
|
||||||
result.key = C0.ESC;
|
|
||||||
result.cancel = true;
|
|
||||||
break;
|
|
||||||
case 37:
|
|
||||||
// left-arrow
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';
|
|
||||||
// HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards
|
|
||||||
// http://unix.stackexchange.com/a/108106
|
|
||||||
// macOS uses different escape sequences than linux
|
|
||||||
if (result.key === C0.ESC + '[1;3D') {
|
|
||||||
result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';
|
|
||||||
}
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OD';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[D';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 39:
|
|
||||||
// right-arrow
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';
|
|
||||||
// HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward
|
|
||||||
// http://unix.stackexchange.com/a/108106
|
|
||||||
// macOS uses different escape sequences than linux
|
|
||||||
if (result.key === C0.ESC + '[1;3C') {
|
|
||||||
result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';
|
|
||||||
}
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OC';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[C';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 38:
|
|
||||||
// up-arrow
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';
|
|
||||||
// HACK: Make Alt + up-arrow behave like Ctrl + up-arrow
|
|
||||||
// http://unix.stackexchange.com/a/108106
|
|
||||||
if (result.key === C0.ESC + '[1;3A') {
|
|
||||||
result.key = C0.ESC + '[1;5A';
|
|
||||||
}
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OA';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[A';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 40:
|
|
||||||
// down-arrow
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';
|
|
||||||
// HACK: Make Alt + down-arrow behave like Ctrl + down-arrow
|
|
||||||
// http://unix.stackexchange.com/a/108106
|
|
||||||
if (result.key === C0.ESC + '[1;3B') {
|
|
||||||
result.key = C0.ESC + '[1;5B';
|
|
||||||
}
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OB';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[B';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 45:
|
|
||||||
// insert
|
|
||||||
if (!ev.shiftKey && !ev.ctrlKey) {
|
|
||||||
// <Ctrl> or <Shift> + <Insert> are used to
|
|
||||||
// copy-paste on some systems.
|
|
||||||
result.key = C0.ESC + '[2~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 46:
|
|
||||||
// delete
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[3~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 36:
|
|
||||||
// home
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OH';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[H';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 35:
|
|
||||||
// end
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';
|
|
||||||
} else if (this.applicationCursor) {
|
|
||||||
result.key = C0.ESC + 'OF';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[F';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 33:
|
|
||||||
// page up
|
|
||||||
if (ev.shiftKey) {
|
|
||||||
result.scrollLines = -(this.rows - 1);
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[5~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
// page down
|
|
||||||
if (ev.shiftKey) {
|
|
||||||
result.scrollLines = this.rows - 1;
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[6~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 112:
|
|
||||||
// F1-F12
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + 'OP';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 113:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + 'OQ';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 114:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + 'OR';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 115:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + 'OS';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 116:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[15~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 117:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[17~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 118:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[18~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 119:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[19~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 120:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[20~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 121:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[21~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 122:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[23~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 123:
|
|
||||||
if (modifiers) {
|
|
||||||
result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';
|
|
||||||
} else {
|
|
||||||
result.key = C0.ESC + '[24~';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// a-z and space
|
|
||||||
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
|
|
||||||
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
|
||||||
result.key = String.fromCharCode(ev.keyCode - 64);
|
|
||||||
} else if (ev.keyCode === 32) {
|
|
||||||
// NUL
|
|
||||||
result.key = String.fromCharCode(0);
|
|
||||||
} else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
|
|
||||||
// escape, file sep, group sep, record sep, unit sep
|
|
||||||
result.key = String.fromCharCode(ev.keyCode - 51 + 27);
|
|
||||||
} else if (ev.keyCode === 56) {
|
|
||||||
// delete
|
|
||||||
result.key = String.fromCharCode(127);
|
|
||||||
} else if (ev.keyCode === 219) {
|
|
||||||
// ^[ - Control Sequence Introducer (CSI)
|
|
||||||
result.key = String.fromCharCode(27);
|
|
||||||
} else if (ev.keyCode === 220) {
|
|
||||||
// ^\ - String Terminator (ST)
|
|
||||||
result.key = String.fromCharCode(28);
|
|
||||||
} else if (ev.keyCode === 221) {
|
|
||||||
// ^] - Operating System Command (OSC)
|
|
||||||
result.key = String.fromCharCode(29);
|
|
||||||
}
|
|
||||||
} else if ((!this.browser.isMac || this.options.macOptionIsMeta) && ev.altKey && !ev.metaKey) {
|
|
||||||
// On macOS this is a third level shift when !macOptionIsMeta. Use <Esc> instead.
|
|
||||||
const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];
|
|
||||||
const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1];
|
|
||||||
if (key) {
|
|
||||||
result.key = C0.ESC + key;
|
|
||||||
} else if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
|
||||||
const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;
|
|
||||||
result.key = C0.ESC + String.fromCharCode(keyCode);
|
|
||||||
}
|
|
||||||
} else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) {
|
|
||||||
if (ev.keyCode === 65) { // cmd + a
|
|
||||||
this.selectAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the G level of the terminal
|
* Set the G level of the terminal
|
||||||
* @param g
|
* @param g
|
||||||
|
|||||||
+1
-4
@@ -6,6 +6,7 @@
|
|||||||
import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter } from 'xterm';
|
import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter } from 'xterm';
|
||||||
import { IColorSet, IRenderer } from './renderer/Types';
|
import { IColorSet, IRenderer } from './renderer/Types';
|
||||||
import { IMouseZoneManager } from './input/Types';
|
import { IMouseZoneManager } from './input/Types';
|
||||||
|
import { ICharset } from './core/Types';
|
||||||
|
|
||||||
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
|
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
|
||||||
|
|
||||||
@@ -191,10 +192,6 @@ export interface ILinkMatcher {
|
|||||||
willLinkActivate?: (event: MouseEvent, uri: string) => boolean;
|
willLinkActivate?: (event: MouseEvent, uri: string) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICharset {
|
|
||||||
[key: string]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ILinkHoverEvent {
|
export interface ILinkHoverEvent {
|
||||||
x1: number;
|
x1: number;
|
||||||
y1: number;
|
y1: number;
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ export function proposeGeometry(term: Terminal): IGeometry {
|
|||||||
const elementPaddingVer = elementPadding.top + elementPadding.bottom;
|
const elementPaddingVer = elementPadding.top + elementPadding.bottom;
|
||||||
const elementPaddingHor = elementPadding.right + elementPadding.left;
|
const elementPaddingHor = elementPadding.right + elementPadding.left;
|
||||||
const availableHeight = parentElementHeight - elementPaddingVer;
|
const availableHeight = parentElementHeight - elementPaddingVer;
|
||||||
const availableWidth = parentElementWidth - elementPaddingHor - (<any>term).viewport.scrollBarWidth;
|
const availableWidth = parentElementWidth - elementPaddingHor - (<any>term)._core.viewport.scrollBarWidth;
|
||||||
const geometry = {
|
const geometry = {
|
||||||
cols: Math.floor(availableWidth / (<any>term).renderer.dimensions.actualCellWidth),
|
cols: Math.floor(availableWidth / (<any>term)._core.renderer.dimensions.actualCellWidth),
|
||||||
rows: Math.floor(availableHeight / (<any>term).renderer.dimensions.actualCellHeight)
|
rows: Math.floor(availableHeight / (<any>term)._core.renderer.dimensions.actualCellHeight)
|
||||||
};
|
};
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ export function fit(term: Terminal): void {
|
|||||||
if (geometry) {
|
if (geometry) {
|
||||||
// Force a full render
|
// Force a full render
|
||||||
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
|
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
|
||||||
(<any>term).renderer.clear();
|
(<any>term)._core.renderer.clear();
|
||||||
term.resize(geometry.cols, geometry.rows);
|
term.resize(geometry.cols, geometry.rows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,17 @@
|
|||||||
|
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
|
|
||||||
export interface ISearchAddonTerminal extends Terminal {
|
// TODO: Don't rely on this private API
|
||||||
__searchHelper?: ISearchHelper;
|
export interface ITerminalCore {
|
||||||
|
|
||||||
// TODO: Reuse ITerminal from core
|
|
||||||
buffer: any;
|
buffer: any;
|
||||||
selectionManager: any;
|
selectionManager: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISearchAddonTerminal extends Terminal {
|
||||||
|
__searchHelper?: ISearchHelper;
|
||||||
|
_core: ITerminalCore;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ISearchHelper {
|
export interface ISearchHelper {
|
||||||
findNext(term: string): boolean;
|
findNext(term: string): boolean;
|
||||||
findPrevious(term: string): boolean;
|
findPrevious(term: string): boolean;
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ export class SearchHelper implements ISearchHelper {
|
|||||||
|
|
||||||
let result: ISearchResult;
|
let result: ISearchResult;
|
||||||
|
|
||||||
let startRow = this._terminal.buffer.ydisp;
|
let startRow = this._terminal._core.buffer.ydisp;
|
||||||
if (this._terminal.selectionManager.selectionEnd) {
|
if (this._terminal._core.selectionManager.selectionEnd) {
|
||||||
// Start from the selection end if there is a selection
|
// Start from the selection end if there is a selection
|
||||||
startRow = this._terminal.selectionManager.selectionEnd[1];
|
startRow = this._terminal._core.selectionManager.selectionEnd[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search from ydisp + 1 to end
|
// Search from ydisp + 1 to end
|
||||||
for (let y = startRow + 1; y < this._terminal.buffer.ybase + this._terminal.rows; y++) {
|
for (let y = startRow + 1; y < this._terminal._core.buffer.ybase + this._terminal.rows; y++) {
|
||||||
result = this._findInLine(term, y);
|
result = this._findInLine(term, y);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
@@ -76,10 +76,10 @@ export class SearchHelper implements ISearchHelper {
|
|||||||
|
|
||||||
let result: ISearchResult;
|
let result: ISearchResult;
|
||||||
|
|
||||||
let startRow = this._terminal.buffer.ydisp;
|
let startRow = this._terminal._core.buffer.ydisp;
|
||||||
if (this._terminal.selectionManager.selectionStart) {
|
if (this._terminal._core.selectionManager.selectionStart) {
|
||||||
// Start from the selection end if there is a selection
|
// Start from the selection end if there is a selection
|
||||||
startRow = this._terminal.selectionManager.selectionStart[1];
|
startRow = this._terminal._core.selectionManager.selectionStart[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search from ydisp + 1 to end
|
// Search from ydisp + 1 to end
|
||||||
@@ -92,7 +92,7 @@ export class SearchHelper implements ISearchHelper {
|
|||||||
|
|
||||||
// Search from the top to the current ydisp
|
// Search from the top to the current ydisp
|
||||||
if (!result) {
|
if (!result) {
|
||||||
for (let y = this._terminal.buffer.ybase + this._terminal.rows - 1; y > startRow; y--) {
|
for (let y = this._terminal._core.buffer.ybase + this._terminal.rows - 1; y > startRow; y--) {
|
||||||
result = this._findInLine(term, y);
|
result = this._findInLine(term, y);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
@@ -111,11 +111,11 @@ export class SearchHelper implements ISearchHelper {
|
|||||||
* @return The search result if it was found.
|
* @return The search result if it was found.
|
||||||
*/
|
*/
|
||||||
private _findInLine(term: string, y: number): ISearchResult {
|
private _findInLine(term: string, y: number): ISearchResult {
|
||||||
const lowerStringLine = this._terminal.buffer.translateBufferLineToString(y, true).toLowerCase();
|
const lowerStringLine = this._terminal._core.buffer.translateBufferLineToString(y, true).toLowerCase();
|
||||||
const lowerTerm = term.toLowerCase();
|
const lowerTerm = term.toLowerCase();
|
||||||
let searchIndex = lowerStringLine.indexOf(lowerTerm);
|
let searchIndex = lowerStringLine.indexOf(lowerTerm);
|
||||||
if (searchIndex >= 0) {
|
if (searchIndex >= 0) {
|
||||||
const line = this._terminal.buffer.lines.get(y);
|
const line = this._terminal._core.buffer.lines.get(y);
|
||||||
for (let i = 0; i < searchIndex; i++) {
|
for (let i = 0; i < searchIndex; i++) {
|
||||||
const charData = line[i];
|
const charData = line[i];
|
||||||
// Adjust the searchIndex to normalize emoji into single chars
|
// Adjust the searchIndex to normalize emoji into single chars
|
||||||
@@ -147,8 +147,8 @@ export class SearchHelper implements ISearchHelper {
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this._terminal.selectionManager.setSelection(result.col, result.row, result.term.length);
|
this._terminal._core.selectionManager.setSelection(result.col, result.row, result.term.length);
|
||||||
this._terminal.scrollLines(result.row - this._terminal.buffer.ydisp);
|
this._terminal.scrollLines(result.row - this._terminal._core.buffer.ydisp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
|
|
||||||
export interface IWinptyCompatAddonTerminal extends Terminal {
|
export interface ITerminalCore {
|
||||||
buffer: any;
|
buffer: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IWinptyCompatAddonTerminal extends Terminal {
|
||||||
|
_core: ITerminalCore;
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ export function winptyCompatInit(terminal: Terminal): void {
|
|||||||
// Windows when text reaches the end of the terminal it's likely going to be
|
// Windows when text reaches the end of the terminal it's likely going to be
|
||||||
// wrapped.
|
// wrapped.
|
||||||
addonTerminal.on('linefeed', () => {
|
addonTerminal.on('linefeed', () => {
|
||||||
const line = addonTerminal.buffer.lines.get(addonTerminal.buffer.ybase + addonTerminal.buffer.y - 1);
|
const line = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y - 1);
|
||||||
const lastChar = line[addonTerminal.cols - 1];
|
const lastChar = line[addonTerminal.cols - 1];
|
||||||
|
|
||||||
if (lastChar[3] !== 32 /* ' ' */) {
|
if (lastChar[3] !== 32 /* ' ' */) {
|
||||||
const nextLine = addonTerminal.buffer.lines.get(addonTerminal.buffer.ybase + addonTerminal.buffer.y);
|
const nextLine = addonTerminal._core.buffer.lines.get(addonTerminal._core.buffer.ybase + addonTerminal._core.buffer.y);
|
||||||
(<any>nextLine).isWrapped = true;
|
(<any>nextLine).isWrapped = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A keyboard event interface which does not depend on the DOM, KeyboardEvent implicitly extends
|
||||||
|
* this event.
|
||||||
|
*/
|
||||||
|
export interface IKeyboardEvent {
|
||||||
|
altKey: boolean;
|
||||||
|
ctrlKey: boolean;
|
||||||
|
shiftKey: boolean;
|
||||||
|
metaKey: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
key: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const enum KeyboardResultType {
|
||||||
|
SEND_KEY,
|
||||||
|
SELECT_ALL,
|
||||||
|
PAGE_UP,
|
||||||
|
PAGE_DOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IKeyboardResult {
|
||||||
|
type: KeyboardResultType;
|
||||||
|
cancel: boolean;
|
||||||
|
key: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ICharset {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ICharset } from './Types';
|
import { ICharset } from '../Types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The character sets supported by the terminal. These enable several languages
|
* The character sets supported by the terminal. These enable several languages
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
import { evaluateKeyboardEvent } from './Keyboard';
|
||||||
|
import { IKeyboardResult } from '../Types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function for testing which allows passing in a partial event and defaults will be filled
|
||||||
|
* in on it.
|
||||||
|
*/
|
||||||
|
function testEvaluateKeyboardEvent(partialEvent: {
|
||||||
|
altKey?: boolean;
|
||||||
|
ctrlKey?: boolean;
|
||||||
|
shiftKey?: boolean;
|
||||||
|
metaKey?: boolean;
|
||||||
|
keyCode?: number;
|
||||||
|
key?: string;
|
||||||
|
type?: string;
|
||||||
|
}, partialOptions: {
|
||||||
|
applicationCursorMode?: boolean;
|
||||||
|
isMac?: boolean;
|
||||||
|
macOptionIsMeta?: boolean;
|
||||||
|
} = {}): IKeyboardResult {
|
||||||
|
const event = {
|
||||||
|
altKey: partialEvent.altKey || false,
|
||||||
|
ctrlKey: partialEvent.ctrlKey || false,
|
||||||
|
shiftKey: partialEvent.shiftKey || false,
|
||||||
|
metaKey: partialEvent.metaKey || false,
|
||||||
|
keyCode: partialEvent.keyCode !== undefined ? partialEvent.keyCode : undefined,
|
||||||
|
key: partialEvent.key || '',
|
||||||
|
type: partialEvent.type || ''
|
||||||
|
};
|
||||||
|
const options = {
|
||||||
|
applicationCursorMode: partialOptions.applicationCursorMode || false,
|
||||||
|
isMac: partialOptions.isMac || false,
|
||||||
|
macOptionIsMeta: partialOptions.macOptionIsMeta || false
|
||||||
|
};
|
||||||
|
return evaluateKeyboardEvent(event, options.applicationCursorMode, options.isMac, options.macOptionIsMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Keyboard', () => {
|
||||||
|
describe('evaluateKeyEscapeSequence', () => {
|
||||||
|
it('should return the correct escape sequence for unmodified keys', () => {
|
||||||
|
// Backspace
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 8 }).key, '\x7f'); // ^?
|
||||||
|
// Tab
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 9 }).key, '\t');
|
||||||
|
// Return/enter
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 13 }).key, '\r'); // CR
|
||||||
|
// Escape
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 27 }).key, '\x1b');
|
||||||
|
// Page up, page down
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~
|
||||||
|
// End, Home
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 35 }).key, '\x1b[F'); // SS3 F
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 36 }).key, '\x1b[H'); // SS3 H
|
||||||
|
// Left, up, right, down arrows
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 37 }).key, '\x1b[D'); // CSI D
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 38 }).key, '\x1b[A'); // CSI A
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 39 }).key, '\x1b[C'); // CSI C
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 40 }).key, '\x1b[B'); // CSI B
|
||||||
|
// Insert
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~
|
||||||
|
// Delete
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~
|
||||||
|
// F1-F12
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 112 }).key, '\x1bOP'); // SS3 P
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 114 }).key, '\x1bOR'); // SS3 R
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 115 }).key, '\x1bOS'); // SS3 S
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~
|
||||||
|
});
|
||||||
|
it('should return \\x1b[3;5~ for ctrl+delete', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~');
|
||||||
|
});
|
||||||
|
it('should return \\x1b[3;2~ for shift+delete', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~');
|
||||||
|
});
|
||||||
|
it('should return \\x1b[3;3~ for alt+delete', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~');
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5D for ctrl+left', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5C for ctrl+right', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5A for ctrl+up', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5B for ctrl+down', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('On non-macOS platforms', () => {
|
||||||
|
// Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
|
||||||
|
// http://unix.stackexchange.com/a/108106
|
||||||
|
it('should return \\x1b[5D for alt+left', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 37 }, { isMac: false }).key, '\x1b[1;5D'); // CSI 5 D
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5C for alt+right', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 39 }, { isMac: false }).key, '\x1b[1;5C'); // CSI 5 C
|
||||||
|
});
|
||||||
|
it('should return \\x1ba for alt+a', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: false }).key, '\x1ba');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('On macOS platforms', () => {
|
||||||
|
it('should return \\x1bb for alt+left', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 37 }, { isMac: true }).key, '\x1bb'); // CSI 5 D
|
||||||
|
});
|
||||||
|
it('should return \\x1bf for alt+right', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 39 }, { isMac: true }).key, '\x1bf'); // CSI 5 C
|
||||||
|
});
|
||||||
|
it('should return undefined for alt+a', () => {
|
||||||
|
assert.strictEqual(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: true }).key, undefined), { isMac: true };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with macOptionIsMeta', () => {
|
||||||
|
it('should return \\x1ba for alt+a', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: true, macOptionIsMeta: true }).key, '\x1ba');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return \\x1b[5A for alt+up', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
|
||||||
|
});
|
||||||
|
it('should return \\x1b[5B for alt+down', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
|
||||||
|
});
|
||||||
|
it('should return the correct escape sequence for modified F1-F12 keys', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~');
|
||||||
|
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Characters using ctrl+alt sequences
|
||||||
|
it('should return proper sequence for ctrl+alt+a', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, ctrlKey: true, keyCode: 65 }).key, '\x1b\x01');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Characters using alt sequences (numbers)
|
||||||
|
it('should return proper sequences for alt+0', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 48 }).key, '\x1b0');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 48 }).key, '\x1b)');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+1', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 49 }).key, '\x1b1');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 49 }).key, '\x1b!');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+2', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 50 }).key, '\x1b2');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 50 }).key, '\x1b@');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+3', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 51 }).key, '\x1b3');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 51 }).key, '\x1b#');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+4', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 52 }).key, '\x1b4');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 52 }).key, '\x1b$');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+5', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 53 }).key, '\x1b5');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 53 }).key, '\x1b%');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+6', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 54 }).key, '\x1b6');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 54 }).key, '\x1b^');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+7', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 55 }).key, '\x1b7');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 55 }).key, '\x1b&');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+8', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 56 }).key, '\x1b8');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 56 }).key, '\x1b*');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+9', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 57 }).key, '\x1b9');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 57 }).key, '\x1b(');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Characters using alt sequences (special chars)
|
||||||
|
it('should return proper sequences for alt+;', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 186 }).key, '\x1b;');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 186 }).key, '\x1b:');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+=', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 187 }).key, '\x1b=');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 187 }).key, '\x1b+');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+,', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 188 }).key, '\x1b,');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 188 }).key, '\x1b<');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+-', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 189 }).key, '\x1b-');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 189 }).key, '\x1b_');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+.', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 190 }).key, '\x1b.');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 190 }).key, '\x1b>');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+/', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 191 }).key, '\x1b/');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 191 }).key, '\x1b?');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+~', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 192 }).key, '\x1b`');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 192 }).key, '\x1b~');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+[', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 219 }).key, '\x1b[');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 219 }).key, '\x1b{');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+\\', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 220 }).key, '\x1b\\');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 220 }).key, '\x1b|');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+]', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 221 }).key, '\x1b]');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 221 }).key, '\x1b}');
|
||||||
|
});
|
||||||
|
it('should return proper sequences for alt+\'', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 222 }).key, '\x1b\'');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 222 }).key, '\x1b"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle mobile arrow events', () => {
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputUpArrow' }).key, '\x1b[A');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputUpArrow' }, { applicationCursorMode: true }).key, '\x1bOA');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputLeftArrow' }).key, '\x1b[D');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputLeftArrow' }, { applicationCursorMode: true }).key, '\x1bOD');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputRightArrow' }).key, '\x1b[C');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputRightArrow' }, { applicationCursorMode: true }).key, '\x1bOC');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputDownArrow' }).key, '\x1b[B');
|
||||||
|
assert.equal(testEvaluateKeyboardEvent({ keyCode: 0, key: 'UIKeyInputDownArrow' }, { applicationCursorMode: true }).key, '\x1bOB');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,357 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||||
|
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IKeyboardEvent } from '../../common/Types';
|
||||||
|
import { IKeyboardResult, KeyboardResultType } from '../Types';
|
||||||
|
import { C0 } from '../../common/data/EscapeSequences';
|
||||||
|
|
||||||
|
// reg + shift key mappings for digits and special chars
|
||||||
|
const KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = {
|
||||||
|
// digits 0-9
|
||||||
|
48: ['0', ')'],
|
||||||
|
49: ['1', '!'],
|
||||||
|
50: ['2', '@'],
|
||||||
|
51: ['3', '#'],
|
||||||
|
52: ['4', '$'],
|
||||||
|
53: ['5', '%'],
|
||||||
|
54: ['6', '^'],
|
||||||
|
55: ['7', '&'],
|
||||||
|
56: ['8', '*'],
|
||||||
|
57: ['9', '('],
|
||||||
|
|
||||||
|
// special chars
|
||||||
|
186: [';', ':'],
|
||||||
|
187: ['=', '+'],
|
||||||
|
188: [',', '<'],
|
||||||
|
189: ['-', '_'],
|
||||||
|
190: ['.', '>'],
|
||||||
|
191: ['/', '?'],
|
||||||
|
192: ['`', '~'],
|
||||||
|
219: ['[', '{'],
|
||||||
|
220: ['\\', '|'],
|
||||||
|
221: [']', '}'],
|
||||||
|
222: ['\'', '"']
|
||||||
|
};
|
||||||
|
|
||||||
|
export function evaluateKeyboardEvent(
|
||||||
|
ev: IKeyboardEvent,
|
||||||
|
applicationCursorMode: boolean,
|
||||||
|
isMac: boolean,
|
||||||
|
macOptionIsMeta: boolean
|
||||||
|
): IKeyboardResult {
|
||||||
|
const result: IKeyboardResult = {
|
||||||
|
type: KeyboardResultType.SEND_KEY,
|
||||||
|
// Whether to cancel event propogation (NOTE: this may not be needed since the event is
|
||||||
|
// canceled at the end of keyDown
|
||||||
|
cancel: false,
|
||||||
|
// The new key even to emit
|
||||||
|
key: undefined
|
||||||
|
};
|
||||||
|
const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);
|
||||||
|
switch (ev.keyCode) {
|
||||||
|
case 0:
|
||||||
|
if (ev.key === 'UIKeyInputUpArrow') {
|
||||||
|
if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OA';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ev.key === 'UIKeyInputLeftArrow') {
|
||||||
|
if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OD';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[D';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ev.key === 'UIKeyInputRightArrow') {
|
||||||
|
if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OC';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[C';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ev.key === 'UIKeyInputDownArrow') {
|
||||||
|
if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OB';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[B';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
// backspace
|
||||||
|
if (ev.shiftKey) {
|
||||||
|
result.key = C0.BS; // ^H
|
||||||
|
break;
|
||||||
|
} else if (ev.altKey) {
|
||||||
|
result.key = C0.ESC + C0.DEL; // \e ^?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.key = C0.DEL; // ^?
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
// tab
|
||||||
|
if (ev.shiftKey) {
|
||||||
|
result.key = C0.ESC + '[Z';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.key = C0.HT;
|
||||||
|
result.cancel = true;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
// return/enter
|
||||||
|
result.key = C0.CR;
|
||||||
|
result.cancel = true;
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
// escape
|
||||||
|
result.key = C0.ESC;
|
||||||
|
result.cancel = true;
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
// left-arrow
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';
|
||||||
|
// HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards
|
||||||
|
// http://unix.stackexchange.com/a/108106
|
||||||
|
// macOS uses different escape sequences than linux
|
||||||
|
if (result.key === C0.ESC + '[1;3D') {
|
||||||
|
result.key = isMac ? C0.ESC + 'b' : C0.ESC + '[1;5D';
|
||||||
|
}
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OD';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[D';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
// right-arrow
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';
|
||||||
|
// HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward
|
||||||
|
// http://unix.stackexchange.com/a/108106
|
||||||
|
// macOS uses different escape sequences than linux
|
||||||
|
if (result.key === C0.ESC + '[1;3C') {
|
||||||
|
result.key = isMac ? C0.ESC + 'f' : C0.ESC + '[1;5C';
|
||||||
|
}
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OC';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[C';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
// up-arrow
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';
|
||||||
|
// HACK: Make Alt + up-arrow behave like Ctrl + up-arrow
|
||||||
|
// http://unix.stackexchange.com/a/108106
|
||||||
|
if (result.key === C0.ESC + '[1;3A') {
|
||||||
|
result.key = C0.ESC + '[1;5A';
|
||||||
|
}
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OA';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[A';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
// down-arrow
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';
|
||||||
|
// HACK: Make Alt + down-arrow behave like Ctrl + down-arrow
|
||||||
|
// http://unix.stackexchange.com/a/108106
|
||||||
|
if (result.key === C0.ESC + '[1;3B') {
|
||||||
|
result.key = C0.ESC + '[1;5B';
|
||||||
|
}
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OB';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[B';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
// insert
|
||||||
|
if (!ev.shiftKey && !ev.ctrlKey) {
|
||||||
|
// <Ctrl> or <Shift> + <Insert> are used to
|
||||||
|
// copy-paste on some systems.
|
||||||
|
result.key = C0.ESC + '[2~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
// delete
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[3~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
// home
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OH';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[H';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
// end
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';
|
||||||
|
} else if (applicationCursorMode) {
|
||||||
|
result.key = C0.ESC + 'OF';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[F';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
// page up
|
||||||
|
if (ev.shiftKey) {
|
||||||
|
result.type = KeyboardResultType.PAGE_UP;
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[5~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
// page down
|
||||||
|
if (ev.shiftKey) {
|
||||||
|
result.type = KeyboardResultType.PAGE_DOWN;
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[6~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 112:
|
||||||
|
// F1-F12
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + 'OP';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 113:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + 'OQ';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 114:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + 'OR';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 115:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + 'OS';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 116:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[15~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 117:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[17~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 118:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[18~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 119:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[19~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 120:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[20~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 121:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[21~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 122:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[23~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 123:
|
||||||
|
if (modifiers) {
|
||||||
|
result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';
|
||||||
|
} else {
|
||||||
|
result.key = C0.ESC + '[24~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// a-z and space
|
||||||
|
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
|
||||||
|
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
||||||
|
result.key = String.fromCharCode(ev.keyCode - 64);
|
||||||
|
} else if (ev.keyCode === 32) {
|
||||||
|
// NUL
|
||||||
|
result.key = String.fromCharCode(0);
|
||||||
|
} else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
|
||||||
|
// escape, file sep, group sep, record sep, unit sep
|
||||||
|
result.key = String.fromCharCode(ev.keyCode - 51 + 27);
|
||||||
|
} else if (ev.keyCode === 56) {
|
||||||
|
// delete
|
||||||
|
result.key = String.fromCharCode(127);
|
||||||
|
} else if (ev.keyCode === 219) {
|
||||||
|
// ^[ - Control Sequence Introducer (CSI)
|
||||||
|
result.key = String.fromCharCode(27);
|
||||||
|
} else if (ev.keyCode === 220) {
|
||||||
|
// ^\ - String Terminator (ST)
|
||||||
|
result.key = String.fromCharCode(28);
|
||||||
|
} else if (ev.keyCode === 221) {
|
||||||
|
// ^] - Operating System Command (OSC)
|
||||||
|
result.key = String.fromCharCode(29);
|
||||||
|
}
|
||||||
|
} else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) {
|
||||||
|
// On macOS this is a third level shift when !macOptionIsMeta. Use <Esc> instead.
|
||||||
|
const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode];
|
||||||
|
const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1];
|
||||||
|
if (key) {
|
||||||
|
result.key = C0.ESC + key;
|
||||||
|
} else if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
||||||
|
const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32;
|
||||||
|
result.key = C0.ESC + String.fromCharCode(keyCode);
|
||||||
|
}
|
||||||
|
} else if (isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) {
|
||||||
|
if (ev.keyCode === 65) { // cmd + a
|
||||||
|
result.type = KeyboardResultType.SELECT_ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ITerminal, ICircularList, LineData } from '../Types';
|
import { ITerminal, ICircularList, LineData } from '../Types';
|
||||||
import { C0 } from '../EscapeSequences';
|
import { C0 } from '../common/data/EscapeSequences';
|
||||||
|
|
||||||
const enum Direction {
|
const enum Direction {
|
||||||
UP = 'A',
|
UP = 'A',
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016 The xterm.js authors. All rights reserved.
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { assert } from 'chai';
|
||||||
|
import { Terminal } from './Terminal';
|
||||||
|
import * as attach from '../addons/attach/attach';
|
||||||
|
|
||||||
|
describe('Terminal', () => {
|
||||||
|
it('should apply addons with Terminal.applyAddon', () => {
|
||||||
|
Terminal.applyAddon(attach);
|
||||||
|
// Test that addon was applied successfully, adding attach to Terminal's
|
||||||
|
// prototype.
|
||||||
|
assert.equal(typeof (<any>Terminal).prototype.attach, 'function');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings } from 'xterm';
|
||||||
|
import { ITerminal } from '../Types';
|
||||||
|
import { Terminal as TerminalCore } from '../Terminal';
|
||||||
|
import * as Strings from '../Strings';
|
||||||
|
|
||||||
|
export class Terminal implements ITerminalApi {
|
||||||
|
private _core: ITerminal;
|
||||||
|
|
||||||
|
constructor(options?: ITerminalOptions) {
|
||||||
|
this._core = new TerminalCore(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get element(): HTMLElement { return this._core.element; }
|
||||||
|
public get textarea(): HTMLTextAreaElement { return this._core.textarea; }
|
||||||
|
public get rows(): number { return this._core.rows; }
|
||||||
|
public get cols(): number { return this._core.cols; }
|
||||||
|
public get markers(): IMarker[] { return this._core.markers; }
|
||||||
|
public blur(): void {
|
||||||
|
this._core.blur();
|
||||||
|
}
|
||||||
|
public focus(): void {
|
||||||
|
this._core.focus();
|
||||||
|
}
|
||||||
|
public on(type: 'blur' | 'focus' | 'linefeed' | 'selection', listener: () => void): void;
|
||||||
|
public on(type: 'data', listener: (...args: any[]) => void): void;
|
||||||
|
public on(type: 'key', listener: (key?: string, event?: KeyboardEvent) => void): void;
|
||||||
|
public on(type: 'keypress' | 'keydown', listener: (event?: KeyboardEvent) => void): void;
|
||||||
|
public on(type: 'refresh', listener: (data?: { start: number; end: number; }) => void): void;
|
||||||
|
public on(type: 'resize', listener: (data?: { cols: number; rows: number; }) => void): void;
|
||||||
|
public on(type: 'scroll', listener: (ydisp?: number) => void): void;
|
||||||
|
public on(type: 'title', listener: (title?: string) => void): void;
|
||||||
|
public on(type: string, listener: (...args: any[]) => void): void;
|
||||||
|
public on(type: any, listener: any): void {
|
||||||
|
this._core.on(type, listener);
|
||||||
|
}
|
||||||
|
public off(type: string, listener: (...args: any[]) => void): void {
|
||||||
|
this._core.off(type, listener);
|
||||||
|
}
|
||||||
|
public emit(type: string, data?: any): void {
|
||||||
|
this._core.emit(type, data);
|
||||||
|
}
|
||||||
|
public addDisposableListener(type: string, handler: (...args: any[]) => void): IDisposable {
|
||||||
|
return this.addDisposableListener(type, handler);
|
||||||
|
}
|
||||||
|
public resize(columns: number, rows: number): void {
|
||||||
|
this._core.resize(columns, rows);
|
||||||
|
}
|
||||||
|
public writeln(data: string): void {
|
||||||
|
this._core.writeln(data);
|
||||||
|
}
|
||||||
|
public open(parent: HTMLElement): void {
|
||||||
|
this._core.open(parent);
|
||||||
|
}
|
||||||
|
public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {
|
||||||
|
this._core.attachCustomKeyEventHandler(customKeyEventHandler);
|
||||||
|
}
|
||||||
|
public registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => void, options?: ILinkMatcherOptions): number {
|
||||||
|
return this._core.registerLinkMatcher(regex, handler, options);
|
||||||
|
}
|
||||||
|
public deregisterLinkMatcher(matcherId: number): void {
|
||||||
|
this._core.deregisterLinkMatcher(matcherId);
|
||||||
|
}
|
||||||
|
public addMarker(cursorYOffset: number): IMarker {
|
||||||
|
return this._core.addMarker(cursorYOffset);
|
||||||
|
}
|
||||||
|
public hasSelection(): boolean {
|
||||||
|
return this._core.hasSelection();
|
||||||
|
}
|
||||||
|
public getSelection(): string {
|
||||||
|
return this._core.getSelection();
|
||||||
|
}
|
||||||
|
public clearSelection(): void {
|
||||||
|
this._core.clearSelection();
|
||||||
|
}
|
||||||
|
public selectAll(): void {
|
||||||
|
this._core.selectAll();
|
||||||
|
}
|
||||||
|
public selectLines(start: number, end: number): void {
|
||||||
|
this._core.selectLines(start, end);
|
||||||
|
}
|
||||||
|
public dispose(): void {
|
||||||
|
this._core.dispose();
|
||||||
|
}
|
||||||
|
public destroy(): void {
|
||||||
|
this._core.destroy();
|
||||||
|
}
|
||||||
|
public scrollLines(amount: number): void {
|
||||||
|
this._core.scrollLines(amount);
|
||||||
|
}
|
||||||
|
public scrollPages(pageCount: number): void {
|
||||||
|
this._core.scrollPages(pageCount);
|
||||||
|
}
|
||||||
|
public scrollToTop(): void {
|
||||||
|
this._core.scrollToTop();
|
||||||
|
}
|
||||||
|
public scrollToBottom(): void {
|
||||||
|
this._core.scrollToBottom();
|
||||||
|
}
|
||||||
|
public scrollToLine(line: number): void {
|
||||||
|
this._core.scrollToLine(line);
|
||||||
|
}
|
||||||
|
public clear(): void {
|
||||||
|
this._core.clear();
|
||||||
|
}
|
||||||
|
public write(data: string): void {
|
||||||
|
this._core.write(data);
|
||||||
|
}
|
||||||
|
public getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold' | 'rendererType' | 'termName'): string;
|
||||||
|
public getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean;
|
||||||
|
public getOption(key: 'colors'): string[];
|
||||||
|
public getOption(key: 'cols' | 'fontSize' | 'letterSpacing' | 'lineHeight' | 'rows' | 'tabStopWidth' | 'scrollback'): number;
|
||||||
|
public getOption(key: 'handler'): (data: string) => void;
|
||||||
|
public getOption(key: string): any;
|
||||||
|
public getOption(key: any): any {
|
||||||
|
return this._core.getOption(key);
|
||||||
|
}
|
||||||
|
public setOption(key: 'bellSound' | 'fontFamily' | 'termName', value: string): void;
|
||||||
|
public setOption(key: 'fontWeight' | 'fontWeightBold', value: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'): void;
|
||||||
|
public setOption(key: 'bellStyle', value: 'none' | 'visual' | 'sound' | 'both'): void;
|
||||||
|
public setOption(key: 'cursorStyle', value: 'block' | 'underline' | 'bar'): void;
|
||||||
|
public setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void;
|
||||||
|
public setOption(key: 'colors', value: string[]): void;
|
||||||
|
public setOption(key: 'fontSize' | 'letterSpacing' | 'lineHeight' | 'tabStopWidth' | 'scrollback', value: number): void;
|
||||||
|
public setOption(key: 'handler', value: (data: string) => void): void;
|
||||||
|
public setOption(key: 'theme', value: ITheme): void;
|
||||||
|
public setOption(key: 'cols' | 'rows', value: number): void;
|
||||||
|
public setOption(key: string, value: any): void;
|
||||||
|
public setOption(key: any, value: any): void {
|
||||||
|
this._core.setOption(key, value);
|
||||||
|
}
|
||||||
|
public refresh(start: number, end: number): void {
|
||||||
|
this._core.refresh(start, end);
|
||||||
|
}
|
||||||
|
public reset(): void {
|
||||||
|
this._core.reset();
|
||||||
|
}
|
||||||
|
public static applyAddon(addon: any): void {
|
||||||
|
addon.apply(Terminal);
|
||||||
|
}
|
||||||
|
public static get strings(): ILocalizableStrings {
|
||||||
|
return Strings;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -5,6 +5,6 @@
|
|||||||
* This file is the entry point for browserify.
|
* This file is the entry point for browserify.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Terminal } from './Terminal';
|
import { Terminal } from './public/Terminal';
|
||||||
|
|
||||||
module.exports = Terminal;
|
module.exports = Terminal;
|
||||||
|
|||||||
Reference in New Issue
Block a user