Obsah
1. Evil: kombinace editačních příkazů Vimu a síly Emacsu
2. Proč by měl být Emacs zajímavý i pro Vimaře?
3. Emacs není jediný editor s emulací Vimu
4. Instalace balíčku Evil do Emacsu
5. Povolení režimu Evil, přepínání režimů Emacs/Vim
7. Práce s registry (registers)
10. Další přizpůsobení Emacsu pro skalní Vimaře
11. Modifikace funkce klávesy Y
13. Instalace a konfigurace balíčku evil-numbers
14. Ostatní užitečná nastavení
19. Obsah navazujícího článku – projekt Spacemacs
1. Evil: kombinace editačních příkazů Vimu a síly Emacsu
V dnešním článku se seznámíme s pluginem určeným pro slavný textový editor Emacs. Tento plugin se jmenuje Evil a umožňuje ovládat Emacs pomocí klávesových zkratek emulujících (a to velmi důkladně) další slavný textový editor Vim. Díky tomuto pluginu je tak umožněna synergie schopností Vimu s univerzálností Emacsu. Se samotným Emacsem jsme se na Rootu již setkali, a to dokonce několikrát. Především vyšly dva seriály [1] [2] věnované použití Emacsu, poměrně podrobně jsme si popsali i historii vzniku tohoto textového editoru a taktéž jsme si ukázali schopnosti Emacsu při ladění nativních aplikací (samotné ladění je prováděno GNU Debuggerem, Emacs zde slouží především jako inteligentní front end). Prozatím poslední článek se věnoval režimu interaktivního porovnávání souborů.
Obrázek 1: Spuštění textového editoru Emacs se zobrazením hypertextového souboru s nápovědou.
I přesto, že v současnosti existuje poměrně velké množství programátorských textových editorů postavených na moderních technologiích (jmenujme například Atom, Sublime Text 2, Light Table či projekt Kakoune), stále mnoho uživatelů – ať již se jedná o programátory, administrátory, testery atd. – používá dnes již klasické editory Vim a Emacs. Ostatně není se čemu divit, protože jak ve Vimu, tak i v Emacsu lze s texty pracovat velmi efektivně a navíc je možné si mnohé úlohy plně zautomatizovat, například prostým opakováním příkazu, použitím uživatelských maker, mapováním kláves či dokonce vytvořením složitějších skriptů/pluginů.
Obrázek 2: GNU Emacs přepnutý do takzvaného ediff režimu.
Obrázek 3: Pokud vám grafické uživatelské rozhraní u textových editorů z nějakého důvodu nevyhovuje a dáváte přednost použití terminálu, je možné Emacs startovat s volbou -nw nebo –no-window-system. Pokud se Emacs spouští z textové konzole, samozřejmě se přepne do čistě textového rozhraní.
2. Proč by měl být Emacs zajímavý i pro Vimaře?
Pokud tento článek čte dlouholetý příznivce Vimu, asi si klade otázku, zda mu použití Emacsu skutečně může přinést nějaké výhody a jestli má smysl si Emacs + Evil vyzkoušet. Samozřejmě jsou požadavky uživatelů různé, ale vyzkoušení Evilu může být přínosné, zejména ve chvíli, kdy se použije ještě nějaký další plugin měnící Emacs v integrované vývojové prostředí (navíc je vždy vhodné znát možnosti „nepřítele“ :-). Vim je samozřejmě taktéž rozšiřitelný díky existenci Vim Scriptu, ovšem například integrace dynamicky typovaných jazyků je v Emacsu (podle mých zkušeností) lepší. Díky tomu, že je tento programátorský editor relativně snadno rozšiřitelný s využitím skriptů a modulů naprogramovaných v jazyce Lisp, přesněji řečeno v jeho dialektu nazvaném Emacs Lisp (též Elisp), existuje v současnosti poměrně velké množství propracovaných modulů, které z Emacsu vytváří sofistikované integrované vývojové prostředí (IDE), jež se navíc v případě potřeby dokáže přizpůsobit mnoha programovacím jazykům (překladačům, ale i interpretrům).
Obrázek 4: Porovnání tří variant zdrojového kódu v ediff režimu.
Textový editor Emacs je možné v závislosti na tom, jaký typ souboru je právě otevřený, přepínat mezi různými režimy, přičemž v každém režimu mohou být použity jiné klávesové zkratky, zobrazena odlišná okna (nejenom klasická okna s editovaným textem) apod. Příkladem může být režim ladění programů s využitím GNU Debuggeru. O propojení debuggeru s Emacsem se stará knihovna GUD neboli Grand Unified Debugger, s níž se můžete seznámit v článku Debuggery a jejich nadstavby v Linuxu (5): ladění aplikací v editorech Emacs a Vim. Zapomenout nesmíme ani na slavný Org-mode nabízející možnosti plánovače úloh, tvorbu strukturovaných dokumentů, přípravu programů schůzek, práci s tabulkami (v čistě textových dokumentech). Ostatně znám několik lidí (neprogramátorů), kteří přešli na Emacs právě kvůli existenci Org-mode.
Obrázek 5: Podpora ladění přímo z prostředí Emacsu – inicializace knihovny GUD a připojení Emacsu ke GNU Debuggeru.
3. Emacs není jediný editor s emulací Vimu
Ve skutečnosti není textový editor Emacs jedinou aplikací, pro kterou byl vytvořen plugin emulující možnosti Vimu. Například pro textový editor Atom existuje zásuvný modul pojmenovaný atom-vim-mode-plus. Na stránkách serveru mojefedora.cz [1] [2] jste se mohli se seznámit s projektem Vrapper přidávajícím klávesové zkratky Vimu do integrovaného vývojového prostředí Eclipse a emulace Vimu je dokonce dostupná o pro Libre Office díky pluginu vibreoffice (ten ovšem podporuje jen ty nejzákladnější příkazy, ze všech zmíněných pluginů je v nejhorším stavu).
Obrázek 6: Integrované vývojové prostředí Eclipse s nainstalovaným pluginem Vrapper.
4. Instalace balíčku Evil do Emacsu
Existuje několik způsobů instalace pluginu Evil (příslušný balíček se jmenuje jednouše evil). Nejjednodušší je instalace ve chvíli, kdy máte v Emacsu povolen repositář balíčků MELPA (ten obsahuje přibližně 3900 balíčků!). Po zadání příkazu:
M-x list-packages
je možné zjistit, jestli je MELPA povolena a zda je tedy balíček evil přímo k dispozici:
Obrázek 7: V případě, že repositář MELPA není povolen, budou dostupné pouze balíčky z výchozího repositáře ELPA (Emacs Lisp Package Archive).
Pokud balíček evil nebyl nalezen, je nutné MELPu povolit, například těmito řádky přidanými do souboru .emacs umístěného v domovském adresáři:
(require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
Po opětovném načtení editoru zkuste znovu zadat příkaz:
M-x list-packages
Tentokrát by se měl objevit mj. i balíček nazvaný evil (pozor na to, že prvotní načtení všech 3900 balíčků může chvíli trvat):
Obrázek 8: V případě, že je repositář MELPA povolen, měl by se v seznamu balíčků objevit i plugin evil.
Plugin evil nainstalujeme běžným způsobem:
Obrázek 9: Výběr pluginu evil pro instalaci.
5. Povolení režimu Evil, přepínání režimů Emacs/Vim
V případě, že budete chtít, aby Emacs implicitně pracovat v režimu emulace editoru Vim, přidejte si do souboru .emacs umístěného v domovském adresáři následující dvojici řádků:
(require 'evil) (evil-mode 1)
Přepínání mezi originálním ovládáním Emacsu a emulací Vimu se dá provést i dalšími způsoby. Například je možné použít klávesovou zkratku C-z (neboli Ctrl+Z), což ovšem nemusí fungovat v textové konzoli. Taktéž je možné zavolat příkaz evil-mode, a to následujícím způsobem:
M-x evil-mode
Tento příkaz přepíná mezi původním režimem Emacsu a Vimem popř. i opačným směrem. Ovšem pokud se editor nachází v režimu emulace Vimu, můžeme namísto hledání Alt+X použít i „vimovský způsob“:
:evil-mode
Obrázek 10: Přepnutí do režimu Evil zadáním příkazu M-x evil-mode.
6. Základní editační příkazy
Obrázek 11: Režimy Vimu a způsob přechodu mezi nimi.
Ihned po povolení režimu evil (evil mode) se textový editor Emacs přepne do normálního stavu (normal state), tj. je možné zadávat prakticky všechny editační příkazy, které znáte z Vimu (emulace je skutečně na velmi dobré úrovni). Podporovány jsou samozřejmě i všechny operátory Vimu, dokonce včetně ROT13:
Operátor | Význam | Stručný popis |
---|---|---|
c | change | změna textu (delete a následný přechod do vkládacího režimu) |
d | delete | vymazání textu |
y | yank | kopie textu do registru |
! | filter | filtrace přes externí příkaz |
> | shift right | posun textu doprava o shiftwidth |
< | shift left | posun textu doleva o shiftwidth |
g~ | swap case | změna malých písmen na velké a naopak |
gu | lowercase | změna na malá písmena (mínusky) |
gU | Uppercase | změna na velká písmena (verzálky) |
gq | format | zformátování textu |
g? | ROT13 | rotace ASCII znaků o 13 pozic dopředu (režim modulo) |
= | indent | změna zarovnání textu |
Pro přepnutí do stavu vkládání se používají běžné příkazy a, A, i, I, o, O, c, R (stav přepisu) atd. Aktuálně nastavený stav je zobrazen na stavovém řádku každého bufferu. Jedná se o zápis [N], [V], [I], [R] atd. Při zapnutí stavu psaní nového textu se navíc objeví zpráva „– INSERT –“, podobně jako v samotném Vimu.
Klávesová zkratka C-SPC (neboli Ctrl+Space), která v Emacsu slouží pro nastavení značky, dostala poněkud odlišný význam – zapíná režim vizuálního výběru bloku. Je to vlastně logické, protože typické editační operace v Emacsu probíhají mezi pozicí kurzoru a nastavenou značkou (tzv. region) a ve Vimu pro vizuálně vybraný blok (tj. mezi začátkem bloku a pozicí kurzoru).
7. Práce s registry (registers)
Užitečným a často používaným nástrojem nabízeným textovým editorem Vim i režimem Evil jsou takzvané registry. Jedná se o proměnné pojmenované jedním znakem, které v první řadě slouží pro kopii či přenos editovaných textů pomocí příkazů c (change), s (substitute), d (delete), y (yank) a p (paste), což vlastně znamená, že registry lze využít ve funkci pojmenovaných schránek (clipboard). Podobně jako v případě dále zmíněných značek, existují registry naplňované uživatelem a registry, jejichž obsah je měněn textovým editorem automaticky při provádění různých operací. Jména a význam některých důležitých registrů můžete najít v následující tabulce:
Registr | Význam |
---|---|
a-z | registry, které je možné přímo měnit uživatelem |
0 | použitý při příkazu yank (kopie textu) |
1–9 | registry naplňované automaticky příkazy d a c (delete, change) |
% | není ve výchozím nastavení přímo použit |
: | registr obsahující poslední příkaz, vhodné při vyvolání tohoto příkazu jako makra |
= | není ve výchozím nastavení přímo použit |
/ | registr obsahující posledně vyhledávaný řetězec (resp. text odpovídající regulárnímu výrazu) |
" | implicitní registr pro operace c, d, s nebo y |
– | implicitní registr pro operace, které mění menší část textu, než je jeden textový řádek |
Obrázek 12: Zobrazení registrů (registers, resp. přesněji řečeno evil-registers).
8. Použití značek (marks)
Další užitečnou věcí, kterou ve Vimu a samozřejmě i v Evilu najdeme, jsou takzvané značky (marks). Nejedná se však o značky vytvářené externími nástroji a ukládané většinou do souboru pojmenovaného tags, ale o interní seznam pozic kurzoru (jakési „špendlíky“ zapíchnuté do důležitých míst) v souboru, na které se lze během editace vrátit, nebo na něž se lze odkazovat. Podobnou funkcionalitu nabízí i mnohé další programátorské textové editory, ovšem u nich se většinou jedná o maximálně deset značek, zatímco ve Vimu může být značek mnohem více, protože každé značce je přiřazeno jednopísmenné označení.
Obrázek 13: Zobrazení značek (marks, resp. přesněji řečeno evil-marks).
V rámci jednoho souboru lze lokálně používat značky pojmenované malými písmeny a až z, zatímco značky pojmenované velkými písmeny A až Z si „pamatují“ i jméno souboru, v němž jsou definovány, tudíž se jedná o značky globální. Speciální význam mají značky se jmény 0 až 9 (naplňované většinou při ukončování Vimu) a taktéž v některých případech velmi užitečná značka ". Významy některých jmen značek (ve skutečnosti jich je ještě mnohem více) jsou vypsány v následující tabulce:
Jméno značky | Definice značky | Význam |
---|---|---|
a-z | manuálně | značky lokální v rámci souboru |
A-Z | manuálně | značky globální, ke značce je připojeno i jméno souboru |
" | automaticky | pozice kurzoru při zavření bloku |
^ | automaticky | pozice kurzoru, na níž se kurzor naposledy nacházel ve vkládacím režimu |
Práce se značkami je v mnoha ohledech velmi jednoduchá, ostatně všechny důležité příkazy najdete v následující tabulce:
Příkaz | Význam |
---|---|
:marks | výpis všech právě aktivních značek |
:marks značka | výpis vybrané značky |
ma – mz | definice lokální značky a-z |
mA – mZ | definice globální značky A-Z |
'a – 'z | skok na řádek, kde je značka definovaná (jedná se o příkaz pohybu kurzoru!) |
'A – 'Z | skok na soubor a řádek, kde je značka definovaná |
`a – `z | skok na přesné místo, kde je značka definovaná (jedná se o příkaz pohybu kurzoru!) |
'A – 'Z | skok na přesné místo (řádek i sloupec), kde je značka definovaná |
9. Uživatelská makra
Ve Vimu je možné definovat uživatelská makra, jejichž definice se uloží do zvoleného pracovního registru (definice makra obsahuje sekvenci stisknutých kláves, takže zde s výhodou využijeme především operátory zkombinované s příkazy pro pohyb v textu). Pro záznam makra se používá klávesová zkratka q[registr], například qa. Vim v tomto případě na stavový řádek vypíše slovo recording. V Emacsu je tomu nepatrně jinak, protože se namísto toho napíše zpráva:
Defining kbd macro...
Ukončení záznamu makra je provedeno pouze klávesou q. Ve Vimu se po zadání tohoto příkazu makro uloží do pracovního registru a slovo recording ze stavového řádku zmizí. Emacs (samozřejmě přepnutý do režimu evil) pracuje podobně, pouze navíc na stavový řádek vypíše zprávu:
Keyboard macro defined
Uživatelská makra lze přeložit do maker běžných v Emacsu. Postup je následující:
Makro vytvoříme běžným způsobem, tj. například qagU3wq pro převod tří slov na velká písmena. Následně zadáme příkaz:
:name-last-kbd-macro
a doplníme vhodné jméno makra, například „upcase3words“.
V posledním kroku si můžeme makro vypsat popř. vložit do souborů init.el či .emacs:
:insert-kbd-macro
Měl by se vypsat tento text:
(fset 'upcase3words "gU3w")
10. Další přizpůsobení Emacsu pro skalní Vimaře
Výchozí konfigurace používaná balíčkem Evil samozřejmě nemusí vyhovovat všem uživatelům. V navazujících kapitolách se zmíním o některých nastaveních, která osobně považuji za užitečná, i když se chování Evil-u bude odlišovat od standardního chování Vimu (přesněji řečeno od chování Vimu s nastavením nocompatible, tj. Vimu ve chvíli, kdy se nesnaží být zpětně kompatibilní s textovým editorem Vi). Podobná nastavení mám ovšem provedena i v klasickém Vimu, takže se oba textové editory budou z tohoto pohledu chovat velmi podobným způsobem.
11. Modifikace funkce klávesy Y
První nastavení se týká příkazu Y. Standardní chování tohoto příkazu totiž znamená: vlož celý řádek (popř. větší množství řádků při zadání čísla) do nějakého registru (při nezadání registru se použije registr pojmenovaný "). To ovšem logicky koliduje s dalšími operátory, zejména Change a Delete. Tyto operátory totiž existují v kombinacích umožňujících jejich aplikaci buď na celý řádek (více řádků) nebo od pozice kurzoru do konce řádku:
Operace | Operátor | Celý řádek | Do konce řádku |
---|---|---|---|
Změna | c | cc | C |
Smazání | d | dd | D |
Kopie | y | yy/Y |
Logičtější by bylo následující chování:
Operace | Operátor | Celý řádek | Do konce řádku |
---|---|---|---|
Změna | c | cc | C |
Smazání | d | dd | D |
Kopie | y | yy | Y |
Ve skutečnosti lze takového chování dosáhnout snadno, a to následujícím příkazem, který si můžeme přidat do souboru .emacs:
(setq evil-want-Y-yank-to-eol t)
12. Balíček evil-numbers
Jednou z užitečných vlastností textového editoru Vim je možnost používat (v normálním režimu) klávesové zkratky Ctrl+A a Ctrl+X pro zvýšení popř. pro snížení číselné hodnoty, která je zapsána na pozici kurzoru nebo kdekoli ZA pozicí kurzoru. Chování těchto klávesových zkratek je intuitivní a může se hodit například při tvorbě různých tabulek, seznamů apod.:
- Po stisku Ctrl+A nebo Ctrl+X Vim zjistí, kde se (napravo od kurzoru) nachází číselná hodnota.
- Následně se detekuje typ hodnoty (decimální číslo bez prefixu, hexadecimální číslo s prefixem 0×, osmičková hodnota s prefixem 0).
- Tato hodnota se zvýší nebo sníží o jedničku. Popř. pokud je před klávesovou zkratkou Ctrl+A nebo Ctrl+X použit počet opakování, bude se přičítat nebo odečítat uživatelem zadaná hodnota větší než 1.
Toto chování je samozřejmě možné doprogramovat i do Emacsu; popř. je možné použít vhodný balíček, který toto naprogramování již obsahuje. Tento balíček skutečně existuje a jmenuje se evil-numbers.
13. Instalace a konfigurace balíčku evil-numbers
Balíček evil-numbers se instaluje zcela totožným způsobem jako jakýkoli jiný balíček:
Obrázek 14: Správce balíčků MELPA již máme povolen, takže po zadání příkazu M-x list-packages uvidíme i balíček evil-numbers.
Po instalaci balíčku evil-numbers se zdánlivě nic nezměnilo, protože je nutné provést alespoň minimální konfiguraci. Ta spočívá v načtení balíčku, ideálně při startu Emacsu a dále v namapování funkcí evil-numbers/inc-at-pt a evil-numbers/dec-at-pt na vhodné klávesové zkratky. V mém případě je provedeno nastavení odpovídající Vimu, tj. namapování kláves Ctrl+A a Ctrl+X v normálním režimu na obě zmíněné funkce:
(define-key evil-normal-state-map (kbd "C-a") 'evil-numbers/inc-at-pt) (define-key evil-normal-state-map (kbd "C-x") 'evil-numbers/dec-at-pt)
Obrázek 15: Nastavení si můžete jednoduše vyzkoušet ve scratch bufferu (viz klávesové zkratky, které naleznete v menu Lisp-Interaction).
Samozřejmě je možné klávesové zkratky uchovat i pro další spuštění Emacsu, například následujícími příkazy vloženými do souboru .emacs:
(require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) (require 'evil) (require 'evil-numbers) (evil-mode 1) (define-key evil-normal-state-map (kbd "C-a") 'evil-numbers/inc-at-pt) (define-key evil-normal-state-map (kbd "C-x") 'evil-numbers/dec-at-pt)
14. Ostatní užitečná nastavení
Mezi další užitečná nastavení, která je možné provést typicky při startu a inicializaci Emacsu, patří:
(setq evil-move-beyond-eol t)
Při tomto nastavení je možné v normálním stavu přesunout textový kurzor ZA poslední znak na řádku. To může být užitečné například pro ty uživatele, kterým vadí odlišné chování některých příkazů nebo maker na konci řádku (navíc se jedná o chování odpovídající klasickému Emacsu). Výchozího chování odpovídajícího Vimu dosáhnete příkazem:
(setq evil-move-beyond-eol nil)
Nastavení:
(setq evil-backspace-join-lines t)
umožňuje, aby například klávesová zkratka C-w (Ctrl+W) ve stavu zápisu textu dokázala mazat slova i na předchozích řádcích. Toto chování (které vlastně vůbec nesouvisí s klávesou Backspace) vypnete opačným nastavením:
(setq evil-backspace-join-lines nil)
Další nastavení se týká příkazů f a t sloužících pro vyhledávání znaku a skok na tento znak. Je možné přepínat mezi vyhledáváním na jediném řádku, což odpovídá Vimu:
(setq evil-cross-line nil)
A vyhledáváním kdekoli (to ovšem může mít vliv na některá makra):
(setq evil-cross-line t)
Konečně poslední užitečná konfigurační volba:
(setq evil-symbol-word-search t) (setq evil-symbol-word-search nil)
se používá pro přepínání mezi režimem vyhledávání slov nebo celých identifikátorů pomocí příkazů * a #, což má vliv především ve chvíli, kdy se pracuje se zdrojovými kódy. Podívejme se, jaký vliv má tato volba na vyhledávání:
Obrázek 16: Za identifikátor je nyní považován text s pomlčkami popř. dalšími speciálními znaky.
Obrázek 17: Za identifikátor je nyní považováno jen jedno slovo.
15. Mapování kláves ve Vimu
Jeden z poměrně velkých rozdílů mezi klasickým Vimem a kombinací Emacs+Evil spočívá v odlišném přístupu k mapování kláves. Připomeňme si, že ve Vimu je možné použít například následující příkazy, které do tohoto editoru přidají další klávesové zkratky:
<i>" uložení souboru při stisku klávesy F2</i> <i>" (ukončující entita <cr> zajišťuje automatické spuštění</i> <i>" příkazu bez nutnosti stlačovat Enter)</i> :map <F2> :w<cr> " zavolání externího příkazu make při stisku klávesy F9 :map <F9> :!make<cr> " kompilace právě editovaného souboru při stisku klávesy F7 :map <F7> :!gcc -c %<cr> " posun jednoho řádku doleva či doprava pomocí " klávesových zkratek Tab a Shift+Tab :map <Tab> >> :map <S-Tab> <<
Kromě vytváření nových příkazů je možné měnit i příkazy již existující. Například lze zjednodušit posun kurzoru nahoru a dolů v dlouhém textovém řádku (rozděleném na obrazovce na více řádků volbou :set wrap) pomocí těchto mapování:
:map k gk :map j gj
Předchozí mapování klávesových zkratek pracovalo v normálním režimu (resp. stavu v Emacsu), ovšem v případě potřeby je možné přiřazovat význam klávesám v režimu vkládacím příkazem :imap:
" pohyb kurzoru ve vkládacím režimu " na začátek a konec řádku :imap <C-A> <C-O>g0 :imap <C-E> <C-O>g$ " nové příkazy určené pro " mazání znaků ve vkládacím režimu :imap <C-Y> <C-O>dd :imap <C-Q> <C-O>D :imap <C-T> <C-O>dw :imap <C-G> <Del>
Podobným příkazem :vmap je možné vytvářet nové klávesové zkratky pro vizuální režim, tj. pro režim, v němž se vybírá textová oblast:
" posun vybraných řádků doleva či doprava pomocí " klávesových zkratek Tab a Shift+Tab " s obnovením výběru (výběr se tedy nezruší!) :vmap <Tab> >gv :vmap <S-Tab> <gv
16. Mapování kláves v Emacsu
V Emacsu se namísto různých variant příkazu :map používá LISpovská funkce nazvaná define-key. Nápovědu k této funkci získáme snadno:
C-h f define-key
define-key is a built-in function in ‘C source code’. (define-key KEYMAP KEY DEF) In KEYMAP, define key sequence KEY as DEF. KEYMAP is a keymap. KEY is a string or a vector of symbols and characters, representing a sequence of keystrokes and events. Non-ASCII characters with codes above 127 (such as ISO Latin-1) can be represented by vectors. Two types of vector have special meanings: [remap COMMAND] remaps any key binding for COMMAND. [t] creates a default definition, which applies to any event with no other definition in KEYMAP.
Důležitý je hned první parametr MAP, který (velmi zjednodušeně řečeno) určuje tabulku s převody klávesa:akce-provedená-editorem. Ve chvíli, kdy je aktivní režim Evil, se používají tyto tabulky:
Tabulka/mapa | Význam |
---|---|
evil-normal-state-map | klávesy funkční v normálním stavu (výchozí stav Vimu i Evilu) |
evil-window-map | klávesy funkční po stisku C-w |
evil-motion-state-map | všechny posuny kurzoru, včetně počitadla posunů (3w apod.) |
evil-outer-text-objects-map | výběr textového objektu (slovo, věta, odstavec, blok) |
evil-visual-state-map | stav vizuálního výběru bloku |
evil-operator-state-map | stav, ve kterém již byla vybrána operace (c, d, y) a čeká se na zápis operátoru |
evil-insert-state-map | stav zápisu textu (ve Vimu klasický insert mode) |
evil-replace-state-ma | stav přepisu textu (ve Vimu klasický replace mode) |
Podívejme se nyní na jednoduchý příklad. Budeme chtít, aby se po stisku velkého Z prohodily dva sousední znaky v textu (na levém znaku je kurzor). Ve Vimu to je snadné:
:map Z xp
V Emacsu můžeme pro zhruba stejnou operaci zavolat funkci transpose-chars, takže mapování vytvoříme takto:
(define-key evil-normal-state-map "Z" 'transpose-chars)
Oba dva příkazy (Vimovský i Evilovský) budou funkční v normálním stavu.
Obrázek 18: Namapování funkce transpose-chars na klávesu Z.
V některých situacích se však může hodit použít i „vimovský přístup“, v němž je nějaká klávesa (například ono velké Z) mapována na sekvenci znaků zapisovaných na klávesnici (v našem případě xp). V Emacsu samozřejmě prakticky nic není nemožné :-), takže je v tomto případě možné použít zápis:
(define-key evil-normal-state-map "Z" (kbd "xp"))
Obrázek 19: Namapování sekvence znaků „xp“ na klávesu Y.
Používáme zde funkci kbd:
kbd is a compiled Lisp function in ‘subr.el’. (kbd KEYS) Convert KEYS to the internal Emacs key representation. KEYS should be a string in the format returned by commands such as ‘C-h k’ (‘describe-key’). This is the same format used for saving keyboard macros (see ‘edmacro-mode’).
17. Evil a Elisp
V předchozí kapitole jsme se již nepatrně dotkli jedné z nejdůležitějších technologií Emacsu. Jedná se o dialekt programovacího jazyka LISP, který je skutečně s Emacsem takřka neoddělitelně spojen, a to mj. i proto, že dnes pravděpodobně nejrozšířenější varianta Emacsu – GNU Emacs – je z velké části naprogramována v Emacs LISPu (Elispu). Volba LISPu vlastně není ani příliš překvapivá, protože se jednalo o programovací jazyk, který byl v polovině sedmdesátých let minulého století v AI Labu (kde první varianty Emacsu – což byla původně makra nad editorem TECO – vznikaly) poměrně intenzivně používán; později se dokonce někteří lidé z AI Labu podíleli i na konstrukci počítačů s LISPem. Jednalo se o takzvané Lisp Machines vyráběné například společností Symbolics, LMI Lambda či Xerox.
Obrázek 20: ZMACS je pokračovatelem editoru ZWEI naprogramovaného v LISPu (autor screenshotu: Phil.grenet).
Dnes se ještě (alespoň prozatím) nebudeme zabývat konkrétními možnostmi nabízenými Emacs LISPem, ovšem ukážeme si některé základní funkce, způsob vytváření uživatelských funkcí, jejich spouštění atd. Prakticky všechny operace budou prováděny v bufferu *scratch*, který má tři pro nás užitečné vlastnosti:
- Je automaticky otevřen po spuštění Emacsu (pokud si neprovedete úpravu konfigurace).
- Dovoluje zapisované funkce přímo spouštět (opět lze přenastavit, ale spouštění/vyhodnocování LISPovských funkcí je výchozí chování, protože buffer používá režim lisp-interaction-mode).
- Navíc pokud něco pokazíme, tak se obsah tohoto bufferu při ukončení Emacsu ztratí, takže Emacs gentlemansky přejde všechny možné chyby.
Obrázek 21: Čtení na dlouhé zimní večery aneb dokumentace k Emacs LISPu.
V jedenácté kapitole jsme si řekli, jakým způsobem je možné modifikovat funkci klávesy Y. Tato kapitola byla poměrně podrobná, což není náhoda, protože se nyní pokusíme funkci klávesy Y sami doprogramovat. Nebude se v žádném případě jednat o zcela korektní chování, ovšem seznámíme se s koncepcí značek (mark), kill-ringu, pojmu aktivního bodu (point) a taktéž s vlastním zápisem funkcí v Emacs LISPu.
Nejprve si vyzkoušejme jednodušší příklad – vytvoření příkazu pro smazání textu do konce řádku, což je typicky provedeno klávesovou zkratkou D. Očekávané chování klávesy D by mělo být „smaž text od pozice kurzoru do konce řádku a vlož tento text do registru“. Podobná funkce již v Emacsu ve skutečnosti existuje a jmenuje se kill-line (nenechte se zmást jejím jménem, skutečně maže text od pozice kurzoru); standardně je namapována na klávesovou zkratku C-k. Můžeme tedy klávese D tuto funkci přiřadit, a to následujícím způsobem:
(define-key evil-normal-state-map "D" 'kill-line)
Ovšem můžeme si zvolit i složitější způsob. Smazání textu do konce řádku (s uložením textu do kill ringu) lze v Emacsu provést i takto:
C-SPC C-e C-w
Což znamená postupné provedení těchto operací:
- Vložení značky (mark) na pozici kurzoru.
- Skok kurzorem na konec řádku.
- Smazání textu mezi značkou a kurzorem s jeho vložením do kill ringu.
Všechny tři výše zmíněné kroky jsou implementovány v odpovídajících (interaktivních) funkcích nazvaných set-mark-command, move-end-of-line a kill-region, takže je možné vytvořit funkci navázanou na klávesovou zkratku, v níž se postupně všechny tři uvedené funkce budou volat.
18. Využití funkcí evil-*
Ve skutečnosti však bude chování odlišné od klávesové zkratky D, a to z toho důvodu, že v režimu Evil se smazaný text ukládá do bufferů. Podobně tomu bude v případě pokusu o definici funkce namapované na klávesu Y. Můžeme zde ovšem využít ještě jednu možnost – zavolat funkce naprogramované v Emacs LISPu, které pro nás připravili tvůrci modulu Evil. Konkrétně se bude jednat o funkci evil-yank:
Obrázek 22: Nápověda k funkci evil-yank.
Z nápovědy je možné vyčíst, že tato funkce vyžaduje minimálně dva parametry udávající začátek a konec textu, který se má uložit do registru. Začátek textu je jednoduchý – zavoláme funkci point vracející aktuální souřadnice kurzoru:
Obrázek 23: Nápověda k funkci point vracející aktuální souřadnice kurzoru.
Konec oblasti ukládané do registru leží na konci řádku, takže (po delším hledání) můžeme zjistit, že lze použít funkci nazvanou line-end-position, která se v nejjednodušším případě volá bez parametrů:
Obrázek 24: Nápověda k funkci line-end-position vracející souřadnici na konci textového řádku.
Celý příkaz namapovaný na klávesu Y bude vypadat následovně:
Obrázek 25: Výsledný tvar příkazu namapovaného na klávesu Y.
Proč musí tato funkce/příkaz vypadat tak, jak je zapsána (včetně interactive) si řekneme příště.
19. Obsah navazujícího článku – projekt Spacemacs
V dalším článku na podobné téma si nejdříve popíšeme další moduly používané společně s modulem evil. Jedná se například o pluginy umožňující komentování označeného bloku kódu, plugin nahrazující Vimovský modul Surround atd. Ve druhé části dalšího článku si představíme projekt Spacemacs, který je z velké části naprogramovaný právě v Emacs Lispu a ukazuje možnosti tohoto jazyka a samozřejmě i „enginu“, nad kterým je tento jazyk postaven.
Obrázek 26: Logo projektu Spacemacs.
20. Odkazy na Internetu
- Evil (Emacs Wiki)
https://www.emacswiki.org/emacs/Evil - Evil (na GitHubu)
https://github.com/emacs-evil/evil - Evil (na stránkách repositáře MELPA)
https://melpa.org/#/evil - Evil Mode: How I Switched From VIM to Emacs
https://blog.jakuba.net/2014/06/23/evil-mode-how-to-switch-from-vim-to-emacs.html - GNU Emacs (home page)
https://www.gnu.org/software/emacs/ - GNU Emacs (texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?GnuEmacs - An Introduction To Using GDB Under Emacs
http://tedlab.mit.edu/~dr/gdbintro.html - An Introduction to Programming in Emacs Lisp
https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html - 27.6 Running Debuggers Under Emacs
https://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html - GdbMode
http://www.emacswiki.org/emacs/GdbMode - Emacs (Wikipedia)
https://en.wikipedia.org/wiki/Emacs - Emacs timeline
http://www.jwz.org/doc/emacs-timeline.html - Emacs Text Editors Family
http://texteditors.org/cgi-bin/wiki.pl?EmacsFamily - Vrapper aneb spojení možností Vimu a Eclipse
https://mojefedora.cz/vrapper-aneb-spojeni-moznosti-vimu-a-eclipse/ - Vrapper aneb spojení možností Vimu a Eclipse (část 2: vyhledávání a nahrazování textu)
https://mojefedora.cz/vrapper-aneb-spojeni-moznosti-vimu-a-eclipse-cast-2-vyhledavani-a-nahrazovani-textu/ - Emacs/Evil-mode – A basic reference to using evil mode in Emacs
http://www.aakarshnair.com/posts/emacs-evil-mode-cheatsheet - From Vim to Emacs+Evil chaotic migration guide
https://juanjoalvarez.net/es/detail/2014/sep/19/vim-emacsevil-chaotic-migration-guide/ - Introduction to evil-mode {video)
https://www.youtube.com/watch?v=PeVQwYUxYEg - EINE (Emacs Wiki)
http://www.emacswiki.org/emacs/EINE - EINE (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?EINE - ZWEI (Emacs Wiki)
http://www.emacswiki.org/emacs/ZWEI - ZWEI (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?ZWEI - Zmacs (Wikipedia)
https://en.wikipedia.org/wiki/Zmacs - Zmacs (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?Zmacs - TecoEmacs (Emacs Wiki)
http://www.emacswiki.org/emacs/TecoEmacs - Micro Emacs
http://www.emacswiki.org/emacs/MicroEmacs - Micro Emacs (Wikipedia)
https://en.wikipedia.org/wiki/MicroEMACS - EmacsHistory
http://www.emacswiki.org/emacs/EmacsHistory - Seznam editorů s ovládáním podobným Emacsu či kompatibilních s příkazy Emacsu
http://www.finseth.com/emacs.html - evil-numbers
https://github.com/cofi/evil-numbers - Debuggery a jejich nadstavby v Linuxu (1.část)
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/ - Debuggery a jejich nadstavby v Linuxu (2.část)
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/ - Debuggery a jejich nadstavby v Linuxu (3): Nemiver
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/ - Debuggery a jejich nadstavby v Linuxu (4): KDbg
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/ - Debuggery a jejich nadstavby v Linuxu (5): ladění aplikací v editorech Emacs a Vim
https://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-5-ladeni-aplikaci-v-editorech-emacs-a-vim/ - Org mode
https://orgmode.org/ - The Org Manual
https://orgmode.org/manual/index.html - Kakoune (modální textový editor)
http://kakoune.org/ - Vim-style keybinding in Emacs/Evil-mode
https://gist.github.com/troyp/6b4c9e1c8670200c04c16036805773d8 - Emacs – jak začít
http://www.abclinuxu.cz/clanky/navody/emacs-jak-zacit - Programovací jazyk LISP a LISP machines
https://www.root.cz/clanky/programovaci-jazyk-lisp-a-lisp-machines/ - Evil-surround
https://github.com/emacs-evil/evil-surround - Spacemacs
http://spacemacs.org/