upgrade to xterm v5

This commit is contained in:
Labhansh Agrawal 2023-06-15 22:40:34 +05:30
parent 8337acb32c
commit 1daf594e4b
6 changed files with 96 additions and 93 deletions

View file

@ -23,9 +23,9 @@ if (false) {
require('mousetrap');
require('open');
require('xterm-addon-fit');
require('xterm-addon-ligatures');
require('xterm-addon-search');
require('xterm-addon-web-links');
require('xterm-addon-webgl');
require('xterm-addon-canvas');
require('xterm');
}

View file

@ -4,6 +4,7 @@ import {FitAddon} from 'xterm-addon-fit';
import {WebLinksAddon} from 'xterm-addon-web-links';
import {SearchAddon, ISearchDecorationOptions} from 'xterm-addon-search';
import {WebglAddon} from 'xterm-addon-webgl';
import {CanvasAddon} from 'xterm-addon-canvas';
import {LigaturesAddon} from 'xterm-addon-ligatures';
import {Unicode11Addon} from 'xterm-addon-unicode11';
import {clipboard, shell} from 'electron';
@ -12,7 +13,7 @@ import terms from '../terms';
import processClipboard from '../utils/paste';
import _SearchBox from './searchBox';
import {TermProps} from '../hyper';
import {ObjectTypedKeys} from '../utils/object';
import {pickBy, isEqual} from 'lodash';
import {decorate} from '../utils/plugins';
import 'xterm/css/xterm.css';
@ -57,14 +58,13 @@ const getTermOptions = (props: TermProps): ITerminalOptions => {
letterSpacing: props.letterSpacing,
allowTransparency: needTransparency,
macOptionClickForcesSelection: props.macOptionSelectionMode === 'force',
bellStyle: props.bell === 'SOUND' ? 'sound' : 'none',
windowsMode: isWindows,
theme: {
foreground: props.foregroundColor,
background: backgroundColor,
cursor: props.cursorColor,
cursorAccent: props.cursorAccentColor,
selection: props.selectionColor,
selectionBackground: props.selectionColor,
black: props.colors.black,
red: props.colors.red,
green: props.colors.green,
@ -83,7 +83,8 @@ const getTermOptions = (props: TermProps): ITerminalOptions => {
brightWhite: props.colors.lightWhite
},
screenReaderMode: props.screenReaderMode,
overviewRulerWidth: 20
overviewRulerWidth: 20,
allowProposedApi: true
};
};
@ -107,7 +108,8 @@ export default class Term extends React.PureComponent<
termWrapperRef: HTMLElement | null;
termOptions: ITerminalOptions;
disposableListeners: IDisposable[];
termDefaultBellSound: string | null;
defaultBellSound: HTMLAudioElement | null;
bellSound: HTMLAudioElement | null;
fitAddon: FitAddon;
searchAddon: SearchAddon;
static rendererTypes: Record<string, string>;
@ -131,7 +133,8 @@ export default class Term extends React.PureComponent<
this.termWrapperRef = null;
this.termOptions = {};
this.disposableListeners = [];
this.termDefaultBellSound = null;
this.defaultBellSound = null;
this.bellSound = null;
this.fitAddon = new FitAddon();
this.searchAddon = new SearchAddon();
this.searchDecorations = {
@ -158,7 +161,14 @@ export default class Term extends React.PureComponent<
this.termOptions = getTermOptions(props);
this.term = props.term || new Terminal(this.termOptions);
this.termDefaultBellSound = this.term.getOption('bellSound');
this.defaultBellSound = new Audio(
// Source: https://freesound.org/people/altemark/sounds/45759/
// This sound is released under the Creative Commons Attribution 3.0 Unported
// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been
// made, apart from the conversion to base64.
'data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjMyLjEwNAAAAAAAAAAAAAAA//tQxAADB8AhSmxhIIEVCSiJrDCQBTcu3UrAIwUdkRgQbFAZC1CQEwTJ9mjRvBA4UOLD8nKVOWfh+UlK3z/177OXrfOdKl7pyn3Xf//WreyTRUoAWgBgkOAGbZHBgG1OF6zM82DWbZaUmMBptgQhGjsyYqc9ae9XFz280948NMBWInljyzsNRFLPWdnZGWrddDsjK1unuSrVN9jJsK8KuQtQCtMBjCEtImISdNKJOopIpBFpNSMbIHCSRpRR5iakjTiyzLhchUUBwCgyKiweBv/7UsQbg8isVNoMPMjAAAA0gAAABEVFGmgqK////9bP/6XCykxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq'
);
this.setBellSound(props.bell, props.bellSound);
// The parent element for the terminal is attached and removed manually so
// that we can preserve it across mounts and unmounts of the component
@ -186,9 +196,9 @@ export default class Term extends React.PureComponent<
}
Term.reportRenderer(props.uid, useWebGL ? 'WebGL' : 'Canvas');
const shallActivateWebLink = (event: Record<string, any> | undefined): boolean => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return event && (!props.webLinksActivationKey || event[`${props.webLinksActivationKey}Key`]);
const shallActivateWebLink = (event: MouseEvent): boolean => {
if (!event) return false;
return props.webLinksActivationKey ? event[`${props.webLinksActivationKey}Key`] : true;
};
// eslint-disable-next-line @typescript-eslint/unbound-method
@ -196,25 +206,17 @@ export default class Term extends React.PureComponent<
this.term.loadAddon(this.fitAddon);
this.term.loadAddon(this.searchAddon);
this.term.loadAddon(
new WebLinksAddon(
(event: MouseEvent | undefined, uri: string) => {
if (shallActivateWebLink(event)) void shell.openExternal(uri);
},
{
// prevent default electron link handling to allow selection, e.g. via double-click
willLinkActivate: (event: MouseEvent | undefined) => {
event?.preventDefault();
return shallActivateWebLink(event);
},
priority: Date.now()
}
)
new WebLinksAddon((event, uri) => {
if (shallActivateWebLink(event)) void shell.openExternal(uri);
})
);
this.term.open(this.termRef);
if (useWebGL) {
this.term.loadAddon(new WebglAddon());
} else {
this.term.loadAddon(new CanvasAddon());
}
if (props.disableLigatures !== true && !useWebGL) {
if (props.disableLigatures !== true) {
this.term.loadAddon(new LigaturesAddon());
}
this.term.loadAddon(new Unicode11Addon());
@ -252,6 +254,10 @@ export default class Term extends React.PureComponent<
this.disposableListeners.push(this.term.onData(props.onData));
}
this.term.onBell(() => {
this.ringBell();
});
if (props.onResize) {
this.disposableListeners.push(
this.term.onResize(({cols, rows}) => {
@ -393,6 +399,18 @@ export default class Term extends React.PureComponent<
return !e.catched;
}
setBellSound(bell: string | null, sound: string | null) {
if (bell?.toUpperCase() === 'SOUND') {
this.bellSound = sound ? new Audio(sound) : this.defaultBellSound;
} else {
this.bellSound = null;
}
}
ringBell() {
void this.bellSound?.play();
}
componentDidUpdate(prevProps: TermProps) {
if (!prevProps.cleared && this.props.cleared) {
this.clear();
@ -400,40 +418,19 @@ export default class Term extends React.PureComponent<
const nextTermOptions = getTermOptions(this.props);
// Use bellSound in nextProps if it exists
// otherwise use the default sound found in xterm.
nextTermOptions.bellSound = this.props.bellSound || this.termDefaultBellSound!;
if (prevProps.bell !== this.props.bell || prevProps.bellSound !== this.props.bellSound) {
this.setBellSound(this.props.bell, this.props.bellSound);
}
if (prevProps.search && !this.props.search) {
this.closeSearchBox();
}
// Update only options that have changed.
ObjectTypedKeys(nextTermOptions)
.filter((option) => option !== 'theme' && nextTermOptions[option] !== this.termOptions[option])
.forEach((option) => {
try {
this.term.setOption(option, nextTermOptions[option]);
} catch (_e) {
const e = _e as {message: string};
if (/The webgl renderer only works with the webgl char atlas/i.test(e.message)) {
// Ignore this because the char atlas will also be changed
} else {
throw e;
}
}
});
// Do we need to update theme?
const shouldUpdateTheme =
!this.termOptions.theme ||
nextTermOptions.rendererType !== this.termOptions.rendererType ||
ObjectTypedKeys(nextTermOptions.theme!).some(
(option) => nextTermOptions.theme![option] !== this.termOptions.theme![option]
);
if (shouldUpdateTheme) {
this.term.setOption('theme', nextTermOptions.theme);
}
this.term.options = pickBy(
nextTermOptions,
(value, key) => !isEqual(this.termOptions[key as keyof ITerminalOptions], value)
);
this.termOptions = nextTermOptions;

4
lib/hyper.d.ts vendored
View file

@ -102,7 +102,7 @@ export type uiState = Immutable<{
updateReleaseUrl: string | null;
updateVersion: string | null;
webGLRenderer: boolean;
webLinksActivationKey: string;
webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | '';
}>;
export type session = {
@ -381,7 +381,7 @@ export type TermProps = {
uiFontFamily: string;
url: string | null;
webGLRenderer: boolean;
webLinksActivationKey: string;
webLinksActivationKey: 'ctrl' | 'alt' | 'meta' | 'shift' | '';
ref_: (uid: string, term: Term | null) => void;
} & extensionProps;

View file

@ -59,13 +59,14 @@
"typescript-json-schema": "0.57.0",
"uuid": "9.0.0",
"webpack-cli": "5.1.4",
"xterm": "4.19.0",
"xterm-addon-fit": "^0.5.0",
"xterm-addon-ligatures": "0.6.0-beta.19",
"xterm-addon-search": "^0.9.0",
"xterm-addon-unicode11": "^0.3.0",
"xterm-addon-web-links": "^0.6.0",
"xterm-addon-webgl": "0.12.0"
"xterm": "5.2.1",
"xterm-addon-canvas": "0.4.0",
"xterm-addon-fit": "0.7.0",
"xterm-addon-ligatures": "0.6.0",
"xterm-addon-search": "0.12.0",
"xterm-addon-unicode11": "0.5.0",
"xterm-addon-web-links": "0.8.0",
"xterm-addon-webgl": "0.15.0"
},
"devDependencies": {
"@ava/babel": "2.0.0",

View file

@ -118,10 +118,10 @@ const config: webpack.Configuration[] = [
mousetrap: 'require("./node_modules/mousetrap/mousetrap.js")',
open: 'require("./node_modules/open/index.js")',
'xterm-addon-fit': 'require("./node_modules/xterm-addon-fit/lib/xterm-addon-fit.js")',
'xterm-addon-ligatures': 'require("./node_modules/xterm-addon-ligatures/lib/xterm-addon-ligatures.js")',
'xterm-addon-search': 'require("./node_modules/xterm-addon-search/lib/xterm-addon-search.js")',
'xterm-addon-web-links': 'require("./node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js")',
'xterm-addon-webgl': 'require("./node_modules/xterm-addon-webgl/lib/xterm-addon-webgl.js")',
'xterm-addon-canvas': 'require("./node_modules/xterm-addon-canvas/lib/xterm-addon-canvas.js")',
xterm: 'require("./node_modules/xterm/lib/xterm.js")'
},
plugins: [

View file

@ -7532,43 +7532,48 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.0:
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
xterm-addon-fit@^0.5.0:
version "0.5.0"
resolved "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz#2d51b983b786a97dcd6cde805e700c7f913bc596"
integrity sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==
xterm-addon-canvas@0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/xterm-addon-canvas/-/xterm-addon-canvas-0.4.0.tgz#a6ee6a56deb0c495fcef29afe6d94b7119a0f334"
integrity sha512-iTC8CdjX9+hGX7jiEuiDMXzHsY/FKJdVnbjep5xjRXNu7RKOk15xuecIkJ7HZORqMVPpr4DGS3jyd9XUoBuxqw==
xterm-addon-ligatures@0.6.0-beta.19:
version "0.6.0-beta.19"
resolved "https://registry.npmjs.org/xterm-addon-ligatures/-/xterm-addon-ligatures-0.6.0-beta.19.tgz#5e43eeaf84968e014769a5f2c6a3a3601dc4771c"
integrity sha512-A0BIjFF6g5aPI0HiI2JMhhMV3gaHbpZ+ua+UNagkID0GxZ/ezn0wVOAtNQl/KlqnFueoyZIxlbyXmWNAfJVPRg==
xterm-addon-fit@0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.7.0.tgz#b8ade6d96e63b47443862088f6670b49fb752c6a"
integrity sha512-tQgHGoHqRTgeROPnvmtEJywLKoC/V9eNs4bLLz7iyJr1aW/QFzRwfd3MGiJ6odJd9xEfxcW36/xRU47JkD5NKQ==
xterm-addon-ligatures@0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/xterm-addon-ligatures/-/xterm-addon-ligatures-0.6.0.tgz#c51801b0150c62ac1165654757b55c796457d195"
integrity sha512-DxiYCXXYEpnwr8li4/QhG64exjrLX1nHBfNNfrQgx5e8Z9tK2SjWKpxI6PZEy++8+YdL1F7VjWI4aKOaDt2VVw==
dependencies:
font-finder "^1.1.0"
font-ligatures "^1.4.1"
xterm-addon-search@^0.9.0:
version "0.9.0"
resolved "https://registry.npmjs.org/xterm-addon-search/-/xterm-addon-search-0.9.0.tgz#95278ebb818cfcf882209ae75be96e0bea5d52a5"
integrity sha512-aoolI8YuHvdGw+Qjg8g2M4kst0v86GtB7WeBm4F0jNXA005/6QbWWy9eCsvnIDLJOFI5JSSrZnD6CaOkvBQYPA==
xterm-addon-unicode11@^0.3.0:
version "0.3.0"
resolved "https://registry.npmjs.org/xterm-addon-unicode11/-/xterm-addon-unicode11-0.3.0.tgz#e4435c3c91a5294a7eb8b79c380acbb28a659463"
integrity sha512-x5fHDZT2j9tlTlHnzPHt++9uKZ2kJ/lYQOj3L6xJA22xoJsS8UQRw/5YIFg2FUHqEAbV77Z1fZij/9NycMSH/A==
xterm-addon-web-links@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/xterm-addon-web-links/-/xterm-addon-web-links-0.6.0.tgz#0296cb6c99588847894670d998c9ea6a6aeb26ee"
integrity sha512-H6XzjWWZu8FBo+fnYpxdPk9w5M6drbsvwPEJZGRS38MihiQaVFpKlCMKdfRgDbKGE530tw1yH54rhpZfHgt2/A==
xterm-addon-webgl@0.12.0:
xterm-addon-search@0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0.tgz#2fba8d31890a122adafa1c2fb945482e2ae12973"
integrity sha512-3P5ihdjPnxH6Wrvqjki9UD+duoVrp1fvnO/pSpXP2F1L2GwY6TDNExgj8Yg141vMCNgQbcVqmsTLYEYZxjY92A==
resolved "https://registry.npmjs.org/xterm-addon-search/-/xterm-addon-search-0.12.0.tgz#2ef8f56aecf699a3989223a1260f1e079d7c74e2"
integrity sha512-hXAuO7Ts2+Jf9K8mZrUx8IFd7c/Flgks/jyqA1L4reymyfmXtcsd+WDLel8R9Tgy2CLyKABVBP09/Ua/FmXcvg==
xterm@4.19.0:
version "4.19.0"
resolved "https://registry.npmjs.org/xterm/-/xterm-4.19.0.tgz#c0f9d09cd61de1d658f43ca75f992197add9ef6d"
integrity sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ==
xterm-addon-unicode11@0.5.0:
version "0.5.0"
resolved "https://registry.npmjs.org/xterm-addon-unicode11/-/xterm-addon-unicode11-0.5.0.tgz#41c0d96acc1e3bb6c6596eee64e163b6bca74be7"
integrity sha512-Jm4/g4QiTxiKiTbYICQgC791ubhIZyoIwxAIgOW8z8HWFNY+lwk+dwaKEaEeGBfM48Vk8fklsUW9u/PlenYEBg==
xterm-addon-web-links@0.8.0:
version "0.8.0"
resolved "https://registry.npmjs.org/xterm-addon-web-links/-/xterm-addon-web-links-0.8.0.tgz#2cb1d57129271022569208578b0bf4774e7e6ea9"
integrity sha512-J4tKngmIu20ytX9SEJjAP3UGksah7iALqBtfTwT9ZnmFHVplCumYQsUJfKuS+JwMhjsjH61YXfndenLNvjRrEw==
xterm-addon-webgl@0.15.0:
version "0.15.0"
resolved "https://registry.npmjs.org/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0.tgz#c10f93ca619524f5a470eaac44258bab0ae8e3c7"
integrity sha512-ZLcqogMFHr4g/YRhcCh3xE8tTklnyut/M+O/XhVsFBRB/YCvYhPdLQ5/AQk54V0wjWAQpa8CF3W8DVR9OqyMCg==
xterm@5.2.1:
version "5.2.1"
resolved "https://registry.npmjs.org/xterm/-/xterm-5.2.1.tgz#b3fea7bdb55b9be1d4b31f4cd1091f26ac42afb8"
integrity sha512-cs5Y1fFevgcdoh2hJROMVIWwoBHD80P1fIP79gopLHJIE4kTzzblanoivxTiQ4+92YM9IxS36H1q0MxIJXQBcA==
y18n@^5.0.5:
version "5.0.5"