| Mar | APR | May |
| 06 | ||
| 2021 | 2022 | 2023 |
COLLECTED BY
Collection: GDELT Project
| 64-bit | arm64 | |
| macOS (.app) | v3.2.1 | v3.2.1 |
| Windows (.exe) | v3.2.1 | N/A |
| Debian (.deb) | v3.2.1 | v3.2.1 |
| Fedora (.rpm) | v3.2.1 | v3.2.1 |
| More Linux distros (.AppImage) | v3.2.1 | v3.2.1 |
hyper in the keywordsfield in package.json.
$ npm search hyper
Then edit .hyper.js and add it to plugins
module.exports = {
config: { /*... */ },
plugins: [
"hyperpower"
]
};
Hyper will show a notification when your modules are installed to .hyper_plugins.
.hyper.js and add your desired change to keymaps.
Then Hyper will change the default with your custom change.
Example: 'window:devtools': 'Cmd+Alt+O'
module.exports = {
config: { /*... */ },
keymaps: {
'window:devtools': 'cmd+alt+o'
}
};
| macOS | ~/Library/Application Support/Hyper/.hyper.js |
| Windows | $Env:AppData/Hyper/.hyper.js |
| Linux | ~/.config/Hyper/.hyper.js |
~/.hyper.js still supported, but will be ignored, if config in application directory present. Otherwise it will be moved to the application directory at first run.
The config object seen above in .hyper.js admits the following
| Property | Default | Description |
updateChannel | "stable" | The update channel to receive updates from |
fontSize | 12 | The default size in pixels for the terminal |
fontFamily | "Menlo, DejaVu Sans Mono, Lucida Console, monospace" | The font family to use with optional fallbacks |
uiFontFamily | "-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, ..." | The font family to use for the UI with optional fallbacks |
fontWeight | "normal" | The default font weight: "normal" or "bold" |
fontWeightBold | "bold" | The font weight for bold characters: "normal" or "bold" |
cursorColor | "rgba(248,28,229,0.8)" | The color of the caret in the terminal |
cursorAccentColor | "#000" | The text color under BLOCK cursor |
cursorShape | "BLOCK" | The shape of the caret in the terminal. Available options are: 'BEAM', 'UNDERLINE', 'BLOCK' |
cursorBlink | "false" | If true, cursor will blink |
foregroundColor | "#fff" | The color of the main text of the terminal |
backgroundColor | "#000" | The color and opacity of the window and main terminal background |
selectionColor | "rgba(248,28,229,0.3)" | The background color/opacity of the text selection in terminal |
borderColor | "#333" | The color of the main window border and tab bar |
css | "" | Custom CSS to include in the main window |
padding | "12px 14px" | CSS padding values for the space around each term |
colors | { black: "#000000", red: "#ff0000", ... } | A list of overrides for the color palette. The names of the keys represent the "ANSI 16", which can all be seen in the default config. |
shell | "" | A path to a custom shell to run when Hyper starts a new session |
shellArgs | "['--login']" | An array of shell arguments |
env | {} | An object of environment variables to set before launching shell |
windowSize | [540, 380] | The default width/height in pixels of a new window |
scrollback | 1000 | The number of rows to be persisted in terminal buffer for scrolling |
copyOnSelect | false | If true, selected text will automatically be copied to the clipboard |
quickEdit | false | If true, on right click selected text will be copied or pasted if no selection is present (true by default on Windows) |
defaultSSHApp | true | If true, Hyper will be set as the default protocol client for SSH |
modifierKeys | {altIsMeta: false} | Change the behaviour of modifier keys to act as meta key |
showHamburgerMenu | true on Linux/Windows, false on macOS | Change the visibility of the hamburger menu. Available options are: true, false |
showWindowControls | "" | Change the position/visibility of the window controls. Available options are: true, false, "left" |
React components and Redux actions.
Instead of exposing a custom API method or parameter for every possible customization point, we allow you to intercept and compose every bit of functionality!
The only knowledge that is therefore required to successfully extend Hyper is that of its underlying open source libraries.
You can find additional details about plugin development in the Hyper repository.
Your module has to expose at least one of these methods:
| Method | Invoked from | Description | ||||||
onApp | Electron | Invoked when the app first loads. If a plugin reloads, it's invoked again with the existing app. Parameters:
| ||||||
onWindow | Electron | Invoked when each window is created. If a plugin reloads, it's invoked again with the existing windows. Parameters:
| ||||||
onUnload | Electron | Invoked when a plugin is removed by the user. Parameters:
| ||||||
decorateConfig | Electron / Renderer |
v0.5.0+. Allows you to decorate the user's configuration. Parameters:
| ||||||
decorateEnv | Electron | v0.7.0+. Allows you to decorate the user's environment by returning a modified environment object. Parameters:
| ||||||
decorateMenu | Electron |
Invoked with the Electron's Parameters:
| ||||||
decorateBrowserOptions | Electron |
Allows you to decorate Electron's Parameters:
| ||||||
onRendererWindow | Renderer | Invoked when a plugin is first loaded or subsequently reloaded in each window. Parameters:
| ||||||
middleware | Renderer |
A custom Redux middleware that can intercept any action. Subsequently we invoke the | ||||||
reduceUIreduceSessionsreduceTermGroups | Renderer |
A custom reducer for the
| ||||||
getTabsProps | Renderer |
Passes down props from
| ||||||
getTabProps | Renderer |
Passes down props from
| ||||||
getTermGroupProps | Renderer |
Passes down props from
| ||||||
getTermProps | Renderer |
Passes down props from
| ||||||
mapHyperStatemapTermsStatemapHeaderStatemapNotificationsState | Renderer |
A custom mapper for the state properties that container components receive. Note that for children components to get these properties, you have to pass them down using the corresponding methods (like Must return an extended object of the map passed.
| ||||||
mapHyperDispatchmapTermsDispatchmapHeaderDispatchmapNotificationsDispatch | Renderer | A custom mapper for the dispatch properties. Must return an extended object of the map passed.
| ||||||
decorateHyperdecorateNotificationsdecorateNotificationdecorateHeaderdecorateTabsdecorateTabdecorateTermsdecorateTermGroupdecorateSplitPanedecorateTerm | Renderer |
Invoked with the Parameters:
|
.hyper_plugins/local and then specify it under the localPlugins array in .hyper.js. We load new plugins:
●Periodically (every few hours)
●When changes are made to the configuration file (pluginsorlocalPlugins)
●When the user clicks Plugins > Update all now
The process of reloading involves
●Running npm prune and npm installin .hyper_plugins.
●Pruning the require.cache in both electron and the renderer process
●Invoking on* methods on the existing instances and re-rendering components with the fresh decorations in place.
| macOS | ~/Library/Application Support/Hyper/.hyper_plugins |
| Windows | $Env:AppData/Hyper/.hyper_plugins |
| Linux | ~/.config/Hyper/.hyper_plugins |
~/.hyper_plugins still supported, but will be ignored, if plugins in application directory present. Otherwise they will be moved to the application directory at first run.
Note: on the main process, plugins are registered as soon as possible (we fire onLoad). On the browser, it's up to the user to trigger their load by pressing command+R. We put the user in control of the loading in this way to prevent them from losing critical work by extensions that reset state or don't preserve it correctly.
Hyper UI.
Its structure is as follows:
<Hyper>
<Header>
<Tabs>
<Tab /> ...
</Tabs>
</Header>
<Terms>
<TermGroup>
<SplitPane>
<TermGroup>
<Term /> ...
</TermGroup>
<TermGroup>
<Term /> ...
</TermGroup>
</SplitPane>
</TermGroup>
</Terms>
<Notifications>
<Notification /> ...
</Notifications>
</Hyper>
All the decorate* methods receive the following references in an object passed as the second parameter:
React | The entire React namespace. |
notify | A helper function that shows a desktop notification. The first parameter is the title, the second is the optional body of the notification, and the third is another optional parameter which can be used to log details to the development console.
To pass these details, simply provide and object with an |
Notification | The Notification component in case you want to re-use it. |
customChildren | An array of Element or a singleElement to insert at the bottom of the component. |
customChildrenBefore | The same as the above property, but inserted as the first child element(s) of the component. |
onDecoratedproperty to the decorated component to get a reference to its instance.
Your Term higher order component can supply an onCursorMovehandler property that be called when cursor has moved with an object parameter representing its relative position to Term origin:
x | Horizontal position in pixels |
y | Vertical position in pixels |
width | Cursor width in pixels |
height | Cursor height in pixels |
col | Horizontal position in columns |
row | Vertical position in rows |
render () {
const customChildren = Array.from(this.props.customChildren)
.concat(<p>My new child</p>);
return <Tab {...this.props} customChildren={customChildren} />
}
Or if you use onDecorated property
onDecorated (term) {
this.term = term;
if (this.props.onDecorated) {
this.props.onDecorated(term);
}
}
effect key in the action and later handled by our middleware.
This means that you can override, compose or completely eliminate effects! In other words, this is how you can change the default functionality or behavior of the app.
As an example, consider the action we use to increase the font size when you press Command+=:
export function increaseFontSize () {
return (dispatch, getState) => {
dispatch({
type: UI_FONT_SIZE_INCR,
effect () {
const state = getState();
const old = state.ui.fontSizeOverride || state.ui.fontSize;
const value = old + 1;
dispatch({
type: UI_FONT_SIZE_SET,
value
});
}
});
};
}
Hyper achieves a lot of its speed and functionality thanks to the power of xterm.js
app objects are extended with the following properties:
config | AnObject with the config block from .hyper.js. |
plugins | AnObject with helpers for plugins. |
getWindows | AFunction that returns an Set of all the open windows. |
createWindow | AFunction that will create a new window. Accepts an optional callback that will be passed as the new window's init callback. |
BrowserWindow objects are extended with the following parameters:
rpc | AnEventEmitter that allows for communication with the window process. |
sessions | AMapofSessionobjects which hold the communication with each term's pty.. |
rpc | AnEventEmitter that allows for communication with the window process. |
store | The Redux Store object. This allows access to dispatch actions or read the global state with getState. |
rpc object is symmetrical between browser and renderer process. The API is the same as Node.js, with the exception that it only admits a single object as its parameters only:
window.rpc.emit('hi there', {
some: 'payload',
any: [
'object',
'here'
]
});
decorateConfigis needed:
exports.decorateConfig = (config) => {
return Object.assign({}, config, {
borderColor: 'yellow',
cursorColor: 'yellow',
css: `
${config.css || ''}
.tabs_nav .tabs_list .tab_text {
color: yellow;
}
.tabs_nav .tabs_title {
color: yellow;
}
`
});
}
I grabbed the class names by inspecting the term with Devtools, which you can trigger from View -> Toggle Developer Tools. When you do so, notice that some classes are automatically generated and followed by a random nonce (e.g.: term_13hv8io). Ignore those: they change with every new window!
Notice the emphasis on playing nice with other extensions. Specifically, we create a new object, extend only the keys we are interested in, and we compose the CSS to preserve the user's setting and that of other authors':
return Object.assign({}, config, {
css: `
${config.css || ''}
/* your css here */
`
});
SESSION_ADD_DATA. You can find the full list of actions in the repository.
exports.middleware = (store) => (next) => (action) => {
if ('SESSION_ADD_DATA' === action.type) {
const { data } = action;
if (/bash: wow: command not found/.test(data)) {
store.dispatch({
type: 'WOW_MODE_TOGGLE'
});
} else {
next(action);
}
} else {
next(action);
}
};
Notice that we don't re-dispatch the action, which means we never render the output of the command to the terminal. Instead, we dispatch an action of our own, which we grab in the uiReducerand later map:
exports.reduceUI = (state, action) => {
switch (action.type) {
case 'WOW_MODE_TOGGLE':
return state.set('wowMode', !state.wowMode);
}
return state;
};
exports.mapTermsState = (state, map) => {
return Object.assign(map, {
wowMode: state.ui.wowMode
});
};
We then want to decorate the <Term> component so that we can access the underlying caret.
However, <Term> is not a container that we can map props to. So we use getTermProps to pass the property further down:
exports.getTermProps = (uid, parentProps, props) => {
return Object.assign(props, {
wowMode: parentProps.wowMode
});
}
The extension then returns a higher order component to wrap <Term>. Notice we pass the onDecoratedproperty to access the base Term component and its DOM ref, and the onCursorMove property to use Hyper cursor API:
render () {
return React.createElement(Term, Object.assign({}, this.props, {
onDecorated: this._onDecorated
, onCursorMove: this._onCursorMove
}));
}
ChangelogGitHubLicense: MIT
▲