Skip to content

Commit

Permalink
Merge b12d2c2 into 0a8d57c
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed Apr 2, 2019
2 parents 0a8d57c + b12d2c2 commit 512cab7
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 116 deletions.
16 changes: 6 additions & 10 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import * as fit from '../lib/addons/fit/fit';
import * as fullscreen from '../lib/addons/fullscreen/fullscreen';
import * as search from '../lib/addons/search/search';
import * as webLinks from '../lib/addons/webLinks/webLinks';
import * as winptyCompat from '../lib/addons/winptyCompat/winptyCompat';
import { ISearchOptions } from '../lib/addons/search/Interfaces';

// Pulling in the module's types relies on the <reference> above, it's looks a
// little weird here as we're importing "this" module
import { Terminal as TerminalType } from 'xterm';
import { Terminal as TerminalType, ITerminalOptions } from 'xterm';

export interface IWindowWithTerminal extends Window {
term: TerminalType;
Expand All @@ -30,10 +29,6 @@ Terminal.applyAddon(fit);
Terminal.applyAddon(fullscreen);
Terminal.applyAddon(search);
Terminal.applyAddon(webLinks);
const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
if (isWindows) {
Terminal.applyAddon(winptyCompat);
}


let term;
Expand Down Expand Up @@ -86,7 +81,10 @@ function createTerminal(): void {
while (terminalContainer.children.length) {
terminalContainer.removeChild(terminalContainer.children[0]);
}
term = new Terminal({});
const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
term = new Terminal({
windowsMode: isWindows
} as ITerminalOptions);
window.term = term; // Expose `term` to window for debugging purposes
term.on('resize', (size: { cols: number, rows: number }) => {
if (!pid) {
Expand All @@ -102,9 +100,7 @@ function createTerminal(): void {
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';

term.open(terminalContainer);
if (isWindows) {
term.winptyCompatInit();
}

term.webLinksInit();
term.fit();
term.focus();
Expand Down
2 changes: 1 addition & 1 deletion src/Buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export class Buffer implements IBuffer {
}

private get _isReflowEnabled(): boolean {
return this._hasScrollback && !(this._terminal as any).isWinptyCompatEnabled;
return this._hasScrollback && !this._terminal.options.windowsMode;
}

private _reflow(newCols: number, newRows: number): void {
Expand Down
25 changes: 24 additions & 1 deletion src/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { IKeyboardEvent } from './common/Types';
import { evaluateKeyboardEvent } from './core/input/Keyboard';
import { KeyboardResultType, ICharset } from './core/Types';
import { clone } from './common/Clone';
import { applyWindowsMode } from './WindowsMode';

// Let it work inside Node.js for automated testing purposes.
const document = (typeof window !== 'undefined') ? window.document : null;
Expand Down Expand Up @@ -110,7 +111,8 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
tabStopWidth: 8,
theme: null,
rightClickSelectsWord: Browser.isMac,
rendererType: 'canvas'
rendererType: 'canvas',
windowsMode: false
};

export class Terminal extends EventEmitter implements ITerminal, IDisposable, IInputHandlingTerminal {
Expand Down Expand Up @@ -210,6 +212,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
private _accessibilityManager: AccessibilityManager;
private _screenDprMonitor: ScreenDprMonitor;
private _theme: ITheme;
private _windowsMode: IDisposable | undefined;

// bufferline to clone/copy from for new blank lines
private _blankLine: IBufferLine = null;
Expand Down Expand Up @@ -239,6 +242,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II

public dispose(): void {
super.dispose();
if (this._windowsMode) {
this._windowsMode.dispose();
this._windowsMode = undefined;
}
this._customKeyEventHandler = null;
removeTerminalFromCache(this);
this.handler = () => {};
Expand Down Expand Up @@ -321,6 +328,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this.selectionManager.clearSelection();
this.selectionManager.initBuffersListeners();
}

if (this.options.windowsMode) {
this._windowsMode = applyWindowsMode(this);
}
}

/**
Expand Down Expand Up @@ -501,6 +512,18 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
}
break;
case 'tabStopWidth': this.buffers.setupTabStops(); break;
case 'windowsMode':
if (value) {
if (!this._windowsMode) {
this._windowsMode = applyWindowsMode(this);
}
} else {
if (this._windowsMode) {
this._windowsMode.dispose();
this._windowsMode = undefined;
}
}
break;
}
// Inform renderer of changes
if (this.renderer) {
Expand Down
30 changes: 30 additions & 0 deletions src/WindowsMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/

import { IDisposable } from 'xterm';
import { ITerminal } from './Types';
import { CHAR_DATA_CODE_INDEX, NULL_CELL_CODE, WHITESPACE_CELL_CODE } from './Buffer';

export function applyWindowsMode(terminal: ITerminal): IDisposable {
// Winpty does not support wraparound mode which means that lines will never
// be marked as wrapped. This causes issues for things like copying a line
// retaining the wrapped new line characters or if consumers are listening
// in on the data stream.
//
// The workaround for this is to listen to every incoming line feed and mark
// the line as wrapped if the last character in the previous line is not a
// space. This is certainly not without its problems, but generally on
// Windows when text reaches the end of the terminal it's likely going to be
// wrapped.
return terminal.addDisposableListener('linefeed', () => {
const line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1);
const lastChar = line.get(terminal.cols - 1);

if (lastChar[CHAR_DATA_CODE_INDEX] !== NULL_CELL_CODE && lastChar[CHAR_DATA_CODE_INDEX] !== WHITESPACE_CELL_CODE) {
const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y);
nextLine.isWrapped = true;
}
});
}
14 changes: 0 additions & 14 deletions src/addons/winptyCompat/Interfaces.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/addons/winptyCompat/package.json

This file was deleted.

21 changes: 0 additions & 21 deletions src/addons/winptyCompat/tsconfig.json

This file was deleted.

19 changes: 0 additions & 19 deletions src/addons/winptyCompat/winptyCompat.test.ts

This file was deleted.

43 changes: 0 additions & 43 deletions src/addons/winptyCompat/winptyCompat.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/tsconfig.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
{ "path": "./addons/search" },
{ "path": "./addons/terminado" },
{ "path": "./addons/webLinks" },
{ "path": "./addons/winptyCompat" },
{ "path": "./addons/zmodem" }
]
}

12 changes: 12 additions & 0 deletions typings/xterm.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,18 @@ declare module 'xterm' {
* The color theme of the terminal.
*/
theme?: ITheme;

/**
* Whether "Windows mode" is enabled. Because Windows backends winpty and
* conpty operate by doing line wrapping on their side, xterm.js does not
* have access to wrapped lines. When Windows mode is enabled the following
* changes will be in effect:
*
* - Reflow is disabled.
* - Lines are assumed to be wrapped if the last character of the line is
* not whitespace.
*/
windowsMode?: boolean;
}

/**
Expand Down

0 comments on commit 512cab7

Please sign in to comment.