Instalacja
najnowsza wersja: 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 |
Inne dystrybucje Linuksa (.AppImage) | 3.0.2 |
Cele projektu
Celem projektu jest stworzenie pięknego i rozszerzalnego doświadczenia dla użytkowników interfejsu wiersza poleceń, zbudowanego na otwartych standardach sieciowych. Na początku skupimy się głównie na szybkości, stabilności i rozwoju poprawnego API dla autorów rozszerzeń.
W przyszłości przewidujemy, że społeczność wymyśli innowacyjne dodatki, aby ulepszyć to, co może być najprostszym, najpotężniejszym i dobrze przetestowanym interfejsem dla produktywności.
Rozszerzenia
Rozszerzenia są dostępne na npm. Zachęcamy wszystkich do włączenia hyper
do pola keywords
w package.json
.
$ npm search hyper
Potem edytuj .hyper.js
i dodaj go do plugins
module.exports = { config: { /*... */ }, plugins: };
Hyper
pokaże się powiadomienie, gdy twoje moduły zostaną zainstalowane do .hyper_plugins
.
Keymapy
Wszystkie klucze poleceń mogą zostać zmienione. Aby je zmienić, edytuj .hyper.js
i dodaj swoją pożądaną zmianę do keymaps
.
Wtedy Hyper zmieni domyślne z twoją niestandardową zmianą.
Przykład: 'window:devtools': 'Cmd+Alt+O'
module.exports = { config: { /*... */ }, keymaps: { 'window:devtools': 'cmd+alt+o' }};
Domyślne keymapy:
Configuration
Config location
macOS | ~/Library/Application Support/Hyper/.hyper.js |
Windows | $Env:AppData/Hyper/.hyper.js |
Linux | ~/.config/Hyper/.hyper.js |
Note: config na ~/.hyper.js
nadal obsługiwany, ale będzie ignorowany, jeśli config w katalogu aplikacji jest obecny. W przeciwnym razie zostanie on przeniesiony do katalogu aplikacji przy pierwszym uruchomieniu.
Obiekt config
widziany powyżej w .hyper.js
przyznaje następujące cechy
Właściwość | Default | Opis |
updateChannel |
„stable” | Kanał aktualizacji, z którego mają być odbierane aktualizacje |
fontSize |
12 | Domyślny rozmiar w pikselach dla terminala |
fontFamily |
„Menlo, DejaVu Sans Mono, Lucida Console, monospace” | Rodzina czcionek do użycia z opcjonalnymi fallbackami |
uiFontFamily |
„-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, …” | Rodzina czcionek do użycia dla UI z opcjonalnymi fallbackami |
fontWeight |
„normal” | Domyślna waga czcionki: „normal” lub „bold” |
fontWeightBold |
„bold” | Waga czcionki dla pogrubionych znaków: „normal” lub „bold” |
cursorColor |
„rgba(248,28,229,0.8)” | Kolor careta w terminalu |
cursorAccentColor |
„#000” | Kolor tekstu pod kursorem BLOCK |
cursorShape |
„BLOCK” | Kształt careta w terminalu. Dostępne opcje to: 'BEAM’, 'UNDERLINE’, 'BLOCK’ |
cursorBlink |
„false” | Jeśli true, kursor będzie migał |
foregroundColor |
„#fff” | Kolor głównego tekstu terminala |
backgroundColor |
„#000” | Kolor i krycie tła okna i głównego terminala |
selectionColor |
„rgba(248,28,229,0.3)” | Kolor tła/matowość zaznaczenia tekstu w terminalu |
borderColor |
„#333” | Kolor obramowania okna głównego i paska kart |
css |
„” | Niestandardowy CSS do włączenia w oknie głównym |
padding |
„12px 14px” | Wartości CSS padding dla przestrzeni wokół każdego terminu |
colors |
{ black: „#0000”, red: „#ff0000”, … } | Lista nadpisań dla palety kolorów. Nazwy klawiszy reprezentują „ANSI 16”, które wszystkie można zobaczyć w domyślnym configu. |
shell |
„” | Ścieżka do niestandardowej powłoki uruchamianej, gdy Hyper rozpoczyna nową sesję |
shellArgs |
„” | Tablica argumentów powłoki |
env |
{} | Obiekt zmiennych środowiskowych do ustawienia przed uruchomieniem uruchomieniem powłoki |
windowSize |
Domyślna szerokość/wysokość w pikselach nowego okna | |
scrollback |
1000 | Liczba wierszy do zachowania w buforze terminala dla przewijania |
copyOnSelect |
false | Jeśli true, zaznaczony tekst zostanie automatycznie skopiowany do schowka |
quickEdit |
false | Jeśli true, po kliknięciu prawym przyciskiem myszy wybrany tekst zostanie skopiowany lub wklejony, jeśli nie ma zaznaczenia (domyślnie true w Windows) |
defaultSSHApp |
true | Jeśli true, Hyper zostanie ustawiony jako domyślny klient protokołu dla SSH |
modifierKeys |
{altIsMeta: false} | Zmień zachowanie klawiszy modyfikatorów, aby działały jako klucze meta |
showHamburgerMenu |
true na Linux/Windows, false na macOS | Zmień widoczność menu hamburger. Dostępne opcje to: true, false |
showWindowControls |
„” | Zmień położenie/widoczność kontrolek okna. Dostępne opcje to: true, false, „left” |
Extensions API
Extensions to uniwersalne moduły Node.js ładowane zarówno przez Electrona jak i proces renderowania.
System rozszerzeń został zaprojektowany wokół kompozycji API, których używamy do budowy terminala: React
komponentów i Redux
akcji.
Zamiast eksponować niestandardową metodę API lub parametr dla każdego możliwego punktu dostosowania, pozwalamy ci przechwycić i skomponować każdy bit funkcjonalności!
Jedyną wiedzą, która jest zatem wymagana do pomyślnego rozszerzenia Hyper
, jest wiedza o jego bazowych bibliotekach open source.
Dodatkowe szczegóły na temat tworzenia wtyczek można znaleźć w repozytorium Hyper.
Twój moduł musi eksponować co najmniej jedną z tych metod:
Method | Invoked from | Description | ||||||
onApp |
Electron |
Wywołana przy pierwszym załadowaniu aplikacji. Jeśli plugin przeładowuje się, jest wywoływany ponownie z istniejącą aplikacją. Parametry:
|
||||||
onWindow |
Electron |
Invoked when each window is created. Jeśli plugin się przeładuje, jest wywoływany ponownie z istniejącymi oknami. Parametry:
|
||||||
onUnload |
Elektron |
Invoked when a plugin is removed by the user. Parametry:
|
||||||
decorateConfig |
Electron / Renderer |
v0.5.0+. Umożliwia dekorowanie konfiguracji użytkownika. Parametry:
|
||||||
decorateEnv |
Elektron |
v0.7.0+. Umożliwia dekorowanie środowiska użytkownika przez zwrócenie zmodyfikowanego obiektu środowiska. Parametry:
|
||||||
decorateMenu |
Electron |
Wywołany za pomocą szablonu Parametry:
|
||||||
Electron |
Pozwala udekorować Parametry:
|
|||||||
onRendererWindow |
Renderer |
Wywoływany przy pierwszym załadowaniu lub późniejszym przeładowaniu wtyczki w każdym oknie. Parametry:
|
||||||
middleware |
Renderer |
Niestandardowe oprogramowanie pośrednie Redux, które może przechwycić każdą akcję. Następnie wywołujemy |
||||||
reduceUI reduceSessions reduceTermGroups |
Renderer |
Niestandardowy reduktor dla
|
||||||
getTabsProps |
Renderer |
Przekazuje rekwizyty z
|
||||||
getTabProps |
Renderer |
Przekazuje rekwizyty z
|
||||||
getTermGroupProps |
Renderer |
Przekazuje rekwizyty z
|
||||||
getTermProps |
Renderer |
Przekazuje rekwizyty z
|
||||||
mapHyperState mapTermsState mapHeaderState mapNotificationsState |
Renderer |
Niestandardowy mapper dla właściwości stanu, które otrzymują komponenty kontenera. Zauważ, że aby dzieci komponentów otrzymały te właściwości, musisz przekazać je w dół za pomocą odpowiednich metod (jak Musi zwrócić rozszerzony obiekt przekazanej mapy.
|
||||||
mapHyperDispatch mapTermsDispatch mapHeaderDispatch mapNotificationsDispatch |
Renderer |
Niestandardowy mapper dla właściwości wysyłki. Musi zwracać rozszerzony obiekt przekazanej mapy.
|
||||||
decorateHyper decorateNotifications decorateNotification decorateHeader decorateTabs decorateTab decorateTerms decorateTermGroup decorateSplitPane decorateTerm
|
Renderer |
Wywołany za pomocą Parametry:
|
Ładowanie modułów
Użytkownik może wczytywać i ładować na gorąco wtyczki, naciskając Command + R (odśwież). Proszę starać się tworzyć wtyczki, które nie wymagają całkowitego restartu aplikacji, aby działały.
Uwaga
Wtyczki wpływające na `BrowserWindow` będą miały wpływ na nowe okna po hot-reload.
W przyszłości możemy to robić automatycznie.
Podczas tworzenia, możesz dodać swoją wtyczkę do .hyper_plugins/local
, a następnie określić ją pod tablicą localPlugins
w .hyper.js
. Nowe wtyczki ładujemy:
- Periodycznie (co kilka godzin)
- Gdy wprowadzane są zmiany w pliku konfiguracyjnym (
plugins
lublocalPlugins
) - Gdy użytkownik kliknie Plugins > Update all now
Proces przeładowywania obejmuje
- Uruchamianie
npm prune
inpm install
w.hyper_plugins
. - Uruchomienie
require.cache
zarówno w elektronie, jak i w procesie renderowania - Wywołanie metod
on*
na istniejących instancjach i ponowne wyrenderowanie komponentów ze świeżymi dekoracjami na miejscu.
Lokalizacja wtyczek
macOS | ~/Library/Application Support/Hyper/.hyper_plugins |
Windows | $Env:AppData/Hyper/.hyper_plugins |
Linux | ~/.config/Hyper/.hyper_plugins |
Uwaga: wtyczki w ~/.hyper_plugins
nadal obsługiwane, ale będą ignorowane, jeśli są obecne wtyczki w katalogu aplikacji. W przeciwnym razie zostaną one przeniesione do katalogu aplikacji przy pierwszym uruchomieniu.
Uwaga: na głównym procesie, wtyczki są rejestrowane tak szybko jak to możliwe (odpalamy onLoad
). W przeglądarce natomiast, to użytkownik musi wywołać ich załadowanie wciskając command+R. Oddajemy użytkownikowi kontrolę nad ładowaniem w ten sposób, aby zapobiec utracie krytycznej pracy przez rozszerzenia, które resetują stan lub nie zachowują go poprawnie.
Dekorowanie komponentów
Dajemy ci możliwość dostarczenia komponentu wyższego rzędu dla każdego elementu Hyper
UI.
Jego struktura jest następująca:
<Hyper> <Header> <Tabs> <Tab /> ... </Tabs> </Header> <Terms> <TermGroup> <SplitPane> <TermGroup> <Term /> ... </TermGroup> <TermGroup> <Term /> ... </TermGroup> </SplitPane> </TermGroup> </Terms> <Notifications> <Notification /> ... </Notifications></Hyper>
Wszystkie metody decorate*
otrzymują następujące referencje w obiekcie przekazywanym jako drugi parametr:
React |
Cała przestrzeń nazw React. |
notify |
Funkcja pomocnicza, która wyświetla powiadomienie na pulpicie. Pierwszy parametr to tytuł, drugi to opcjonalne ciało powiadomienia, a trzeci to kolejny opcjonalny parametr, który może być użyty do logowania szczegółów do konsoli deweloperskiej. Aby przekazać te szczegóły, wystarczy przekazać obiekt z właściwością |
Notification |
Komponent Notification na wypadek, gdybyś chciał go ponownie użyć. |
Wszystkie komponenty akceptują następujące dwie właściwości w celu rozszerzenia ich znaczników:
customChildren |
Tablica Element lub pojedynczaElement do wstawienia na dole komponentu. |
customChildrenBefore |
Taka sama jak powyższa właściwość, ale wstawiana jako pierwszy element(y) dziecka komponentu. |
Twój komponent wyższego rzędu może dostarczyć onDecorated
właściwość do dekorowanego komponentu, aby uzyskać odniesienie do jego instancji.
Twój komponent wyższego rzędu Term może dostarczyć właściwość onCursorMove
handler, która zostanie wywołana, gdy kursor zostanie przesunięty z parametrem obiektu reprezentującym jego względną pozycję względem początku Term:
x |
Pozycja pozioma w pikselach |
y |
Pozycja pionowa w pikselach |
width |
Szerokość kursora w pikselach |
height |
Wysokość kursora w pikselach |
col |
Pozycja pozioma w kolumnach |
row |
Pozycja pionowa w wierszach |
Zachęcamy do zachowania kompatybilności z innymi dekoratorami. Ponieważ wiele z nich może być ustawionych, nie zakładaj, że twój jest jedyny.
Na przykład, jeśli przekazujesz dzieci, skompiluj potencjalne istniejące wartości:
render () { const customChildren = Array.from(this.props.customChildren) .concat(<p>My new child</p>); return <Tab {...this.props} customChildren={customChildren} />}
Albo jeśli używasz onDecorated
właściwości
onDecorated (term) { this.term = term; if (this.props.onDecorated) { this.props.onDecorated(term); }}
Akcje i efekty
Wszystkie akcje Redux są dostępne dla ciebie do obsługi przez twoje middleware i reduktory. Aby uzyskać przykład, zapoznaj się z wtyczką referencyjną Hyperpower.
Efekty uboczne występują w dwóch podstawowych formach:
- Niektóre akcje wysyłają inne akcje na podstawie stanu.
- Niektóre akcje wykonują pracę asynchroniczną komunikując się przez kanał RPC do głównego procesu
We wszystkich przypadkach efekt uboczny jest przekazywany jako klucz effect
w akcji i później obsługiwany przez nasze oprogramowanie pośredniczące.
To oznacza, że możesz nadpisywać, komponować lub całkowicie wyeliminować efekty! Innymi słowy, w ten sposób możesz zmienić domyślną funkcjonalność lub zachowanie aplikacji.
Jako przykład, rozważ akcję, której używamy do zwiększenia rozmiaru czcionki po naciśnięciu klawisza 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 }); } }); };}
Podstawowy terminal
Hyper
osiąga wiele ze swojej szybkości i funkcjonalności dzięki mocy xterm.js
Dodatkowe API
Obiekty Electron app
są rozszerzone o następujące właściwości:
config |
An Object z blokiem config z .hyper.js . |
plugins |
An Object z helperami dla wtyczek. |
getWindows |
An Function , który zwraca Set wszystkich otwartych okien. |
createWindow |
An Function , który utworzy nowe okno. Akceptuje opcjonalny callback , który zostanie przekazany jako init callback nowego okna. |
Obiekty Electron BrowserWindow
są rozszerzane o następujące parametry:
rpc |
An EventEmitter , który umożliwia komunikację z procesem okna. |
sessions |
A Map obiektów Session , które utrzymują komunikację z każdym termem pty.. |
Okna renderera są podobnie rozbudowane o:
rpc |
Obiekt EventEmitter , który pozwala na komunikację z procesem okna. |
store |
Obiekt Redux Store . Umożliwia dostęp do dispatch akcji lub odczyt stanu globalnego za pomocą getState . |
Obiekt rpc
jest symetryczny pomiędzy przeglądarką a procesem renderującym. API jest takie samo jak Node.js, z wyjątkiem tego, że dopuszcza tylko pojedynczy obiekt jako swoje parametry tylko:
window.rpc.emit('hi there', { some: 'payload', any: });
Przykładowy motyw: Hyperyellow
Następujące rozszerzenie po prostu zmienia konfigurację, aby dodać CSS i żółte kolory! Oto kod.
Tematy są po prostu wtyczkami! Potrzebny jest tylko jeden hak, decorateConfig
:
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; } ` });}
Złapałem nazwy klas poprzez inspekcję term za pomocą Devtools, które możesz uruchomić z View -> Toggle Developer Tools
. Kiedy to zrobisz, zauważ, że niektóre klasy są generowane automatycznie, a po nich następuje losowy nonce (np.: term_13hv8io
). Zignoruj je: zmieniają się z każdym nowym oknem!
Zauważ, że kładziemy nacisk na miłą współpracę z innymi rozszerzeniami. Konkretnie, tworzymy nowy obiekt, rozszerzamy tylko te klucze, które nas interesują, i komponujemy CSS tak, aby zachować ustawienia użytkownika i innych autorów:
return Object.assign({}, config, { css: ` ${config.css || ''} /* your css here */ `});
Przykładowe rozszerzenie: Hyperpower
Następujące rozszerzenie renderuje cząsteczki w miarę przesuwania się careta:
Przejdźmy przez jego kod.
Na początku przechwytujemy akcję Redux SESSION_ADD_DATA
. Pełną listę akcji można znaleźć w repozytorium.
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); }};
Zauważ, że nie wysyłamy akcji ponownie, co oznacza, że nigdy nie renderujemy wyjścia polecenia do terminala. Zamiast tego, wysyłamy własną akcję, którą łapiemy w uiReducer
i później mapujemy:
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 });};
Potem chcemy udekorować komponent <Term>
tak, abyśmy mieli dostęp do bazowego careta.
Jednakże, <Term>
nie jest kontenerem, do którego możemy mapować rekwizyty. Używamy więc getTermProps
, aby przekazać właściwość dalej:
exports.getTermProps = (uid, parentProps, props) => { return Object.assign(props, { wowMode: parentProps.wowMode });}
Rozszerzenie zwraca następnie komponent wyższego rzędu, aby zawinąć <Term>
. Zauważ, że przekazujemy właściwość onDecorated
, aby uzyskać dostęp do bazowego komponentu Term i jego DOM ref, oraz właściwość onCursorMove
, aby użyć Hyper cursor API:
render () { return React.createElement(Term, Object.assign({}, this.props, { onDecorated: this._onDecorated, onCursorMove: this._onCursorMove }));}
.