hyper/lib/components/term.tsx

462 lines
14 KiB
TypeScript
Raw Normal View History

2016-07-13 12:44:24 -08:00
import React from 'react';
2020-03-18 07:26:46 -08:00
import {Terminal, ITerminalOptions, IDisposable} from 'xterm';
import {FitAddon} from 'xterm-addon-fit';
import {WebLinksAddon} from 'xterm-addon-web-links';
import {SearchAddon} from 'xterm-addon-search';
import {WebglAddon} from 'xterm-addon-webgl';
import {LigaturesAddon} from 'xterm-addon-ligatures';
2020-06-23 02:36:07 -08:00
import {Unicode11Addon} from 'xterm-addon-unicode11';
import {clipboard, shell} from 'electron';
2020-03-18 07:26:46 -08:00
import Color from 'color';
import terms from '../terms';
import processClipboard from '../utils/paste';
import SearchBox from './searchBox';
2020-03-18 07:26:46 -08:00
import {TermProps} from '../hyper';
import {ObjectTypedKeys} from '../utils/object';
2017-06-11 02:42:39 -08:00
2019-11-28 05:17:01 -09:00
const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].includes(navigator.platform);
2017-06-11 02:42:39 -08:00
// map old hterm constants to xterm.js
const CURSOR_STYLES = {
BEAM: 'bar',
UNDERLINE: 'underline',
BLOCK: 'block'
2020-03-18 07:26:46 -08:00
} as const;
2016-06-30 22:01:04 -08:00
const isWebgl2Supported = (() => {
let isSupported = window.WebGL2RenderingContext ? undefined : false;
return () => {
if (isSupported === undefined) {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', {depth: false, antialias: false});
isSupported = gl instanceof window.WebGL2RenderingContext;
}
return isSupported;
};
})();
2020-03-18 07:26:46 -08:00
const getTermOptions = (props: TermProps): ITerminalOptions => {
2018-01-09 07:33:24 -09:00
// Set a background color only if it is opaque
2018-02-18 03:28:26 -09:00
const needTransparency = Color(props.backgroundColor).alpha() < 1;
const backgroundColor = needTransparency ? 'transparent' : props.backgroundColor;
2018-01-09 07:33:24 -09:00
return {
macOptionIsMeta: props.modifierKeys.altIsMeta,
scrollback: props.scrollback,
2018-01-09 07:33:24 -09:00
cursorStyle: CURSOR_STYLES[props.cursorShape],
cursorBlink: props.cursorBlink,
fontFamily: props.fontFamily,
fontSize: props.fontSize,
fontWeight: props.fontWeight,
fontWeightBold: props.fontWeightBold,
lineHeight: props.lineHeight,
letterSpacing: props.letterSpacing,
2018-02-18 03:28:26 -09:00
allowTransparency: needTransparency,
macOptionClickForcesSelection: props.macOptionSelectionMode === 'force',
Return of the Bell (#2938) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise.
2019-10-02 16:08:40 -08:00
bellStyle: props.bell === 'SOUND' ? 'sound' : 'none',
windowsMode: isWindows,
2018-01-09 07:33:24 -09:00
theme: {
foreground: props.foregroundColor,
background: backgroundColor,
cursor: props.cursorColor,
cursorAccent: props.cursorAccentColor,
selection: props.selectionColor,
2018-01-09 07:33:24 -09:00
black: props.colors.black,
red: props.colors.red,
green: props.colors.green,
yellow: props.colors.yellow,
blue: props.colors.blue,
magenta: props.colors.magenta,
cyan: props.colors.cyan,
white: props.colors.white,
brightBlack: props.colors.lightBlack,
brightRed: props.colors.lightRed,
brightGreen: props.colors.lightGreen,
brightYellow: props.colors.lightYellow,
brightBlue: props.colors.lightBlue,
brightMagenta: props.colors.lightMagenta,
brightCyan: props.colors.lightCyan,
brightWhite: props.colors.lightWhite
}
};
};
2020-03-18 07:26:46 -08:00
export default class Term extends React.PureComponent<TermProps> {
termRef: HTMLElement | null;
termWrapperRef: HTMLElement | null;
termOptions: ITerminalOptions;
disposableListeners: IDisposable[];
termDefaultBellSound: string | null;
fitAddon: FitAddon;
searchAddon: SearchAddon;
static rendererTypes: Record<string, string>;
term!: Terminal;
resizeObserver!: ResizeObserver;
resizeTimeout!: NodeJS.Timeout;
constructor(props: TermProps) {
2016-07-13 12:44:24 -08:00
super(props);
2017-09-09 03:42:19 -08:00
props.ref_(props.uid, this);
this.termRef = null;
this.termWrapperRef = null;
2018-01-09 07:33:24 -09:00
this.termOptions = {};
2018-12-06 14:56:29 -09:00
this.disposableListeners = [];
Return of the Bell (#2938) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise.
2019-10-02 16:08:40 -08:00
this.termDefaultBellSound = null;
this.fitAddon = new FitAddon();
this.searchAddon = new SearchAddon();
2016-07-13 12:44:24 -08:00
}
// The main process shows this in the About dialog
2020-03-18 07:26:46 -08:00
static reportRenderer(uid: string, type: string) {
const rendererTypes = Term.rendererTypes || {};
if (rendererTypes[uid] !== type) {
rendererTypes[uid] = type;
Term.rendererTypes = rendererTypes;
window.rpc.emit('info renderer', {uid, type});
}
}
componentDidMount() {
const {props} = this;
2016-06-30 22:01:04 -08:00
2018-01-09 07:33:24 -09:00
this.termOptions = getTermOptions(props);
this.term = props.term || new Terminal(this.termOptions);
Return of the Bell (#2938) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise.
2019-10-02 16:08:40 -08:00
this.termDefaultBellSound = this.term.getOption('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
2020-03-18 07:26:46 -08:00
this.termRef = props.term ? props.term.element!.parentElement! : document.createElement('div');
this.termRef.className = 'term_fit term_term';
2020-03-18 07:26:46 -08:00
this.termWrapperRef?.appendChild(this.termRef);
if (!props.term) {
2020-03-18 07:26:46 -08:00
const needTransparency = Color(props.backgroundColor).alpha() < 1;
2020-01-17 21:31:55 -09:00
let useWebGL = false;
if (props.webGLRenderer) {
if (needTransparency) {
console.warn(
'WebGL Renderer has been disabled since it does not support transparent backgrounds yet. ' +
'Falling back to canvas-based rendering.'
);
} else if (!isWebgl2Supported()) {
console.warn('WebGL2 is not supported on your machine. Falling back to canvas-based rendering.');
} else {
// Experimental WebGL renderer needs some more glue-code to make it work on Hyper.
// If you're working on enabling back WebGL, you will also need to look into `xterm-addon-ligatures` support for that renderer.
2020-01-17 21:31:55 -09:00
useWebGL = true;
}
}
Term.reportRenderer(props.uid, useWebGL ? 'WebGL' : 'Canvas');
const shallActivateWebLink = (event: Record<string, any> | undefined): boolean => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
2020-05-06 11:04:14 -08:00
return event && (!props.webLinksActivationKey || event[`${props.webLinksActivationKey}Key`]);
};
// eslint-disable-next-line @typescript-eslint/unbound-method
this.term.attachCustomKeyEventHandler(this.keyboardHandler);
this.term.loadAddon(this.fitAddon);
this.term.loadAddon(this.searchAddon);
this.term.loadAddon(
2020-05-06 11:04:14 -08:00
new WebLinksAddon(
(event: MouseEvent | undefined, uri: string) => {
if (shallActivateWebLink(event)) void shell.openExternal(uri);
2020-05-06 11:04:14 -08:00
},
{
// 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()
}
)
);
this.term.open(this.termRef);
if (useWebGL) {
this.term.loadAddon(new WebglAddon());
}
if (props.disableLigatures !== true && !useWebGL) {
this.term.loadAddon(new LigaturesAddon());
}
2020-06-23 02:36:07 -08:00
this.term.loadAddon(new Unicode11Addon());
this.term.unicode.activeVersion = '11';
} else {
// get the cached plugins
2020-03-18 07:26:46 -08:00
this.fitAddon = props.fitAddon!;
this.searchAddon = props.searchAddon!;
2017-08-02 11:05:47 -08:00
}
Update Electron to v6 (#3785) * 3.0.0 * 3.0.2 * Save * Save * Upgrade yarn lock packages * update node-gyp and node-pty * update travis and appveyor to node 12 * appveyor is outdated as always * update travis to xenial * update node-pty@0.9.0-beta26 * update yarn.lock * update electron to 6.0.8 * move node-pty to the correct package.json * Fix linting failure * Update yarn lockfile to try to fix appveyor build * Remove unnecessary changes from package.json * Try to fix appveyor by using a newer image * Fix linting after my last change * update electron to 6.0.9 * install windows-build-tools on appveyor * fix syntax * switch back to 2017 image * remove old resolutions field * revert accidental version change * update electron to 6.0.11 and electron-rebuild to 1.8.6 * downgrade yarn to 1.18 until this issue is resolved https://github.com/yarnpkg/yarn/issues/7584 * update node-gyp to 6.0.0 and generate a fresh yarn lockfile * update react and a few other dependencies * fix lint * this should actually be electron-builder, I think! * update a few dependencies * change to electron-store electron-config was renamed to electron-store a while ago * update xterm to v4.1.0 and ora to 4.0.2 * move pify to app/package.json * TODO: Revert maybe. Throw a fit on every change to maybe fix the resizing issues * a * fix react ref problem * fix split view focus problem * remove the unnecessary fit * remove the init col and row * fix the problem that cannot show about hyper * update electron to 6.0.12 * fix lint * add more todos for componentWillReceiveProps deprecation * update babel and plugins Co-authored-by: Juan Campa <juancampa@gmail.com> Co-authored-by: Benjamin Staneck <staneck@gmail.com> Co-authored-by: ivan <ivanwonder@outlook.com>
2019-10-10 11:20:26 -08:00
this.fitAddon.fit();
if (this.props.isTermActive) {
this.term.focus();
}
2017-06-11 02:42:39 -08:00
if (props.onTitle) {
this.disposableListeners.push(this.term.onTitleChange(props.onTitle));
2017-06-11 02:42:39 -08:00
}
2016-07-03 12:35:45 -08:00
2017-06-11 02:42:39 -08:00
if (props.onActive) {
2020-03-18 07:26:46 -08:00
this.term.textarea?.addEventListener('focus', props.onActive);
this.disposableListeners.push({
2020-03-18 07:26:46 -08:00
dispose: () => this.term.textarea?.removeEventListener('focus', this.props.onActive)
});
}
2017-06-11 02:42:39 -08:00
if (props.onData) {
this.disposableListeners.push(this.term.onData(props.onData));
}
2017-06-11 02:42:39 -08:00
if (props.onResize) {
2018-12-06 14:56:29 -09:00
this.disposableListeners.push(
this.term.onResize(({cols, rows}) => {
2018-12-06 14:56:29 -09:00
props.onResize(cols, rows);
})
);
Update Electron to v6 (#3785) * 3.0.0 * 3.0.2 * Save * Save * Upgrade yarn lock packages * update node-gyp and node-pty * update travis and appveyor to node 12 * appveyor is outdated as always * update travis to xenial * update node-pty@0.9.0-beta26 * update yarn.lock * update electron to 6.0.8 * move node-pty to the correct package.json * Fix linting failure * Update yarn lockfile to try to fix appveyor build * Remove unnecessary changes from package.json * Try to fix appveyor by using a newer image * Fix linting after my last change * update electron to 6.0.9 * install windows-build-tools on appveyor * fix syntax * switch back to 2017 image * remove old resolutions field * revert accidental version change * update electron to 6.0.11 and electron-rebuild to 1.8.6 * downgrade yarn to 1.18 until this issue is resolved https://github.com/yarnpkg/yarn/issues/7584 * update node-gyp to 6.0.0 and generate a fresh yarn lockfile * update react and a few other dependencies * fix lint * this should actually be electron-builder, I think! * update a few dependencies * change to electron-store electron-config was renamed to electron-store a while ago * update xterm to v4.1.0 and ora to 4.0.2 * move pify to app/package.json * TODO: Revert maybe. Throw a fit on every change to maybe fix the resizing issues * a * fix react ref problem * fix split view focus problem * remove the unnecessary fit * remove the init col and row * fix the problem that cannot show about hyper * update electron to 6.0.12 * fix lint * add more todos for componentWillReceiveProps deprecation * update babel and plugins Co-authored-by: Juan Campa <juancampa@gmail.com> Co-authored-by: Benjamin Staneck <staneck@gmail.com> Co-authored-by: ivan <ivanwonder@outlook.com>
2019-10-10 11:20:26 -08:00
// the row and col of init session is null, so reize the node-pty
props.onResize(this.term.cols, this.term.rows);
}
2016-07-13 12:44:24 -08:00
if (props.onCursorMove) {
2018-12-06 14:56:29 -09:00
this.disposableListeners.push(
this.term.onCursorMove(() => {
2018-12-06 14:56:29 -09:00
const cursorFrame = {
2020-04-13 00:03:55 -08:00
x: this.term.buffer.active.cursorX * (this.term as any)._core._renderService.dimensions.actualCellWidth,
y: this.term.buffer.active.cursorY * (this.term as any)._core._renderService.dimensions.actualCellHeight,
2020-03-18 07:26:46 -08:00
width: (this.term as any)._core._renderService.dimensions.actualCellWidth,
height: (this.term as any)._core._renderService.dimensions.actualCellHeight,
2020-04-13 00:03:55 -08:00
col: this.term.buffer.active.cursorX,
row: this.term.buffer.active.cursorY
2018-12-06 14:56:29 -09:00
};
2020-03-18 07:26:46 -08:00
props.onCursorMove?.(cursorFrame);
2018-12-06 14:56:29 -09:00
})
);
}
window.addEventListener('paste', this.onWindowPaste, {
capture: true
});
terms[this.props.uid] = this;
2016-07-13 12:44:24 -08:00
}
getTermDocument() {
console.warn(
'The underlying terminal engine of Hyper no longer ' +
'uses iframes with individual `document` objects for each ' +
'terminal instance. This method call is retained for ' +
2017-11-01 13:31:44 -08:00
"backwards compatibility reasons. It's ok to attach directly" +
'to the `document` object of the main `window`.'
);
return document;
}
// intercepting paste event for any necessary processing of
// clipboard data, if result is falsy, paste event continues
onWindowPaste = (e: Event) => {
if (!this.props.isTermActive) return;
const processed = processClipboard();
if (processed) {
e.preventDefault();
e.stopPropagation();
2021-07-20 22:17:53 -08:00
this.term.paste(processed);
}
2019-11-25 07:16:00 -09:00
};
2020-03-18 07:26:46 -08:00
onMouseUp = (e: React.MouseEvent) => {
2017-11-03 14:01:21 -08:00
if (this.props.quickEdit && e.button === 2) {
if (this.term.hasSelection()) {
clipboard.writeText(this.term.getSelection());
this.term.clearSelection();
} else {
document.execCommand('paste');
}
} else if (this.props.copyOnSelect && this.term.hasSelection()) {
2017-10-24 14:06:46 -08:00
clipboard.writeText(this.term.getSelection());
}
2019-11-25 07:16:00 -09:00
};
2017-10-24 14:06:46 -08:00
2020-03-18 07:26:46 -08:00
write(data: string | Uint8Array) {
2017-06-11 02:42:39 -08:00
this.term.write(data);
2016-07-13 12:44:24 -08:00
}
focus() {
2017-06-11 02:42:39 -08:00
this.term.focus();
2016-07-13 12:44:24 -08:00
}
clear() {
2017-06-11 02:42:39 -08:00
this.term.clear();
2017-08-02 11:05:47 -08:00
}
reset() {
2017-08-02 11:05:47 -08:00
this.term.reset();
}
2020-03-18 07:26:46 -08:00
search = (searchTerm = '') => {
this.searchAddon.findNext(searchTerm);
2019-11-25 07:16:00 -09:00
};
2020-03-18 07:26:46 -08:00
searchNext = (searchTerm: string) => {
this.searchAddon.findNext(searchTerm);
2019-11-25 07:16:00 -09:00
};
2020-03-18 07:26:46 -08:00
searchPrevious = (searchTerm: string) => {
this.searchAddon.findPrevious(searchTerm);
2019-11-25 07:16:00 -09:00
};
2019-11-25 07:16:00 -09:00
closeSearchBox = () => {
this.props.toggleSearch();
2019-11-25 07:16:00 -09:00
};
2020-03-18 07:26:46 -08:00
resize(cols: number, rows: number) {
2017-08-02 11:05:47 -08:00
this.term.resize(cols, rows);
}
selectAll() {
this.term.selectAll();
}
fitResize() {
2017-11-06 03:26:56 -09:00
if (!this.termWrapperRef) {
return;
}
this.fitAddon.fit();
2016-07-03 12:35:45 -08:00
}
2020-03-18 07:26:46 -08:00
keyboardHandler(e: any) {
// Has Mousetrap flagged this event as a command?
return !e.catched;
}
2020-03-18 07:26:46 -08:00
componentDidUpdate(prevProps: TermProps) {
Bug fixes for bell configuration (#3850) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise. * 1. Add null safety check on `configInfo.bell` if the config file does not contain this property. 2. Default bellSound to null if the file specified by the filepath in `configInfo.bellSoundUrl` failed to be read. This helps prevent a repeated error being thrown by the xterm instance. 3. Updated `term.js` to use componentDidUpdate in place of the UNSAFE lifcycle method `componentWillReceiveProps`. I found that this unsafe lifecycle was never being fired, which lead to the terminal never responding to configuration changes. Without this change, the custom bell sound was never being loaded into the xterm instance.
2019-10-08 07:13:35 -08:00
if (!prevProps.cleared && this.props.cleared) {
this.clear();
}
const nextTermOptions = getTermOptions(this.props);
// Use bellSound in nextProps if it exists
// otherwise use the default sound found in xterm.
2020-03-18 07:26:46 -08:00
nextTermOptions.bellSound = this.props.bellSound || this.termDefaultBellSound!;
Bug fixes for bell configuration (#3850) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise. * 1. Add null safety check on `configInfo.bell` if the config file does not contain this property. 2. Default bellSound to null if the file specified by the filepath in `configInfo.bellSoundUrl` failed to be read. This helps prevent a repeated error being thrown by the xterm instance. 3. Updated `term.js` to use componentDidUpdate in place of the UNSAFE lifcycle method `componentWillReceiveProps`. I found that this unsafe lifecycle was never being fired, which lead to the terminal never responding to configuration changes. Without this change, the custom bell sound was never being loaded into the xterm instance.
2019-10-08 07:13:35 -08:00
if (!prevProps.search && this.props.search) {
this.search();
}
// Update only options that have changed.
2020-03-18 07:26:46 -08:00
ObjectTypedKeys(nextTermOptions)
2020-03-25 02:15:08 -08:00
.filter((option) => option !== 'theme' && nextTermOptions[option] !== this.termOptions[option])
.forEach((option) => {
Bug fixes for bell configuration (#3850) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise. * 1. Add null safety check on `configInfo.bell` if the config file does not contain this property. 2. Default bellSound to null if the file specified by the filepath in `configInfo.bellSoundUrl` failed to be read. This helps prevent a repeated error being thrown by the xterm instance. 3. Updated `term.js` to use componentDidUpdate in place of the UNSAFE lifcycle method `componentWillReceiveProps`. I found that this unsafe lifecycle was never being fired, which lead to the terminal never responding to configuration changes. Without this change, the custom bell sound was never being loaded into the xterm instance.
2019-10-08 07:13:35 -08:00
try {
this.term.setOption(option, nextTermOptions[option]);
} catch (e) {
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 ||
2020-03-18 07:26:46 -08:00
ObjectTypedKeys(nextTermOptions.theme!).some(
2020-03-25 02:15:08 -08:00
(option) => nextTermOptions.theme![option] !== this.termOptions.theme![option]
Bug fixes for bell configuration (#3850) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise. * 1. Add null safety check on `configInfo.bell` if the config file does not contain this property. 2. Default bellSound to null if the file specified by the filepath in `configInfo.bellSoundUrl` failed to be read. This helps prevent a repeated error being thrown by the xterm instance. 3. Updated `term.js` to use componentDidUpdate in place of the UNSAFE lifcycle method `componentWillReceiveProps`. I found that this unsafe lifecycle was never being fired, which lead to the terminal never responding to configuration changes. Without this change, the custom bell sound was never being loaded into the xterm instance.
2019-10-08 07:13:35 -08:00
);
if (shouldUpdateTheme) {
this.term.setOption('theme', nextTermOptions.theme);
}
this.termOptions = nextTermOptions;
if (
this.props.fontSize !== prevProps.fontSize ||
this.props.fontFamily !== prevProps.fontFamily ||
this.props.lineHeight !== prevProps.lineHeight ||
this.props.letterSpacing !== prevProps.letterSpacing
) {
// resize to fit the container
this.fitResize();
}
if (prevProps.rows !== this.props.rows || prevProps.cols !== this.props.cols) {
2020-03-18 07:26:46 -08:00
this.resize(this.props.cols!, this.props.rows!);
Bug fixes for bell configuration (#3850) * 1. Restored the ability to turn the "bell" sound on and off using the "bell" config parameter. 2. Restored the ability to change the bell sound by providing a URL. These changes allow for a web url or local absolute file path to an audio file. The goal with these changes was to fix the issue causing the bell to never sound due to a difference in the underlying terminal emulators configurations from the previous one. While in the area, also decided to make sure that the sound can be changed by supplying a web url to an audio file or an absolute path to an audio file within the local machine * Code style changes * Code style changes * 1. More code style changes * 1. Spacing changes to try and abide by the linter * 1. Applied all suggested changes by eslint * 1. Removed functionality to specify a remote url to set a sound file for the bell sound. The amount of effort for handling when there is no internet connection, queuing and so forth wasn't worth keeping the feature. It is likely that the url could be used to download the file in which the user would be able to specify the file path tho this download file. 2. Created a new property that gets passed down from the terms container all the way to the individual term. We want to be able to evaluate if the bellSoundURL has changed to determine if we really need to read the sound file. 3. Moved logic to read the audio file into the main process. Setup a new action in the 'actions/ui' that will update the bell sound when it is finished and ready. This should prevent blocking the terminal from loading and thus increasing loading times. * 1. Modified the file reading method to be more generic to increase reusability. 2. Updated the "arrBuf2Base64" method to utilize the node Buffer class which helped to reduce some complexity and seems to run more efficiently. 3. Removed the CONFIG_ASYNC action and reducer in favor of reusing CONFIG_RELOAD when the process is finished reading the file for the bell sound. In order to achieve this, we had to merge the config from "config.getConfig()" method with the "bellSound" property before dispatching to "reloadConfig". * 1. Removed reference to now removed method * 1. Removed the arrBuf2Base64 as it seemed unnecessary now that the function would be reduced to a single line. Moved the one-liner into file.js. Removed references to arrBuf2Base64 method. 2. Refactored the logic that handles reloading the config when it has been updated to fix an issue that would set the bell sound back to the default sound when the config is saved without changing the value of "bellSoundURL". Setup now to either read file and reload the config, or reuse the "bellSound" value saved in state and reload the config. This removes an inefficiency with the reloadConfig being dispatched twice when "bellSoundURL" has changed as well. * 1. Removed a file that contained a single function, referenced in only one place that is performing a fairly simple task. 2. Updated the "getBase64FileData" method to use "Buffer.from()" instead of "Buffer()" due to messages stating that "Buffer()" is deprecated due to security and usability issues. * Adjustments and regression issues fixed 1. Updated the default config file to better explain the supported options for the "bell" config property. 2. Rearranged the bellSoundURL default property to make it easier to find should one decide to change the bell sound. 3. Typos fixed in comments. 4. Update fetchFileData to utilize the configData provided as function argument. There appeared to be no reason to reference different sources of config data within the same method. * 1. Removed the "BELL_STYLE" constant since it was only being used in one place. 2. Updated comment block to accurately reflect the current logic and made the comment much more concise. * 1. Add null safety check on `configInfo.bell` if the config file does not contain this property. 2. Default bellSound to null if the file specified by the filepath in `configInfo.bellSoundUrl` failed to be read. This helps prevent a repeated error being thrown by the xterm instance. 3. Updated `term.js` to use componentDidUpdate in place of the UNSAFE lifcycle method `componentWillReceiveProps`. I found that this unsafe lifecycle was never being fired, which lead to the terminal never responding to configuration changes. Without this change, the custom bell sound was never being loaded into the xterm instance.
2019-10-08 07:13:35 -08:00
}
}
2020-03-18 07:26:46 -08:00
onTermWrapperRef = (component: HTMLElement | null) => {
2017-09-09 03:42:19 -08:00
this.termWrapperRef = component;
if (component) {
this.resizeObserver = new ResizeObserver(() => {
clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(() => {
this.fitResize();
Update Electron to v6 (#3785) * 3.0.0 * 3.0.2 * Save * Save * Upgrade yarn lock packages * update node-gyp and node-pty * update travis and appveyor to node 12 * appveyor is outdated as always * update travis to xenial * update node-pty@0.9.0-beta26 * update yarn.lock * update electron to 6.0.8 * move node-pty to the correct package.json * Fix linting failure * Update yarn lockfile to try to fix appveyor build * Remove unnecessary changes from package.json * Try to fix appveyor by using a newer image * Fix linting after my last change * update electron to 6.0.9 * install windows-build-tools on appveyor * fix syntax * switch back to 2017 image * remove old resolutions field * revert accidental version change * update electron to 6.0.11 and electron-rebuild to 1.8.6 * downgrade yarn to 1.18 until this issue is resolved https://github.com/yarnpkg/yarn/issues/7584 * update node-gyp to 6.0.0 and generate a fresh yarn lockfile * update react and a few other dependencies * fix lint * this should actually be electron-builder, I think! * update a few dependencies * change to electron-store electron-config was renamed to electron-store a while ago * update xterm to v4.1.0 and ora to 4.0.2 * move pify to app/package.json * TODO: Revert maybe. Throw a fit on every change to maybe fix the resizing issues * a * fix react ref problem * fix split view focus problem * remove the unnecessary fit * remove the init col and row * fix the problem that cannot show about hyper * update electron to 6.0.12 * fix lint * add more todos for componentWillReceiveProps deprecation * update babel and plugins Co-authored-by: Juan Campa <juancampa@gmail.com> Co-authored-by: Benjamin Staneck <staneck@gmail.com> Co-authored-by: ivan <ivanwonder@outlook.com>
2019-10-10 11:20:26 -08:00
}, 500);
});
this.resizeObserver.observe(component);
} else {
this.resizeObserver.disconnect();
}
2019-11-25 07:16:00 -09:00
};
2017-09-09 03:42:19 -08:00
componentWillUnmount() {
2017-09-09 03:42:19 -08:00
terms[this.props.uid] = null;
2020-03-18 07:26:46 -08:00
this.termWrapperRef?.removeChild(this.termRef!);
2017-09-09 03:42:19 -08:00
this.props.ref_(this.props.uid, null);
2017-08-02 11:05:47 -08:00
// to clean up the terminal, we remove the listeners
// instead of invoking `destroy`, since it will make the
2017-08-02 11:05:47 -08:00
// term insta un-attachable in the future (which we need
// to do in case of splitting, see `componentDidMount`
2020-03-25 02:15:08 -08:00
this.disposableListeners.forEach((handler) => handler.dispose());
2018-12-06 14:56:29 -09:00
this.disposableListeners = [];
2017-08-02 11:05:47 -08:00
window.removeEventListener('paste', this.onWindowPaste, {
capture: true
});
2016-06-30 22:01:04 -08:00
}
render() {
return (
2017-10-24 14:06:46 -08:00
<div
className={`term_fit ${this.props.isTermActive ? 'term_active' : ''}`}
2017-10-24 14:06:46 -08:00
style={{padding: this.props.padding}}
onMouseUp={this.onMouseUp}
>
{this.props.customChildrenBefore}
<div ref={this.onTermWrapperRef} className="term_fit term_wrapper" />
{this.props.customChildren}
{this.props.search ? (
<SearchBox
search={this.search}
next={this.searchNext}
prev={this.searchPrevious}
close={this.closeSearchBox}
/>
) : (
''
)}
<style jsx global>{`
.term_fit {
display: block;
width: 100%;
height: 100%;
}
.term_wrapper {
/* TODO: decide whether to keep this or not based on understanding what xterm-selection is for */
overflow: hidden;
}
`}</style>
2017-08-02 11:05:47 -08:00
</div>
);
2016-06-30 22:01:04 -08:00
}
}