Skip to content

Commit ea922fe

Browse files
authored
Merge pull request #2422 from jerch/write_enhancement
write callback support
2 parents 22b06ca + 5a65286 commit ea922fe

File tree

18 files changed

+363
-369
lines changed

18 files changed

+363
-369
lines changed

addons/xterm-addon-attach/src/AttachAddon.api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe('AttachAddon', () => {
5454
const server = new WebSocket.Server({ port });
5555
const data = new Uint8Array([102, 111, 111]);
5656
server.on('connection', socket => socket.send(data));
57-
await page.evaluate(`window.term.loadAddon(new window.AttachAddon(new WebSocket('ws://localhost:${port}'), { inputUtf8: true }))`);
57+
await page.evaluate(`window.term.loadAddon(new window.AttachAddon(new WebSocket('ws://localhost:${port}')))`);
5858
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'foo');
5959
server.close();
6060
});

addons/xterm-addon-attach/src/AttachAddon.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,27 @@ import { Terminal, IDisposable, ITerminalAddon } from 'xterm';
99

1010
interface IAttachOptions {
1111
bidirectional?: boolean;
12-
inputUtf8?: boolean;
1312
}
1413

1514
export class AttachAddon implements ITerminalAddon {
1615
private _socket: WebSocket;
1716
private _bidirectional: boolean;
18-
private _utf8: boolean;
1917
private _disposables: IDisposable[] = [];
2018

2119
constructor(socket: WebSocket, options?: IAttachOptions) {
2220
this._socket = socket;
2321
// always set binary type to arraybuffer, we do not handle blobs
2422
this._socket.binaryType = 'arraybuffer';
2523
this._bidirectional = (options && options.bidirectional === false) ? false : true;
26-
this._utf8 = !!(options && options.inputUtf8);
2724
}
2825

2926
public activate(terminal: Terminal): void {
30-
if (this._utf8) {
31-
this._disposables.push(addSocketListener(this._socket, 'message',
32-
(ev: MessageEvent | Event | CloseEvent) => terminal.writeUtf8(new Uint8Array((ev as any).data as ArrayBuffer))));
33-
} else {
34-
this._disposables.push(addSocketListener(this._socket, 'message',
35-
(ev: MessageEvent | Event | CloseEvent) => terminal.write((ev as any).data as string)));
36-
}
27+
this._disposables.push(
28+
addSocketListener(this._socket, 'message', ev => {
29+
const data: ArrayBuffer | string = ev.data;
30+
terminal.write(typeof data === 'string' ? data : new Uint8Array(data));
31+
})
32+
);
3733

3834
if (this._bidirectional) {
3935
this._disposables.push(terminal.onData(data => this._sendData(data)));
@@ -57,7 +53,7 @@ export class AttachAddon implements ITerminalAddon {
5753
}
5854
}
5955

60-
function addSocketListener(socket: WebSocket, type: string, handler: (this: WebSocket, ev: MessageEvent | Event | CloseEvent) => any): IDisposable {
56+
function addSocketListener<K extends keyof WebSocketEventMap>(socket: WebSocket, type: K, handler: (this: WebSocket, ev: WebSocketEventMap[K]) => any): IDisposable {
6157
socket.addEventListener(type, handler);
6258
return {
6359
dispose: () => {

addons/xterm-addon-attach/typings/xterm-addon-attach.d.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ declare module 'xterm-addon-attach' {
1111
* Whether input should be written to the backend. Defaults to `true`.
1212
*/
1313
bidirectional?: boolean;
14-
15-
/**
16-
* Whether to use UTF8 binary transport for incoming messages. Defaults to `false`.
17-
* Note: This must be in line with the server side of the websocket.
18-
* Always send string messages from the backend if this options is false,
19-
* otherwise always binary UTF8 data.
20-
*/
21-
inputUtf8?: boolean;
2214
}
2315

2416
export class AttachAddon implements ITerminalAddon {

addons/xterm-addon-search/src/SearchAddon.api.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,7 @@ async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
111111
}
112112

113113
async function writeSync(data: string): Promise<void> {
114-
await page.evaluate(`window.term.write('${data}');`);
115-
while (true) {
116-
if (await page.evaluate(`window.term._core.writeBuffer.length === 0`)) {
117-
break;
118-
}
119-
}
114+
return page.evaluate(`new Promise(resolve => window.term.write('${data}', resolve))`);
120115
}
121116

122117
function makeData(length: number): string {

addons/xterm-addon-webgl/src/WebglRenderer.api.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,7 @@ async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
145145
}
146146

147147
async function writeSync(data: string): Promise<void> {
148-
await page.evaluate(`window.term.write('${data}');`);
149-
while (true) {
150-
if (await page.evaluate(`window.term._core.writeBuffer.length === 0`)) {
151-
break;
152-
}
153-
}
148+
return page.evaluate(`new Promise(resolve => window.term.write('${data}', resolve))`);
154149
}
155150

156151
async function getCellColor(col: number, row: number): Promise<number[]> {

demo/client.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,7 @@ function createTerminal(): void {
167167
}
168168

169169
function runRealTerminal(): void {
170-
/**
171-
* The demo defaults to string transport by default.
172-
* To run it with UTF8 binary transport, swap comment on
173-
* the lines below. (Must also be switched in server.js)
174-
*/
175170
term.loadAddon(new AttachAddon(socket));
176-
// term.loadAddon(new AttachAddon(socket, {inputUtf8: true}));
177-
178171
term._initialized = true;
179172
}
180173

demo/server.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ var os = require('os');
44
var pty = require('node-pty');
55

66
/**
7-
* Whether to use UTF8 binary transport.
8-
* (Must also be switched in client.ts)
7+
* Whether to use binary transport.
98
*/
10-
const USE_BINARY_UTF8 = false;
9+
const USE_BINARY = true;
1110

1211

1312
function startServer() {
@@ -46,7 +45,7 @@ function startServer() {
4645
rows: rows || 24,
4746
cwd: env.PWD,
4847
env: env,
49-
encoding: USE_BINARY_UTF8 ? null : 'utf8'
48+
encoding: USE_BINARY ? null : 'utf8'
5049
});
5150

5251
console.log('Created terminal with PID: ' + term.pid);
@@ -108,7 +107,7 @@ function startServer() {
108107
}
109108
};
110109
}
111-
const send = USE_BINARY_UTF8 ? bufferUtf8(ws, 5) : buffer(ws, 5);
110+
const send = USE_BINARY ? bufferUtf8(ws, 5) : buffer(ws, 5);
112111

113112
term.on('data', function(data) {
114113
try {

src/InputHandler.ts

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export class InputHandler extends Disposable implements IInputHandler {
324324
super.dispose();
325325
}
326326

327-
public parse(data: string): void {
327+
public parse(data: string | Uint8Array): void {
328328
let buffer = this._bufferService.buffer;
329329
const cursorStartX = buffer.x;
330330
const cursorStartY = buffer.y;
@@ -334,30 +334,17 @@ export class InputHandler extends Disposable implements IInputHandler {
334334
if (this._parseBuffer.length < data.length) {
335335
this._parseBuffer = new Uint32Array(data.length);
336336
}
337-
this._parser.parse(this._parseBuffer, this._stringDecoder.decode(data, this._parseBuffer));
338-
339-
buffer = this._bufferService.buffer;
340-
if (buffer.x !== cursorStartX || buffer.y !== cursorStartY) {
341-
this._onCursorMove.fire();
342-
}
343-
}
344-
345-
public parseUtf8(data: Uint8Array): void {
346-
let buffer = this._bufferService.buffer;
347-
const cursorStartX = buffer.x;
348-
const cursorStartY = buffer.y;
349-
350-
this._logService.debug('parsing data', data);
351-
352-
if (this._parseBuffer.length < data.length) {
353-
this._parseBuffer = new Uint32Array(data.length);
354-
}
355-
this._parser.parse(this._parseBuffer, this._utf8Decoder.decode(data, this._parseBuffer));
337+
this._parser.parse(this._parseBuffer,
338+
(typeof data === 'string')
339+
? this._stringDecoder.decode(data, this._parseBuffer)
340+
: this._utf8Decoder.decode(data, this._parseBuffer)
341+
);
356342

357343
buffer = this._bufferService.buffer;
358344
if (buffer.x !== cursorStartX || buffer.y !== cursorStartY) {
359345
this._onCursorMove.fire();
360346
}
347+
this._terminal.refresh(this._dirtyRowService.start, this._dirtyRowService.end);
361348
}
362349

363350
public print(data: Uint32Array, start: number, end: number): void {

0 commit comments

Comments
 (0)