mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into 2370
This commit is contained in:
+21
-3
@@ -62,7 +62,7 @@ jobs:
|
||||
yarn lint
|
||||
displayName: 'Lint'
|
||||
|
||||
- job: IntegrationTests
|
||||
- job: Linux_IntegrationTests
|
||||
pool:
|
||||
vmImage: 'ubuntu-16.04'
|
||||
steps:
|
||||
@@ -81,14 +81,32 @@ jobs:
|
||||
yarn start &
|
||||
sleep 10
|
||||
yarn test-api --headless
|
||||
displayName: 'Integration tests'
|
||||
displayName: 'Linux Integration tests'
|
||||
|
||||
- job: macOS_IntegrationTests
|
||||
pool:
|
||||
vmImage: 'xcode9-macos10.13'
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '8.x'
|
||||
displayName: 'Install Node.js'
|
||||
- script: |
|
||||
yarn
|
||||
displayName: 'Install dependencies and build'
|
||||
- script: |
|
||||
yarn start &
|
||||
sleep 10
|
||||
yarn test-api --headless
|
||||
displayName: 'MacOS Integration tests'
|
||||
|
||||
- job: Release
|
||||
dependsOn:
|
||||
- Linux
|
||||
- macOS
|
||||
- Windows
|
||||
- IntegrationTests
|
||||
- Linux_IntegrationTests
|
||||
- macOS_IntegrationTests
|
||||
condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['Build.SourceBranch'], 'refs/heads/release/*')))
|
||||
pool:
|
||||
vmImage: 'ubuntu-16.04'
|
||||
|
||||
+57
-34
@@ -48,43 +48,66 @@ stdin.addListener('data', function(data) {
|
||||
}
|
||||
});
|
||||
|
||||
// basic button codes (modifier keys are added on top)
|
||||
const BUTTONS = {
|
||||
0: ['left', 'press'],
|
||||
1: ['middle', 'press'],
|
||||
2: ['right', 'press'],
|
||||
3: ['', 'release'],
|
||||
32: ['left', 'move'],
|
||||
33: ['middle', 'move'],
|
||||
34: ['right', 'move'],
|
||||
35: ['', 'move'],
|
||||
64: ['wheel', 'up'],
|
||||
65: ['wheel', 'down']
|
||||
// button definitions
|
||||
const buttons = {
|
||||
'<none>': -1,
|
||||
left: 0,
|
||||
middle: 1,
|
||||
right: 2,
|
||||
released: 3,
|
||||
wheelUp: 4,
|
||||
wheelDown: 5,
|
||||
wheelLeft: 6,
|
||||
wheelRight: 7,
|
||||
aux1: 8,
|
||||
aux2: 9,
|
||||
aux3: 10,
|
||||
aux4: 11,
|
||||
aux5: 12,
|
||||
aux6: 13,
|
||||
aux7: 14,
|
||||
aux8: 15
|
||||
};
|
||||
const reverseButtons = {};
|
||||
for (const el in buttons) {
|
||||
reverseButtons[buttons[el]] = el;
|
||||
}
|
||||
|
||||
// extract button data from buttonCode
|
||||
function evalButtonCode(code) {
|
||||
// 2 bits: 0 - left, 1 - middle, 2 - right, 3 - release
|
||||
// higher bits: 4 - shift, 8 - meta, 16 - control
|
||||
const modifier = {shift: !!(code & 4), meta: !!(code & 8), control: !!(code & 16)};
|
||||
const wheel = code & 64;
|
||||
let action;
|
||||
let button;
|
||||
if (wheel) {
|
||||
action = (code & 1) ? 'down' : 'up';
|
||||
button = 'wheel';
|
||||
} else {
|
||||
action = code & 32 ? 'move' : code === 3 ? 'release' : 'press';
|
||||
code &= 3; // TODO: more than 3 buttons + wheel
|
||||
button = code === 0 ? 'left' : code === 1 ? 'middle' : code === 2 ? 'right' : '<none>';
|
||||
// more than 15 buttons are not supported
|
||||
if (code > 255) {
|
||||
return {button: 'invalid', action: 'invalid', modifier: {}};
|
||||
}
|
||||
return {button, action, modifier};
|
||||
const modifier = {shift: !!(code & 4), meta: !!(code & 8), control: !!(code & 16)};
|
||||
const move = code & 32;
|
||||
let button = code & 3;
|
||||
if (code & 128) {
|
||||
button |= 8;
|
||||
}
|
||||
if (code & 64) {
|
||||
button |= 4
|
||||
}
|
||||
let actionS = 'press';
|
||||
let buttonS = reverseButtons[button];
|
||||
if (button === 3) {
|
||||
buttonS = '<none>';
|
||||
actionS = 'release';
|
||||
}
|
||||
if (move) {
|
||||
actionS = 'move';
|
||||
} else if (4 <= button && button <= 7) {
|
||||
buttonS = 'wheel';
|
||||
actionS = button === 4 ? 'up' : button === 5 ? 'down' : button === 6 ? 'left' : 'right';
|
||||
}
|
||||
return {button: buttonS, action: actionS, modifier};
|
||||
}
|
||||
|
||||
// protocols
|
||||
const PROTOCOLS = {
|
||||
'9 (X10: press only)': '\x1b[?9h',
|
||||
'1000 (VT200: press, release, wheel)': '\x1b[?1000h',
|
||||
// '1001 (VT200 highlight)': '\x1b[?1001h', // handle of backreport not implemented
|
||||
// '1001 (VT200 highlight)': '\x1b[?1001h', // handle of backreport - not implemented
|
||||
'1002 (press, release, move on pressed, wheel)': '\x1b[?1002h',
|
||||
'1003 (press, relase, move, wheel)': '\x1b[?1003h'
|
||||
}
|
||||
@@ -96,8 +119,8 @@ const ENC = {
|
||||
// format: CSI M <button + 32> <row + 32> <col + 32>
|
||||
report => ({
|
||||
state: evalButtonCode(report[3] - 32),
|
||||
row: report[4] - 32,
|
||||
col: report[5] - 32
|
||||
col: report[4] - 32,
|
||||
row: report[5] - 32
|
||||
})
|
||||
],
|
||||
'UTF8' : [
|
||||
@@ -108,8 +131,8 @@ const ENC = {
|
||||
const sReport = report.toString(); // decode with utf8
|
||||
return {
|
||||
state: evalButtonCode(sReport.charCodeAt(3) - 32),
|
||||
row: sReport.charCodeAt(4) - 32,
|
||||
col: sReport.charCodeAt(5) - 32
|
||||
col: sReport.charCodeAt(4) - 32,
|
||||
row: sReport.charCodeAt(5) - 32
|
||||
};
|
||||
}
|
||||
],
|
||||
@@ -119,7 +142,7 @@ const ENC = {
|
||||
report => {
|
||||
// strip off introducer + M
|
||||
const sReport = report.toString().slice(3, -1);
|
||||
const [buttonCode, row, col] = sReport.split(';');
|
||||
const [buttonCode, col, row] = sReport.split(';');
|
||||
const state = evalButtonCode(buttonCode);
|
||||
if (report[report.length - 1] === 'm'.charCodeAt(0)) {
|
||||
state.action = 'release';
|
||||
@@ -133,7 +156,7 @@ const ENC = {
|
||||
report => {
|
||||
// strip off introducer + M
|
||||
const sReport = report.toString().slice(2, -1);
|
||||
const [button, row, col] = sReport.split(';');
|
||||
const [button, col, row] = sReport.split(';');
|
||||
return {state: evalButtonCode(button - 32), row, col};
|
||||
}
|
||||
]
|
||||
@@ -182,7 +205,7 @@ function applyReportData(data) {
|
||||
let {state, row, col} = ENC[Object.keys(ENC)[activeEnc]][1](data);
|
||||
console.log('\x1b[2KButton:', state.button, 'Action:', state.action, 'Modifier:', state.modifier, 'row:', row, 'col:', col);
|
||||
// apply to cursor position
|
||||
process.stdout.write(`\x1b[${col};${row}H`);
|
||||
process.stdout.write(`\x1b[${row};${col}H`);
|
||||
}
|
||||
|
||||
printMenu();
|
||||
|
||||
@@ -27,5 +27,5 @@ r
|
||||
s
|
||||
t
|
||||
u[78Gvwxyz
|
||||
[r[24d
|
||||
[r[25d
|
||||
The end.
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
1
|
||||
2
|
||||
6
|
||||
7
|
||||
8
|
||||
9 ABC
|
||||
6
|
||||
7
|
||||
8
|
||||
9 ABC
|
||||
DEF
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
j
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
yz qrstu vwx
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
j
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
q
|
||||
yz vwx
|
||||
The end.
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[3;7r1D2D3D4D5D6D7D8D9[78GABCDEF[8daDbDcDdDeDfDgDhDiDjDkDlDmDnDoDpDqDrDsDtDu[78Gvwxyz
|
||||
[r[24d
|
||||
[r[25d
|
||||
The end.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
2
|
||||
6
|
||||
7
|
||||
8
|
||||
@@ -21,5 +20,6 @@ DEF
|
||||
o
|
||||
p
|
||||
q
|
||||
The end. rstu vwx
|
||||
yz rstu vwx
|
||||
The end.
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
6 C
|
||||
8 ^^^^
|
||||
9 vvvv DL on line 11, expected: ACD_
|
||||
10 A
|
||||
@@ -13,14 +12,14 @@
|
||||
19 vvvv IL on line 21, expected: A_
|
||||
20 A
|
||||
|
||||
|
||||
22 ^^^^
|
||||
24 A
|
||||
25 B
|
||||
27 vvvv DL on line 28, expected: B_
|
||||
|
||||
23 vvvv IL on line 24, expected: _A
|
||||
25 B
|
||||
26 ^^^^
|
||||
28 A
|
||||
|
||||
29 B
|
||||
30 ^^^^
|
||||
31
|
||||
32
|
||||
32
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
j
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
q
|
||||
r
|
||||
s
|
||||
t
|
||||
u
|
||||
v
|
||||
w
|
||||
x[10;19r[25E1[24d[25F2[r[24d
|
||||
@@ -0,0 +1,25 @@
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
2
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
q
|
||||
r
|
||||
1
|
||||
t
|
||||
u
|
||||
v
|
||||
w
|
||||
x
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
j
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
q
|
||||
r
|
||||
s
|
||||
t
|
||||
u
|
||||
v
|
||||
w
|
||||
x[10;19r[H[25e1[r[24d
|
||||
@@ -0,0 +1,25 @@
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
e
|
||||
f
|
||||
g
|
||||
h
|
||||
i
|
||||
j
|
||||
k
|
||||
l
|
||||
m
|
||||
n
|
||||
o
|
||||
p
|
||||
q
|
||||
r
|
||||
s
|
||||
t
|
||||
u
|
||||
v
|
||||
w
|
||||
x
|
||||
1
|
||||
+30
-10
@@ -412,10 +412,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (wraparoundMode) {
|
||||
buffer.x = 0;
|
||||
buffer.y++;
|
||||
if (buffer.y > buffer.scrollBottom) {
|
||||
if (buffer.y === buffer.scrollBottom + 1) {
|
||||
buffer.y--;
|
||||
this._terminal.scroll(true);
|
||||
} else {
|
||||
if (buffer.y >= this._bufferService.rows) {
|
||||
buffer.y = this._bufferService.rows - 1;
|
||||
}
|
||||
// The line already exists (eg. the initial viewport), mark it as a
|
||||
// wrapped line
|
||||
buffer.lines.get(buffer.y).isWrapped = true;
|
||||
@@ -508,9 +511,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
buffer.x = 0;
|
||||
}
|
||||
buffer.y++;
|
||||
if (buffer.y > buffer.scrollBottom) {
|
||||
if (buffer.y === buffer.scrollBottom + 1) {
|
||||
buffer.y--;
|
||||
this._terminal.scroll();
|
||||
} else if (buffer.y >= this._bufferService.rows) {
|
||||
buffer.y = this._bufferService.rows - 1;
|
||||
}
|
||||
// If the end of the line is hit, prevent this action from wrapping around to the next line.
|
||||
if (buffer.x >= this._bufferService.cols) {
|
||||
@@ -611,7 +616,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Cursor Up Ps Times (default = 1) (CUU).
|
||||
*/
|
||||
public cursorUp(params: IParams): void {
|
||||
this._moveCursor(0, -(params.params[0] || 1));
|
||||
// stop at scrollTop
|
||||
const diffToTop = this._bufferService.buffer.y - this._bufferService.buffer.scrollTop;
|
||||
if (diffToTop >= 0) {
|
||||
this._moveCursor(0, -Math.min(diffToTop, params.params[0] || 1));
|
||||
} else {
|
||||
this._moveCursor(0, -(params.params[0] || 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,7 +630,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Cursor Down Ps Times (default = 1) (CUD).
|
||||
*/
|
||||
public cursorDown(params: IParams): void {
|
||||
this._moveCursor(0, params.params[0] || 1);
|
||||
// stop at scrollBottom
|
||||
const diffToBottom = this._bufferService.buffer.scrollBottom - this._bufferService.buffer.y;
|
||||
if (diffToBottom >= 0) {
|
||||
this._moveCursor(0, Math.min(diffToBottom, params.params[0] || 1));
|
||||
} else {
|
||||
this._moveCursor(0, params.params[0] || 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -644,7 +661,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Other than cursorDown (CUD) also set the cursor to first column.
|
||||
*/
|
||||
public cursorNextLine(params: IParams): void {
|
||||
this._moveCursor(0, params.params[0] || 1);
|
||||
this.cursorDown(params);
|
||||
this._bufferService.buffer.x = 0;
|
||||
}
|
||||
|
||||
@@ -654,7 +671,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Other than cursorUp (CUU) also set the cursor to first column.
|
||||
*/
|
||||
public cursorPrecedingLine(params: IParams): void {
|
||||
this._moveCursor(0, -(params.params[0] || 1));
|
||||
this.cursorUp(params);
|
||||
this._bufferService.buffer.x = 0;
|
||||
}
|
||||
|
||||
@@ -996,7 +1013,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
while (param--) {
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 1);
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
|
||||
}
|
||||
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
|
||||
}
|
||||
@@ -1013,7 +1030,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
while (param--) {
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollBottom, 1);
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
buffer.lines.splice(buffer.ybase + buffer.scrollTop, 0, buffer.getBlankLine(this._terminal.eraseAttrData()));
|
||||
}
|
||||
this._dirtyRowService.markRangeDirty(buffer.scrollTop, buffer.scrollBottom);
|
||||
}
|
||||
@@ -2043,10 +2060,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
*/
|
||||
public index(): void {
|
||||
this._restrictCursor();
|
||||
const buffer = this._bufferService.buffer;
|
||||
this._bufferService.buffer.y++;
|
||||
if (this._bufferService.buffer.y > this._bufferService.buffer.scrollBottom) {
|
||||
this._bufferService.buffer.y--;
|
||||
if (buffer.y === buffer.scrollBottom + 1) {
|
||||
buffer.y--;
|
||||
this._terminal.scroll();
|
||||
} else if (buffer.y >= this._bufferService.rows) {
|
||||
buffer.y = this._bufferService.rows - 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
@@ -265,6 +265,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
super.dispose();
|
||||
if (this._windowsMode) {
|
||||
this._windowsMode.dispose();
|
||||
|
||||
@@ -17,12 +17,6 @@ const ROWS = 25;
|
||||
|
||||
const TESTFILES = glob.sync('**/escape_sequence_files/*.in', { cwd: path.join(__dirname, '..')});
|
||||
const SKIP_FILES = [
|
||||
't0070-DECSTBM_LF.in', // lineFeed not working correctly
|
||||
't0071-DECSTBM_IND.in',
|
||||
't0072-DECSTBM_NEL.in',
|
||||
't0075-DECSTBM_CUU_CUD.in',
|
||||
't0076-DECSTBM_IL_DL.in', // not working due to lineFeed
|
||||
't0077-DECSTBM_quirks.in',
|
||||
't0084-CBT.in',
|
||||
't0101-NLM.in',
|
||||
't0103-reverse_wrap.in',
|
||||
@@ -42,7 +36,7 @@ const FILES = TESTFILES.filter(value => SKIP_FILES.indexOf(value.split('/').slic
|
||||
|
||||
|
||||
describe('Escape Sequence Files', function(): void {
|
||||
this.timeout(20000);
|
||||
this.timeout(1000);
|
||||
|
||||
let ptyTerm: any;
|
||||
let slaveEnd: any;
|
||||
|
||||
@@ -563,9 +563,10 @@ export class SelectionService implements ISelectionService {
|
||||
// to be sent to the pty.
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
// Something went wrong
|
||||
// Do nothing if there is no selection start, this can happen if the first
|
||||
// click in the terminal is an incremental click
|
||||
if (!this._model.selectionStart) {
|
||||
throw new Error('Selection start position was not set before mousemove event');
|
||||
return;
|
||||
}
|
||||
|
||||
// Record the previous position so we know whether to redraw the selection
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user