This repository has been archived by the owner on Dec 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 681
/
createTerminal.js
121 lines (115 loc) · 3.71 KB
/
createTerminal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @format
*/
import type {TerminalOptions} from 'xterm';
import {
boolean,
constant,
either,
either3,
object,
number,
string,
guard,
} from 'decoders';
import featureConfig from 'nuclide-commons-atom/feature-config';
import {Terminal as XTerminal} from 'xterm';
import * as Fit from 'xterm/lib/addons/fit/fit';
import * as WebLinks from 'xterm/lib/addons/webLinks/webLinks';
import {
CHAR_ATLAS_CONFIG,
CURSOR_BLINK_CONFIG,
CURSOR_STYLE_CONFIG,
FONT_FAMILY_CONFIG,
LINE_HEIGHT_CONFIG,
OPTION_IS_META_CONFIG,
SCROLLBACK_CONFIG,
TRANSPARENCY_CONFIG,
getFontSize,
RENDERER_TYPE_CONFIG,
} from './config';
export type Terminal = TerminalClass;
declare class TerminalClass extends XTerminal {
proposeGeometry: () => {rows: number, cols: number};
fit: () => void;
webLinksInit: (handler?: (event: Event, link: string) => void) => void;
// TODO: Update xterm types?
linkifier: any;
buffer: any;
selectionManager: any;
dispose: () => void;
}
const assertTerminalOptionsInFeatureConfig = guard(
object({
cursorBlink: boolean,
cursorStyle: either3(
constant('block'),
constant('underline'),
constant('bar'),
),
scrollback: number,
fontFamily: string,
fontSize: number,
lineHeight: number,
macOptionIsMeta: boolean,
allowTransparency: boolean,
experimentalCharAtlas: either3(
constant('none'),
constant('static'),
constant('dynamic'),
),
rendererType: either(constant('canvas'), constant('dom')),
}),
);
export function createTerminal(options: TerminalOptions = {}): Terminal {
// Load the addons on-demand the first time we create a terminal.
// $FlowIgnore
if (XTerminal.fit == null) {
// The 'fit' add-on resizes the terminal based on the container size
// and the font size such that the terminal fills the container.
XTerminal.applyAddon(Fit);
}
// $FlowIgnore
if (XTerminal.webLinksInit == null) {
// The 'webLinks' add-on linkifies http URL strings.
XTerminal.applyAddon(WebLinks);
}
const rendererType = featureConfig.get(RENDERER_TYPE_CONFIG);
// $FlowIgnore We know that TerminalClass is XTerminal + addons
const terminal = new XTerminal(
// $FlowIssue: xterms type needs to be updated to include experimentalCharAtlas
assertTerminalOptionsInFeatureConfig({
cursorBlink: featureConfig.get(CURSOR_BLINK_CONFIG),
cursorStyle: featureConfig.get(CURSOR_STYLE_CONFIG),
scrollback: featureConfig.get(SCROLLBACK_CONFIG),
fontFamily: featureConfig.get(FONT_FAMILY_CONFIG),
fontSize: getFontSize(),
lineHeight: featureConfig.get(LINE_HEIGHT_CONFIG),
macOptionIsMeta: featureConfig.get(OPTION_IS_META_CONFIG),
allowTransparency: featureConfig.get(TRANSPARENCY_CONFIG),
experimentalCharAtlas: featureConfig.get(CHAR_ATLAS_CONFIG),
rendererType: rendererType === 'auto' ? 'canvas' : rendererType,
...options,
}),
);
// Patch into xterm Linkifier to catch errors on out of bounds line fetching.
// Track issue at https://github.com/xtermjs/xterm.js/issues/1669
const linkifier = terminal._core.linkifier;
const doLinkifyRow = linkifier._doLinkifyRow;
linkifier._doLinkifyRow = (row, text, matcher, offset) => {
try {
doLinkifyRow.call(linkifier, row, text, matcher, offset);
} catch (e) {
// swallow errors to avoid red box because the linkifier runs on a timer.
}
};
return terminal;
}