- Installation
- Projektziele
- Erweiterungen
- Keymaps
- Standardtastaturbelegung:
- Konfiguration
- Konfigurationsort
- Extensions API
- Laden von Modulen
- Hinweis
- Plugins Standort
- Dekorieren von Komponenten
- Aktionen und Effekte
- Das zugrunde liegende Terminal
- Zusätzliche APIs
- Beispielthema: Hyperyellow
- Beispiel für eine Erweiterung: Hyperpower
Installation
neueste Version: 3.0.2
64-bit | |
macOS (.app) | 3.0.2 |
Windows (.exe) | 3.0.2 |
Debian (.deb) | 3.0.2 |
Fedora (.rpm) | 3.0.2 |
Andere Linux-Distributionen (.AppImage) | 3.0.2 |
Projektziele
Das Ziel des Projekts ist es, eine schöne und erweiterbare Erfahrung für Benutzer der Kommandozeilenschnittstelle zu schaffen, die auf offenen Webstandards aufbaut. Am Anfang werden wir uns hauptsächlich auf Geschwindigkeit, Stabilität und die Entwicklung der richtigen API für die Autoren von Erweiterungen konzentrieren.
In der Zukunft erwarten wir, dass die Community mit innovativen Ergänzungen aufwarten wird, um das zu verbessern, was die einfachste, leistungsfähigste und gut getestete Schnittstelle für Produktivität sein könnte.
Erweiterungen
Erweiterungen sind auf npm verfügbar. Wir ermutigen jeden, hyper
in das keywords
Feld in package.json
einzutragen.
$ npm search hyper
Dann editiere .hyper.js
und füge es zu plugins
module.exports = { config: { /*... */ }, plugins: };
Hyper
wird eine Benachrichtigung anzeigen, wenn deine Module installiert sind.
Keymaps
Alle Befehlsschlüssel können geändert werden. Um sie zu ändern, bearbeiten Sie .hyper.js
und fügen Sie Ihre gewünschte Änderung zu keymaps
.
Dann wird Hyper die Standardeinstellung mit Ihrer benutzerdefinierten Änderung ändern.
Beispiel: 'window:devtools': 'Cmd+Alt+O'
module.exports = { config: { /*... */ }, keymaps: { 'window:devtools': 'cmd+alt+o' }};
Standardtastaturbelegung:
Konfiguration
Konfigurationsort
macOS | ~/Library/Application Support/Hyper/.hyper.js |
Windows | $Env:AppData/Hyper/.hyper.js |
Linux | ~/.config/Hyper/.hyper.js |
Anmerk: config bei ~/.hyper.js
wird noch unterstützt, wird aber ignoriert, wenn config im Anwendungsverzeichnis vorhanden ist. Andernfalls wird sie beim ersten Lauf in das Anwendungsverzeichnis verschoben.
Das config
Objekt, das oben in .hyper.js
gesehen wurde, gibt folgendes zu
Eigenschaft | Standard | Beschreibung |
updateChannel |
„stabil“ | Der Aktualisierungskanal, von dem Aktualisierungen empfangen werden sollen |
fontSize |
12 | Die Standardgröße in Pixel für das Terminal |
fontFamily |
„Menlo, DejaVu Sans Mono, Lucida Console, monospace“ | Die zu verwendende Schriftfamilie mit optionalen Fallbacks |
uiFontFamily |
„-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, …“ | Die für die Benutzeroberfläche zu verwendende Schriftfamilie mit optionalen Fallbacks |
fontWeight |
„normal“ | Die Standardschriftstärke: „normal“ oder „fett“ |
fontWeightBold |
„fett“ | Die Schriftstärke für fette Zeichen: „normal“ oder „bold“ |
cursorColor |
„rgba(248,28,229,0.8)“ | Die Farbe der Einfügemarke im Terminal |
cursorAccentColor |
„#000“ | Die Textfarbe unter BLOCK-Cursor |
cursorShape |
„BLOCK“ | Die Form der Einfügemarke im Terminal. Verfügbare Optionen sind: ‚BEAM‘, ‚UNDERLINE‘, ‚BLOCK‘ |
cursorBlink |
„false“ | Wenn wahr, blinkt der Cursor |
foregroundColor |
„#fff“ | Die Farbe des Haupttextes des Terminals |
backgroundColor |
„#000“ | Die Farbe und Deckkraft des Hintergrunds des Fensters und des Hauptterminals |
selectionColor |
„rgba(248,28,229,0.3)“ | Die Hintergrundfarbe/Deckkraft der Textauswahl im Terminal |
borderColor |
„#333“ | Die Farbe des Hauptfensterrandes und der Registerkartenleiste |
css |
„“ | Benutzerdefiniertes CSS für das Hauptfenster |
padding |
„12px 14px“ | CSS-Padding-Werte für den Raum um jeden Begriff |
colors |
{ black: „#000000“, red: „#ff0000“, … } | Eine Liste von Überschreibungen für die Farbpalette. Die Namen der Tasten stellen die „ANSI 16“ dar, die alle in der Standardkonfiguration zu sehen sind. |
shell |
„“ | Ein Pfad zu einer benutzerdefinierten Shell, die ausgeführt wird, wenn Hyper eine neue Sitzung startet |
shellArgs |
„“ | Ein Array von Shell-Argumenten |
env |
{} | Ein Objekt mit Umgebungsvariablen, die vor dem Shell zu setzen |
windowSize |
Die Standardbreite/-höhe in Pixeln eines neuen Fensters | |
scrollback |
1000 | Die Anzahl der Zeilen, die im Terminalpuffer für den Bildlauf beibehalten werden sollen |
copyOnSelect |
false | Wenn true, markierter Text wird automatisch in die Zwischenablage kopiert |
quickEdit |
falsch | Wenn wahr, beim Rechtsklick wird der markierte Text kopiert oder eingefügt, wenn keine Markierung vorhanden ist (unter Windows standardmäßig wahr) |
defaultSSHApp |
wahr | Wenn wahr, wird Hyper als Standard-Protokoll-Client für SSH festgelegt |
modifierKeys |
{altIsMeta: false} | Ändern Sie das Verhalten von Modifikatortasten so, dass sie als Metataste fungieren |
showHamburgerMenu |
true unter Linux/Windows, false unter macOS | Ändern Sie die Sichtbarkeit des Hamburger-Menüs. Verfügbare Optionen sind: true, false |
showWindowControls |
„“ | Ändern Sie die Position/Sichtbarkeit der Fenstersteuerungen. Verfügbare Optionen sind: true, false, „left“ |
Extensions API
Extensions sind universelle Node.js-Module, die sowohl von Electron als auch vom Renderer-Prozess geladen werden.
Das Extensions-System wurde um die Komposition der APIs herum entwickelt, die wir zur Erstellung des Terminals verwenden: React
Komponenten und Redux
Aktionen.
Anstatt für jeden möglichen Anpassungspunkt eine eigene API-Methode oder einen eigenen Parameter bereitzustellen, ermöglichen wir es, jedes bisschen Funktionalität abzufangen und zu komponieren!
Das einzige Wissen, das daher erforderlich ist, um Hyper
erfolgreich zu erweitern, ist das der zugrunde liegenden Open-Source-Bibliotheken.
Weitere Details zur Plugin-Entwicklung finden Sie im Hyper-Repository.
Ihr Modul muss mindestens eine dieser Methoden zur Verfügung stellen:
Methode | Aufgerufen von | Beschreibung | ||||||
onApp |
Elektron |
Aufgerufen beim ersten Laden der App. Wenn ein Plugin neu geladen wird, wird es erneut mit der vorhandenen App aufgerufen. Parameter:
|
||||||
onWindow |
Electron |
Wird beim Erstellen jedes Fensters aufgerufen. Wenn ein Plugin neu geladen wird, wird es mit den vorhandenen Fenstern erneut aufgerufen. Parameter:
|
||||||
onUnload |
Elektron |
Wird aufgerufen, wenn ein Plugin vom Benutzer entfernt wird. Parameter:
|
||||||
decorateConfig |
Electron / Renderer |
v0.5.0+. Ermöglicht es Ihnen, die Konfiguration des Benutzers zu dekorieren. Parameter:
|
||||||
decorateEnv |
Elektron |
v0.7.0+. Ermöglicht es, die Umgebung des Benutzers zu dekorieren, indem ein modifiziertes Umgebungsobjekt zurückgegeben wird. Parameter:
|
||||||
decorateMenu |
Electron |
Aufgerufen mit der Parameter:
|
||||||
decorateBrowserOptions |
Electron |
Ermöglicht es, Electron’s Parameter:
|
||||||
onRendererWindow |
Renderer |
Wird aufgerufen, wenn ein Plugin zum ersten Mal oder später in jedem Fenster neu geladen wird. Parameter:
|
||||||
middleware |
Renderer |
Eine benutzerdefinierte Redux-Middleware, die jede Aktion abfangen kann. Anschließend rufen wir die |
||||||
reduceUI reduceSessions reduceTermGroups |
Renderer |
Ein benutzerdefinierter Reducer für die
|
||||||
getTabsProps |
Renderer |
Gibt Props von
|
||||||
getTabProps |
Renderer |
Übergibt Props von
|
||||||
getTermGroupProps |
Renderer |
Gibt Props von
|
||||||
getTermProps |
Renderer |
Gibt Props von
|
||||||
mapHyperState mapTermsState mapHeaderState mapNotificationsState |
Renderer |
Ein benutzerdefinierter Mapper für die Zustandseigenschaften, die Container-Komponenten erhalten. Beachte, dass du für untergeordnete Komponenten diese Eigenschaften mit den entsprechenden Methoden (wie Muss ein erweitertes Objekt der übergebenen Abbildung zurückgeben.
|
||||||
mapHyperDispatch mapTermsDispatch mapHeaderDispatch mapNotificationsDispatch |
Renderer |
Ein benutzerdefinierter Mapper für die Versandeigenschaften. Muss ein erweitertes Objekt der übergebenen Map zurückgeben.
|
||||||
decorateHyper decorateNotifications decorateNotification decorateHeader decorateTabs decorateTab decorateTerms decorateTermGroup decorateSplitPane decorateTerm
|
Renderer |
Aufgerufen mit dem Parameter:
|
Laden von Modulen
Der Benutzer kann Plugins durch Drücken der Tastenkombination Command + R (Aktualisieren) heiß laden und neu laden. Bitte bemühen Sie sich, Plugins zu erstellen, die keinen kompletten Neustart der Anwendung erfordern, um zu funktionieren.
Hinweis
Plugins, die das `BrowserWindow` beeinflussen, wirken sich nach dem Hot-Reload auf neue Fenster aus.
In Zukunft werden wir dies vielleicht automatisch tun.
Wenn Sie entwickeln, können Sie Ihr Plugin zu .hyper_plugins/local
hinzufügen und es dann unter dem localPlugins
-Array in .hyper.js
angeben. Wir laden neue Plugins:
- Periodisch (alle paar Stunden)
- Wenn Änderungen an der Konfigurationsdatei vorgenommen werden (
plugins
oderlocalPlugins
) - Wenn der Benutzer auf Plugins >Alle jetzt aktualisieren klickt
Der Prozess des Nachladens beinhaltet
- Ausführen von
npm prune
undnpm install
in.hyper_plugins
. - Ausführen von
require.cache
sowohl in Electron als auch im Renderer-Prozess - Aufrufen von
on*
Methoden für die vorhandenen Instanzen und erneutes Rendern der Komponenten mit den neuen Dekorationen.
Plugins Standort
macOS | ~/Library/Application Support/Hyper/.hyper_plugins |
Windows | $Env:AppData/Hyper/.hyper_plugins |
Linux | ~/.config/Hyper/.hyper_plugins |
Hinweis: Plugins unter ~/.hyper_plugins
werden weiterhin unterstützt, werden aber ignoriert, wenn Plugins im Anwendungsverzeichnis vorhanden sind. Andernfalls werden sie beim ersten Start in das Anwendungsverzeichnis verschoben.
Hinweis: Auf dem Hauptprozess werden Plugins so schnell wie möglich registriert (wir feuern onLoad
). Im Browser ist es Sache des Benutzers, das Laden der Plugins durch Drücken von Befehl+R auszulösen. Wir geben dem Benutzer auf diese Weise die Kontrolle über das Laden, um zu verhindern, dass er kritische Arbeit durch Erweiterungen verliert, die den Status zurücksetzen oder ihn nicht korrekt bewahren.
Dekorieren von Komponenten
Wir geben Ihnen die Möglichkeit, eine Komponente höherer Ordnung für jedes Stück der Hyper
UI bereitzustellen.
Seine Struktur ist wie folgt:
<Hyper> <Header> <Tabs> <Tab /> ... </Tabs> </Header> <Terms> <TermGroup> <SplitPane> <TermGroup> <Term /> ... </TermGroup> <TermGroup> <Term /> ... </TermGroup> </SplitPane> </TermGroup> </Terms> <Notifications> <Notification /> ... </Notifications></Hyper>
Alle decorate*
Methoden erhalten die folgenden Referenzen in einem Objekt, das als zweiter Parameter übergeben wird:
React |
Der gesamte React-Namespace. |
notify |
Eine Hilfsfunktion, die eine Desktop-Benachrichtigung anzeigt. Der erste Parameter ist der Titel, der zweite ist der optionale Körper der Benachrichtigung, und der dritte ist ein weiterer optionaler Parameter, der verwendet werden kann, um Details an die Entwicklungskonsole zu protokollieren. Um diese Details zu übergeben, stellen Sie einfach ein Objekt mit einer |
Notification |
Die Notification -Komponente, falls Sie sie wiederverwenden möchten. |
Alle Komponenten akzeptieren die folgenden zwei Eigenschaften, um ihr Markup zu erweitern:
customChildren |
Ein Array von Element oder ein einzelnesElement , das am unteren Ende der Komponente eingefügt wird. |
customChildrenBefore |
Das Gleiche wie die obige Eigenschaft, aber eingefügt als erste(s) Kindelement(e) der Komponente. |
Ihre übergeordnete Komponente kann der dekorierten Komponente eine onDecorated
Eigenschaft liefern, um einen Verweis auf ihre Instanz zu erhalten.
Ihre Term-Komponente höherer Ordnung kann eine onCursorMove
Handler-Eigenschaft liefern, die aufgerufen wird, wenn der Cursor mit einem Objektparameter, der seine relative Position zum Term-Ursprung darstellt, bewegt wurde:
x |
Horizontale Position in Pixel |
y |
Vertikale Position in Pixel |
width |
Cursor-Breite in Pixel |
height |
Cursorhöhe in Pixeln |
col |
Horizontale Position in Spalten |
row |
Vertikale Position in Zeilen |
Wir ermutigen Sie, die Kompatibilität mit anderen Dekoratoren zu wahren. Da viele gesetzt werden können, gehen Sie nicht davon aus, dass Ihr Dekorator der einzige ist.
Wenn Sie zum Beispiel Kinder übergeben, komponieren Sie potenziell vorhandene Werte:
render () { const customChildren = Array.from(this.props.customChildren) .concat(<p>My new child</p>); return <Tab {...this.props} customChildren={customChildren} />}
Oder wenn Sie onDecorated
Eigenschaft
onDecorated (term) { this.term = term; if (this.props.onDecorated) { this.props.onDecorated(term); }}
Aktionen und Effekte
Alle Redux-Aktionen stehen Ihnen zur Verfügung, um sie über Ihre Middleware und Reducer zu verarbeiten. Ein Beispiel finden Sie im Hyperpower-Referenz-Plugin.
Seiteneffekte treten in zwei grundlegenden Formen auf:
- Einige Aktionen senden andere Aktionen basierend auf dem Zustand.
- Einige Aktionen arbeiten asynchron, indem sie über den RPC-Kanal mit dem Hauptprozess kommunizieren
In allen Fällen wird der Seiteneffekt als effect
Schlüssel in der Aktion übergeben und später von unserer Middleware behandelt.
Das bedeutet, dass Sie Effekte überschreiben, zusammenstellen oder komplett eliminieren können! Mit anderen Worten, auf diese Weise können Sie die Standardfunktionalität oder das Verhalten der Anwendung ändern.
Betrachten Sie als Beispiel die Aktion, die wir verwenden, um die Schriftgröße zu erhöhen, wenn Sie Command+=
drücken:
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 }); } }); };}
Das zugrunde liegende Terminal
Hyper
erreicht einen Großteil seiner Geschwindigkeit und Funktionalität dank der Leistungsfähigkeit von xterm.js
Zusätzliche APIs
Die Electron app
-Objekte werden mit den folgenden Eigenschaften erweitert:
config |
Ein Object mit dem config -Block aus .hyper.js . |
plugins |
Ein Object mit Helfern für Plugins. |
getWindows |
Ein Function , das ein Set aller offenen Fenster zurückgibt. |
createWindow |
Ein Function , das ein neues Fenster erstellt. Akzeptiert ein optionales callback , das als init Callback des neuen Fensters übergeben wird. |
Electron BrowserWindow
Objekte werden mit den folgenden Parametern erweitert:
rpc |
Ein EventEmitter , das die Kommunikation mit dem Fensterprozess ermöglicht. |
sessions |
Ein Map von Session Objekten, die die Kommunikation mit dem pty. eines jeden Terms halten. |
Renderer-Fenster werden ähnlich erweitert mit:
rpc |
Ein EventEmitter , das die Kommunikation mit dem Fensterprozess ermöglicht. |
store |
Das Redux Store Objekt. Dieses erlaubt den Zugriff auf dispatch Aktionen oder das Lesen des globalen Status mit getState . |
Das rpc
Objekt ist symmetrisch zwischen Browser und Renderer-Prozess. Die API ist die gleiche wie bei Node.js, mit der Ausnahme, dass sie nur ein einziges Objekt als Parameter zulässt:
window.rpc.emit('hi there', { some: 'payload', any: });
Beispielthema: Hyperyellow
Die folgende Erweiterung ändert einfach die Konfiguration, um CSS und gelbe Farben hinzuzufügen! Hier ist der Code.
Themes sind einfach Plugins! Nur ein Hook, decorateConfig
wird benötigt:
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; } ` });}
Ich habe mir die Klassennamen geholt, indem ich den Begriff mit Devtools inspiziert habe, was man über View -> Toggle Developer Tools
auslösen kann. Dabei fällt auf, dass einige Klassen automatisch generiert werden und von einer zufälligen Nonce gefolgt werden (z. B.: term_13hv8io
). Ignorieren Sie diese: sie ändern sich mit jedem neuen Fenster!
Beachten Sie die Betonung des Zusammenspiels mit anderen Erweiterungen. Wir erstellen ein neues Objekt, erweitern nur die Schlüssel, die uns interessieren, und stellen das CSS so zusammen, dass die Einstellungen des Benutzers und die der anderen Autoren erhalten bleiben:
return Object.assign({}, config, { css: ` ${config.css || ''} /* your css here */ `});
Beispiel für eine Erweiterung: Hyperpower
Die folgende Erweiterung rendert Partikel, wenn sich der Cursor bewegt:
Lassen Sie uns durch den Code gehen.
Zunächst fangen wir die Redux-Aktion SESSION_ADD_DATA
ab. Sie können die vollständige Liste der Aktionen im Repository finden.
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); }};
Beachten Sie, dass wir die Aktion nicht erneut versenden, was bedeutet, dass wir die Ausgabe des Befehls nie in das Terminal übertragen. Stattdessen versenden wir eine eigene Aktion, die wir in uiReducer
aufnehmen und später zuordnen:
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 });};
Wir wollen dann die Komponente <Term>
dekorieren, damit wir auf das zugrundeliegende Caret zugreifen können.
Allerdings ist <Term>
kein Container, dem wir Requisiten zuordnen können. Also verwenden wir getTermProps
, um die Eigenschaft weiterzugeben:
exports.getTermProps = (uid, parentProps, props) => { return Object.assign(props, { wowMode: parentProps.wowMode });}
Die Erweiterung gibt dann eine Komponente höherer Ordnung zurück, um <Term>
zu verpacken. Beachten Sie, dass wir die onDecorated
Eigenschaft übergeben, um auf die Term-Basiskomponente und ihre DOM-Referenz zuzugreifen, und die onCursorMove
Eigenschaft, um die Hyper Cursor-API zu verwenden:
render () { return React.createElement(Term, Object.assign({}, this.props, { onDecorated: this._onDecorated, onCursorMove: this._onCursorMove }));}