Úpravy Emacsu s Emacs Lisp: manipulace se základními datovými strukturami Emacsu

27. 9. 2018
Doba čtení: 22 minut

Sdílet

V dnešním článku se již konečně dozvíme, jakými způsoby je možné ve skriptech naprogramovaných v Emacs Lispu pracovat s buffery i s dalšími důležitými interními strukturami samotného Emacsu.

Obsah

1. Základní komunikace mezi Emacsem a Emacs Lispem

2. Základní interní datová struktura Emacsu: buffer

3. Aktuální pozice kurzoru – point

4. Zmenšení dostupné oblasti bufferu, návrat zpět na původní rozsah

5. Značka v bufferu – mark

6. Základní funkce pro pohyb kurzoru v bufferu

7. Ukázka použití funkce goto-char

8. Přesun kurzoru po obrazových řádcích, podpora pro pohyb v programovém kódu

9. Vymazání specifikované oblasti bufferu

10. Interaktivní funkce

11. Vymazání zadaného počtu textových řádků z bufferu

12. Vymazání regionu mezi značkou a textovým kurzorem

13. Modifikace obsahu bufferu – zápis řetězců

14. Zápis opakujících se znaků do bufferu

15. Nepatrně složitější příklad – vykreslení pyramidy

16. Čtení znaků před a za aktuální pozicí kurzoru

17. Repositář s demonstračními příklady

18. Literatura

19. Odkazy na Internetu

1. Základní komunikace mezi Emacsem a Emacs Lispem

Mezi základní datové struktury, k nimž je možné přistupovat z Emacs Lispu, patří především buffery reprezentující editovaný soubor. Ke každému bufferu je přiřazen textový kurzor (point) se specifikovanou souřadnicí, značka (mark) zadaná uživatelem a popř. i tzv. mark ring, v němž se uchovávají pozice již zapsaných značek. Kromě bufferů se setkáme i se strukturami typu window. Tyto struktury představují pohled na buffer. Jednotlivá okna jsou vkládána do rámců (frame), s nimiž je možné taktéž manipulovat ve skriptech. Kromě toho se setkáme i s dalšími strukturami, například s mapami kláves atd. Dnes si popíšeme především funkce související s buffery, textovým kurzorem a značkou.

Na začátku si připomeňme několik základních a užitečných operací, které dnes budeme používat:

  1. Nápovědu k jakékoli funkci získáte pomocí C-h f jméno-funkce Enter
  2. Libovolnou funkci lze zavolat takto: M-: (volaná-funkce parametry) Enter
  3. Naproti tomu interaktivní funkce či příkaz se spustí: M-x volaný-příkaz Enter

2. Základní interní datová struktura Emacsu: buffer

V mnoha modulech se přistupuje přímo k nějakému bufferu, který představuje (velmi zjednodušeně řečeno) obraz otevřeného souboru. Některé funkce přímo vyžadují specifikaci bufferu, kterého se má nějaká operace týkat, ovšem mnoho funkcí očekává, že pokud buffer není zadaný, použije se ten právě aktivní. Získání aktivního bufferu je snadné, protože pro tento účel existuje funkce nazvaná current-buffer:

(current-buffer)
 
#<buffer *scratch*>
(current-buffer)
 
#<buffer *Help*>

3. Aktuální pozice kurzoru – point

První důležitou hodnotou, která je přiřazena ke každému bufferu, je aktuální pozice textového kurzoru v bufferu. Tento kurzor je v Emacsu označován jménem point a stejné pojmenování tedy nalezneme i v Emacs Lispu. Z pohledu uživatele je textový kurzor lokalizován dvojicí souřadnic: číslem řádku a číslem sloupce (neboli pozicí kurzoru na textovém řádku). Ovšem v Emacs Lispu je point představován jediným číslem, které – pokud máme být zcela přesní – neoznačuje přímo pozici nějakého znaku, ale místo ležící mezi dvěma znaky (proto také existují funkce jako following-char a preceding-char popsané níže). První možná pozice kurzoru má číslo (index) 1, poslední možná pozice pak odpovídá velikosti bufferu zvětšené o jedničku. Na začátku bufferu se jedná o místo před prvním znakem a na konci bufferu o místo ležící až za znakem posledním.

Mezi základní funkce pro zjišťování informací o kurzoru a o dalších relevantních údajích patří:

Funkce Stručný popis
point vrátí aktuální pozici kurzoru v bufferu
point-min minimální možná pozice kurzoru (typicky jedna)
point-max maximální souřadnice textového kurzoru
buffer-end začátek nebo konec bufferu (podle hodnoty parametru)
buffer-size velikost bufferu (ve znacích)

Zkusme si tyto funkce zavolat, ať již ze scratch bufferu, nebo přes klávesovou zkratku M-:

Získání aktuální pozice kurzoru:

(point)
9

Pokud se kurzor posune níže, dostaneme samozřejmě jinou hodnotu (zde používáme interaktivní vyhodnocení funkce přímo ve scratch bufferu):

 
;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with  and enter text in its buffer.
 
(point)
164

Při běžném nastavení bude hodnota vrácená funkcí point-min rovna jedné:

(point-min)
1

Hodnota vrácená funkcí point-max bude o jedničku vyšší, než velikost bufferu:

(point-max)
204
 
(buffer-size)
203

Funkce buffer-end vypíše index začátku bufferu nebo jeho konce:

(buffer-end 0)
1
 
(buffer-end 0)
159

4. Zmenšení dostupné oblasti bufferu, návrat zpět na původní rozsah

Některé funkce popsané v předchozí kapitole zdánlivě postrádají význam. Proč je například nutné mít funkci buffer-size a point-max, když dávají snadno odvoditelné výsledky (liší se jen o jedničku)? Ve skutečnosti jsou všechny tyto funkce užitečné, protože Emacs má ještě jednu zajímavou vlastnost – dokáže omezit editovatelnou oblast bufferu, čehož je možné využít v mnoha pluginech. S určením editovatelné oblasti souvisí dvě funkce:

Funkce Stručný popis
narrow-to-region nastavuje oblast, kterou je možné editovat
widen opak předchozí funkce: zpřístupní celý buffer

Můžeme si to snadno vyzkoušet:

(narrow-to-region 100 200)

Po zadání předchozího příkazu je zbytek bufferu skryt a zobrazeno zůstane pouze sto znaků mezi pozicemi 100 a 200. Tuto oblast lze libovolně editovat – zvětšovat ji (přidáním znaků), zmenšovat (smazáním znaků) atd.

Po spuštění funkce (či stejně pojmenovaného příkazu):

(widen)

se opět objeví zbytek textu, který byl před předchozími operaci chráněn.

5. Značka v bufferu – mark

V předchozích dvou kapitolách jsme se seznámili s textovým kurzorem (point), což je vlastně jedna souřadnice přiřazená ke každému bufferu. Druhou důležitou souřadnicí může být takzvaná značka (mark). Ta je typicky nastavována uživatelem pomocí klávesové zkratky C-space nebo C-@.

Poznámka: technicky se klávesovou zkratkou C-@ zadává ASCII kód NUL, tj. první znak v ASCII tabulce, protože znak @ má ASCII kód 64 a stiskem modifikátoru Ctrl snižujeme ASCII kód právě o hodnotu 64. To je také důvod, proč stisk C+I tak odpovídá znaku HT (Horizontal Tab), C+H znaku BS (Backspace) (existují ovšem metody, jak klávesy rozlišit), C+[ řídicímu znaku ESC, C+M konci řádku (CR) atd. Vše osvětlí pohled na ASCII tabulku.

Taktéž je možné použít příkaz C-X C-X pro prohození role značky a kurzoru (kurzor přeskočí na místo původní značky, zatímco značka je nastavena na místo, kde se kurzor nacházel). Značky je možné ukládat a tím pádem si je zapamatovat do datové struktury nazvané mark ring, která je přiřazena ke každému bufferu (mark ring se většinou chová jako běžný zásobník). Pro práci s mark ringem slouží klávesové zkratky C-space C-space (push) a C-u C-space (restore, pop).

Nás dnes budou zajímat především funkce volané z Emacs Lispu, které dokážou se značkou i s mark ringem pracovat:

Funkce Stručný popis
mark funkce vrátí pozici značky popř. nil, pokud není značka nastavena
set-mark nastavení značky (nemělo by se používat ve skriptech, manipulace se značkou by měla být jen interaktivní)
push-mark uložení značky do mark ringu, popř. lze specifikovat novou pozici značky
pop-mark opak předchozí funkce, obnovení značky z mark ringu

Funkcí ve skutečnosti existuje ještě více, ovšem většinou si vystačíme pouze se zjištěním pozice značky, a to ve chvíli, kdy skripty psané v Emacs Lispu mají pracovat s nějakou uživatelem označenou oblastí.

6. Základní funkce pro pohyb kurzoru v bufferu

Mezi další užitečné funkce dostupné skriptům napsaným v Emacs Lispu, patří funkce určené pro pohyb kurzoru (point) v bufferu. Kromě první funkce, která nastaví kurzor na určený index, pracují všechny ostatní funkce podobně jako uživatelské příkazy, tj. poskytují relativní pohyb kurzoru po znacích, slovech, řádcích atd.:

Funkce Stručný popis
goto-char přesun kurzoru na zadanou pozici (index v rámci bufferu)
   
forward-char přesun kurzoru dopředu o jeden znak (výchozí) či o zadaný počet znaků
backward-char přesun kurzoru vzad o jeden znak (výchozí) či o zadaný počet znaků
forward-word přesun kurzoru dopředu o jedno slovo (výchozí) či o zadaný počet slov
backward-word přesun kurzoru vzad o jedno slovo (výchozí) či o zadaný počet slov
beginning-of-line přesun kurzoru na začátek řádky (výchozí) popř. skok na předchozí řádky
end-of-line přesun kurzoru na konec řádky (výchozí) popř. skok na následující řádky
   
forward-line přesun kurzoru na předchozí řádek, pokud je zadáno číslo, jedná se o relativní přesun vpřed/vzad o N řádků
   
beginning-of-buffer přesun kurzoru na začátek bufferu
end-of-buffer přesun kurzoru na konec bufferu
Poznámka: termínem „řádek“ je myšlen logický řádek v textu. Logický řádek může být zobrazen na větším množství obrazových řádků, v závislosti na nastavení bufferu a šířce okna Emacsu.

7. Ukázka použití funkce goto-char

Na následující pětici screenshotů je ukázáno použití funkce goto-char, které se předává pozice kurzoru vypočtená funkcemi point-min a point-max, o nichž jsme se již zmínili ve třetí kapitole. Samozřejmě se jedná o umělý příklad, protože stejného efektu je možné dosáhnout funkcemi beginning-of-buffer a end-of-buffer:

Obrázek 1: Původní obsah bufferu s pozicí kurzoru.

Obrázek 2: Zadání příkazu pro přesun kurzoru na začátek bufferu.

Obrázek 3: Výsledek předchozího příkazu.

Obrázek 4: Zadání příkazu pro přesun kurzoru na konec bufferu.

Obrázek 5: Výsledek předchozího příkazu

8. Přesun kurzoru po obrazových řádcích, podpora pro pohyb v programovém kódu

Další skupina funkcí taktéž slouží pro přesuny kurzoru, ale nikoli po fyzických znacích nebo řádcích, ale po řádcích tak, jak jsou viditelné na obrazovce. Chování tedy bude odlišné ve chvíli, kdy jsou zobrazeny dlouhé zalomené řádky:

Funkce Stručný popis
vertical-motion relativní přesun o N obrazových řádků nahoru nebo dolů, na základě specifikovaného parametru
move-to-window-line přesun na specifikovaný obrazový řádek v zobrazeném oknu
count-screen-lines vrátí počet obrazových řádků popř. přepočítá obrazové řádky mezi dvěma pozicemi

Funkci vertical-motion se předává celé kladné či záporné číslo udávající, o kolik obrazových řádků se má kurzor posunout nahoru či dolů. Před vertikálním posunem je kurzor přesunut na první sloupec. Naproti tomu funkce move-to-window-line očekává zadání indexu řádku v právě zobrazeném oknu. Na rozdíl od pozice kurzoru či značky jsou tyto řádky číslovány od 0.

Obrázek 6: Pokud je obsah bufferu menší než počet obrazových řádků, vrátí se nižší číslo (počet skutečně obsazených obrazových řádků obsahem bufferu).

Další skupina funkcí je mnohem zajímavější a využijí je například uživatelé pracující se zdrojovými kódy naprogramovanými ve Scheme, Emacs Lispu nebo i v Clojure. Tyto funkce totiž dokážou rozpoznat a zpracovat rekurzivně vnořené seznamy:

Funkce Stručný popis
forward-list přesun kurzoru přes seznam (seznamy) směrem dopředu
backward-list přesun kurzoru přes seznam (seznamy) směrem dozadu
   
up-list přesun kurzoru směrem dopředu na takové místo, kde končí vnitřní seznam (seznamy), vyskočení z N-seznamů
down-list opak předchozí funkce, „vnoření“ do vnitřního seznamu (seznamů)
   
beginning-of-defun skok na začátek funkce (kurzor se předtím nachází uvnitř její definice)
end-of-defun skok na konec funkce
   
forward-sexp přeskok zadaného počtu S-výrazů
backward-sexp přeskok zadaného počtu S-výrazů

Obrázek 7: Kurzor před zavoláním funkce forward-list.

Obrázek 8: Kurzor po zavolání funkce forward-list.

Obrázek 9: Kurzor před zavoláním funkce up-list.

Obrázek 10: Kurzor po zavolání funkce up-list.

9. Vymazání specifikované oblasti bufferu

Konečně se dostáváme k funkcím určeným pro manipulaci s obsahem bufferu. Tyto funkce jsou samozřejmě velmi důležité, protože mnoho modulů napsaných pro Emacs nějakým způsobem s obsahem bufferů manipuluje (například formátuje zdrojový kód, provádí automatické doplnění názvů objektů atd.). První tři funkce souvisí s mazáním oblasti z bufferu. Tato oblast je specifikována dvojicí souřadnic od-do. Jedná se o tyto funkce:

Funkce Stručný popis
delete-region oblast mezi počáteční a koncovou souřadnicí je vymazána (implementováno jako nativní funkce)
kill-region oblast mezi počáteční a koncovou souřadnicí je vymazána a přesunuta do kill-ringu
copy-region-as-kill oblast mezi počáteční a koncovou souřadnicí je přesunuta do kill-ringu, ovšem bez vymazání
Poznámka: dejte si prosím pozor na skutečnost, že kill-region existuje jako funkce (je nutné ji předat dvojici souřadnic, tak jak je napsáno v předchozí tabulce) a současně i jako příkaz, kterému se automaticky předává pozice značky a kurzoru. Funkce se volá přes M-:, příkaz přes M-x:
(kill-region od do)

Podívejme se nyní na jednoduchou uživatelsky definovanou lispovskou funkci, která po svém zavolání smaže dva řádky. Nejprve se textový kurzor přesune na začátek aktuálního řádku. Dále se zapamatuje jeho nová pozice (do lokální proměnné p1), kurzor se přesune o dva řádky dopředu a konečně se zavolá funkce kill-region, které se předá původní pozice textového kurzoru i pozice nová:

(defun delete-two-lines
    ()
  (beginning-of-line)
  (let ((p1 (point)))
    (forward-line)
    (forward-line)
    (kill-region p1 (point))))
Poznámka: kromě výše použité funkce forward-line ještě existuje podobná funkce nazvaná next-line. Ta je ovšem určena především pro interaktivní použití, zatímco v lispovských programech by se měla používat právě funkce forward-line.

Obrázek 11: Zavolání funkce pro vymazání dvou řádků.

Obrázek 12: Výsledek aplikace funkce delete-two-lines.

Předchozí funkci si můžeme vylepšit tak, aby dokázala smazat libovolný počet textových řádků. Funkce tedy bude zavolaná s parametrem number a uvnitř jejího těla se bude volat forward-line ve smyčce představované formou dotimes, s níž jsme se již seznámili v úvodních částech tohoto seriálu:

(defun delete-n-lines
    (number)
  (beginning-of-line)
  (let ((p1 (point)))
    (dotimes (i number)
      (forward-line))
    (kill-region p1 (point))))

Obrázek 13: Zavolání funkce pro vymazání čtyř řádků.

Obrázek 14: Výsledek aplikace funkce delete-n-lines.

10. Interaktivní funkce

Samotné LISPovské funkce jsou skutečně základními stavebními bloky všech modulů naprogramovaných v Emacs Lispu. Ovšem pro jejich zavolání většinou potřebujeme ještě jednu maličkost – možnost vytvořit z funkce příkaz, který se zavolá buď přes klávesovou zkratku M-x jméno-příkazu nebo se namapuje na nějakou uživatelem zvolenou klávesovou zkratku. V Emacs Lispu je nutné toto chování funkcí vynutit uvedením speciální formy interactive. Typicky se této speciální formě předává řetězec, kterým je specifikováno, jakým způsobem se budou nyní již interaktivní funkci-příkazu předávat parametry. V řetězci může být dále obsažena otázka zobrazená uživateli. V tomto řetězci je možné definovat například:

# Znak předaný formě interactive Význam
1 a jméno funkce, podporuje automatické doplnění jména
2 b jméno existujícího bufferu, podporuje automatické doplnění jména
3 B jméno bufferu popř. nového bufferu, podporuje automatické doplnění jména
4 c jeden znak
5 C jméno příkazu, podporuje automatické doplnění jména
6 d pozice kurzoru (celé kladné číslo)
7 f jméno existujícího souboru
8 F jméno souboru, který nemusí existovat
9 k sekvence kláves
10 m index značky (mark)
11 M libovolný text načtený z minibufferu
12 n číslo přečtené z minibufferu
13 N číslo zadané nepřímo přes prefix
14 s řetězec
15 p prefix zadaný klávesou C-u
16 r dva parametry: pozice textového kurzoru a pozice značky; velmi užitečné, jak uvidíme dále

11. Vymazání zadaného počtu textových řádků z bufferu

Funkci delete-n-lines, s jejíž první verzí jsme se seznámili v deváté kapitole můžeme snadno změnit na interaktivní příkaz. Do funkce postačuje přidat řádek:

  (interactive "n")

Tímto řádkem oznamujeme, že funkci bude možné spustit interaktivně přes M-x delete-n-lines a současně se Emacs zeptá na počet řádek, které se mají vymazat:

(defun delete-n-lines
    (number)
  (interactive "n")
  (beginning-of-line)
  (let ((p1 (point)))
    (dotimes (i number)
      (forward-line))
    (kill-region p1 (point))))

Obrázek 15: Interaktivní varianta funkce delete-n-lines.

Ve funkci interactive je možné specifikovat i zprávu zobrazenou uživateli, což je samozřejmě mnohem lepší, než pouhý nicneříkající blikající kurzor v minibufferu:

(defun delete-n-lines
    (number)
  (interactive "nHow many lines? ")
  (beginning-of-line)
  (let ((p1 (point)))
    (dotimes (i number)
      (forward-line))
    (kill-region p1 (point))))

Obrázek 16: Dotaz na počet řádků, které se mají funkcí delete-n-lines smazat.

Další varianta této funkce akceptuje prefix zadaný klávesou C-u. Tato funkce se při svém spuštění již neptá na počet řádků a ve výchozím stavu (pokud není prefix zadán) se smaže jediný řádek:

(defun delete-n-lines
    (number)
  (interactive "p")
  (beginning-of-line)
  (let ((p1 (point)))
    (dotimes (i number)
      (forward-line))
    (kill-region p1 (point))))

12. Vymazání regionu mezi značkou a textovým kurzorem

Další interaktivní funkce bude velmi jednoduchá, protože bude sloužit k vymazání oblasti, která se nachází mezi zadanou značkou a textovým kurzorem. Povšimněte si, že se v deklaraci interactive používá znak „r“, který jako jediný zajistí předání dvou parametrů funkci – point a mark. Tyto dva údaje bez dalšího zpracování předáme do standardní funkce nazvané kill-region:

(defun delete-text
    (point mark)
  (interactive "r")
  (kill-region point mark))
Poznámka: asi jsme si povšimli, že je tato interaktivní funkce zbytečná, neboť se namísto ní dá přímo použít kill-region.

13. Modifikace obsahu bufferu – zápis řetězců

Nyní již víme, jakým způsobem je možné z bufferu vymazat určité znaky či celou oblast. Jedná se samozřejmě o užitečné funkce, ovšem mnohem častěji uživatelé od pluginů očekávají, že budou text automaticky přidávat :-) K tomu slouží zejména funkce insert. Jde o jednu ze základních funkcí implementovanou přímo v nativním kódu. Této funkci se předává pouze řetězec popř. znaky, které se mají do bufferu přidat, a to na pozici, na níž se nachází textový kurzor. Příkladem použití může být pomocná funkce, která do bufferu připíše oddělovací řádek obsahující pouze pomlčky:

(defun insert-hr
    ()
  (interactive)
  (beginning-of-line)
  (insert "---------------------")
  (insert "\n"))

Obrázek 17: Nápověda k funkci insert.

14. Zápis opakujících se znaků do bufferu

Kromě výše popsané funkce insert je užitečná i funkce nazvaná insert-char. Té lze předat znak (v Emacs Lispu s prefixem ?) a taktéž počet opakování znaku. Pokud tedy budeme chtít často do zdrojového kódu vkládat oddělovací řádek s osmdesáti hvězdičkami, lze to zařídit velmi jednoduše:

(defun insert-stars
    ()
  (interactive)
  (beginning-of-line)
  (insert-char ?* 80)
  (insert "\n"))

Popř. se uživatele můžeme zeptat, kolik hvězdiček ráčí ve svém textu mít :-)

(defun insert-stars
    (number)
  (interactive "n# of stars? ")
  (beginning-of-line)
  (insert-char ?* number)
  (insert "\n"))

Obrázek 18: Zdrojový kód před zavoláním funkce insert-stars.

Obrázek 19: Zdrojový kód po zavolání funkce insert-stars.

15. Nepatrně složitější příklad – vykreslení pyramidy

Poslední demonstrační příklad, který si dnes ukážeme, slouží k vykreslení pyramidy složené z hvězdiček. Uživatel pouze potřebuje zadat výšku pyramidy (v úsečkách). Povšimněte si, že si stále vystačíme pouze s několika funkcemi – pohyb kurzoru a vložení znaků popř. řetězce do aktivního bufferu:

(defun pyramid
    (number)
  (interactive "n# of lines? ")
  (beginning-of-line)
  (dotimes (i (+ 1 number))
    (insert-char ?\s (- number i))
    (insert-char ?* (- (* 2 i) 1))
    (insert "\n")))

Opět se podívejme na způsob použití této jednoduché interaktivní funkce:

Obrázek 20: Pyramidy výšky 1, 2 a 5.

Obrázek 21: Pyramida výšky 10.

16. Čtení znaků před a za aktuální pozicí kurzoru

Skripty napsané v Emacs Lispu dokážou jednoduše přečíst znaky, které se nachází před popř. za pozicí kurzoru. Připomeňme si, že pozice kurzoru se nachází přesně mezi dvěma znaky (popř. před prvním znakem či za posledním znakem), takže má skutečně význam mluvit o znakem před a za kurzorem. Jedná se o tyto dvě funkce:

Funkce Stručný popis
preceding-char vrátí kód předchozího znaku
following-char vrátí kód následujícího znaku

Po přesunu mezi první dva znaky (což jsou středníky) bude chování obou výše zmíněných funkcí následující:

(goto-char 2)
2
(preceding-char)
59
(following-char)
59

Chování funkcí na začátku bufferu:

bitcoin školení listopad 24

(goto-char (point-min))
1
(preceding-char)
0
(following-char)
59

Chování funkcí na konci bufferu:

(goto-char (point-max))
145
(preceding-char)
10
(following-char)
0

17. Repositář s demonstračními příklady

Zdrojové kódy většiny dnes popsaných demonstračních příkladů byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/elisp-examples (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má doslova několik kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:

# Demonstrační příklad Popis Cesta
1 01_point.el funkce pro zjištění informací o kurzoru a bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/01_point.el
2 02_narrow_widen.el funkce narrow a widen https://github.com/tisnik/elisp-examples/blob/master/elisp-6/02_narrow_widen.el
3 03_delete_two_lines.el vymazání dvou řádků z bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/03_delete_two_lines.el
4 04_deleten_lines_A.el funkce pro vymazání N řádků, první varianta https://github.com/tisnik/elisp-examples/blob/master/elisp-6/04_deleten_lines_A.el
5 05_deleten_lines_B.el funkce pro vymazání N řádků, druhá varianta https://github.com/tisnik/elisp-examples/blob/master/elisp-6/05_deleten_lines_B.el
6 06_deleten_lines_C.el funkce pro vymazání N řádků, třetí varianta https://github.com/tisnik/elisp-examples/blob/master/elisp-6/06_deleten_lines_C.el
7 07_deleten_lines_D.el funkce pro vymazání N řádků, čtvrtá varianta https://github.com/tisnik/elisp-examples/blob/master/elisp-6/07_deleten_lines_D.el
8 08_delete_text.el vymazání označeného textu z bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/08_delete_text.el
9 09_insert_hr.el zápis horizontální řádky do bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/09_insert_hr.el
10 10_insert_stars_A.el zápis horizontální řádky do bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/10_insert_stars_A.el
11 11_insert_stars_B.el zápis horizontální řádky do bufferu https://github.com/tisnik/elisp-examples/blob/master/elisp-6/11_insert_stars_B.el
12 12_draw_pyramid.el vykreslení pyramidy zadané výšky https://github.com/tisnik/elisp-examples/blob/master/elisp-6/12_draw_pyramid.el

18. Literatura

  1. McCarthy
    „Recursive functions of symbolic expressions and their computation by machine, part I“
    1960
  2. Guy L. Steele
    „History of Scheme“
    2006, Sun Microsystems Laboratories
  3. Kolář J., Muller K.:
    „Speciální programovací jazyky“
    Praha 1981
  4. „AutoLISP Release 9, Programmer's reference“
    Autodesk Ltd., October 1987
  5. „AutoLISP Release 10, Programmer's reference“
    Autodesk Ltd., September 1988
  6. McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I.
    „LISP 1.5 Programmer's Manual“
    MIT Press. ISBN 0 262 130 1 1 4
  7. Carl Hewitt; Peter Bishop and Richard Steiger
    „A Universal Modular Actor Formalism for Artificial Intelligence“
    1973
  8. Feiman, J.
    „The Gartner Programming Language Survey (October 2001)“
    Gartner Advisory
  9. Harold Abelson, Gerald Jay Sussman, Julie Sussman:
    Structure and Interpretation of Computer Programs
    MIT Press. 1985, 1996 (a možná vyšel i další přetisk)
  10. Paul Graham:
    On Lisp
    Prentice Hall, 1993
    Dostupné online na stránce http://www.paulgraham.com/on­lisptext.html
  11. David S. Touretzky
    Common LISP: A Gentle Introduction to Symbolic Computation (Dover Books on Engineering)
  12. Peter Norvig
    Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp
  13. Patrick Winston, Berthold Horn
    Lisp (3rd Edition)
    ISBN-13: 978–0201083194, ISBN-10: 0201083191
  14. Matthias Felleisen, David Van Horn, Dr. Conrad Barski
    Realm of Racket: Learn to Program, One Game at a Time!
    ISBN-13: 978–1593274917, ISBN-10: 1593274912

19. Odkazy na Internetu

  1. GNU Emacs Lisp Reference Manual: Point
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­lisp/Point.html
  2. GNU Emacs Lisp Reference Manual: Narrowing
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­lisp/Narrowing.html
  3. GNU Emacs Lisp Reference Manual: Functions that Create Markers
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­lisp/Creating-Markers.html
  4. GNU Emacs Lisp Reference Manual: Motion
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­lisp/Motion.html#Motion
  5. GNU Emacs Lisp Reference Manual: Basic Char Syntax
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­lisp/Basic-Char-Syntax.html
  6. Elisp: Sequence: List, Array
    http://ergoemacs.org/emac­s/elisp_list_vs_vector.html
  7. Elisp: Property List
    http://ergoemacs.org/emac­s/elisp_property_list.html
  8. Elisp: Hash Table
    http://ergoemacs.org/emac­s/elisp_hash_table.html
  9. Elisp: Association List
    http://ergoemacs.org/emac­s/elisp_association_list.html
  10. The mapcar Function (An Introduction to Programming in Emacs Lisp)
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­intr/mapcar.html
  11. Anaphoric macro
    https://en.wikipedia.org/wi­ki/Anaphoric_macro
  12. Some Common Lisp Loop Macro Examples
    https://www.youtube.com/wat­ch?v=3yl8o6r_omw
  13. A Guided Tour of Emacs
    https://www.gnu.org/softwa­re/emacs/tour/
  14. The Roots of Lisp
    http://www.paulgraham.com/ro­otsoflisp.html
  15. Evil (Emacs Wiki)
    https://www.emacswiki.org/emacs/Evil
  16. Evil (na GitHubu)
    https://github.com/emacs-evil/evil
  17. Evil (na stránkách repositáře MELPA)
    https://melpa.org/#/evil
  18. Evil Mode: How I Switched From VIM to Emacs
    https://blog.jakuba.net/2014/06/23/e­vil-mode-how-to-switch-from-vim-to-emacs.html
  19. GNU Emacs (home page)
    https://www.gnu.org/software/emacs/
  20. GNU Emacs (texteditors.org)
    http://texteditors.org/cgi-bin/wiki.pl?GnuEmacs
  21. An Introduction To Using GDB Under Emacs
    http://tedlab.mit.edu/~dr/gdbin­tro.html
  22. An Introduction to Programming in Emacs Lisp
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­intr/index.html
  23. 27.6 Running Debuggers Under Emacs
    https://www.gnu.org/softwa­re/emacs/manual/html_node/e­macs/Debuggers.html
  24. GdbMode
    http://www.emacswiki.org/e­macs/GdbMode
  25. Emacs (Wikipedia)
    https://en.wikipedia.org/wiki/Emacs
  26. Emacs timeline
    http://www.jwz.org/doc/emacs-timeline.html
  27. Emacs Text Editors Family
    http://texteditors.org/cgi-bin/wiki.pl?EmacsFamily
  28. Vrapper aneb spojení možností Vimu a Eclipse
    https://mojefedora.cz/vrapper-aneb-spojeni-moznosti-vimu-a-eclipse/
  29. 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/
  30. Emacs/Evil-mode – A basic reference to using evil mode in Emacs
    http://www.aakarshnair.com/posts/emacs-evil-mode-cheatsheet
  31. From Vim to Emacs+Evil chaotic migration guide
    https://juanjoalvarez.net/es/de­tail/2014/sep/19/vim-emacsevil-chaotic-migration-guide/
  32. Introduction to evil-mode {video)
    https://www.youtube.com/wat­ch?v=PeVQwYUxYEg
  33. EINE (Emacs Wiki)
    http://www.emacswiki.org/emacs/EINE
  34. EINE (Texteditors.org)
    http://texteditors.org/cgi-bin/wiki.pl?EINE
  35. ZWEI (Emacs Wiki)
    http://www.emacswiki.org/emacs/ZWEI
  36. ZWEI (Texteditors.org)
    http://texteditors.org/cgi-bin/wiki.pl?ZWEI
  37. Zmacs (Wikipedia)
    https://en.wikipedia.org/wiki/Zmacs
  38. Zmacs (Texteditors.org)
    http://texteditors.org/cgi-bin/wiki.pl?Zmacs
  39. TecoEmacs (Emacs Wiki)
    http://www.emacswiki.org/e­macs/TecoEmacs
  40. Micro Emacs
    http://www.emacswiki.org/e­macs/MicroEmacs
  41. Micro Emacs (Wikipedia)
    https://en.wikipedia.org/wi­ki/MicroEMACS
  42. EmacsHistory
    http://www.emacswiki.org/e­macs/EmacsHistory
  43. Seznam editorů s ovládáním podobným Emacsu či kompatibilních s příkazy Emacsu
    http://www.finseth.com/emacs.html
  44. evil-numbers
    https://github.com/cofi/evil-numbers
  45. Debuggery a jejich nadstavby v Linuxu (1.část)
    http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/
  46. Debuggery a jejich nadstavby v Linuxu (2.část)
    http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/
  47. Debuggery a jejich nadstavby v Linuxu (3): Nemiver
    http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/
  48. Debuggery a jejich nadstavby v Linuxu (4): KDbg
    http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/
  49. 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/
  50. Org mode
    https://orgmode.org/
  51. The Org Manual
    https://orgmode.org/manual/index.html
  52. Kakoune (modální textový editor)
    http://kakoune.org/
  53. Vim-style keybinding in Emacs/Evil-mode
    https://gist.github.com/tro­yp/6b4c9e1c8670200c04c16036805773d8
  54. Emacs – jak začít
    http://www.abclinuxu.cz/clan­ky/navody/emacs-jak-zacit
  55. Programovací jazyk LISP a LISP machines
    https://www.root.cz/clanky/pro­gramovaci-jazyk-lisp-a-lisp-machines/
  56. Evil-surround
    https://github.com/emacs-evil/evil-surround
  57. Spacemacs
    http://spacemacs.org/
  58. Lisp: Common Lisp, Racket, Clojure, Emacs Lisp
    http://hyperpolyglot.org/lisp
  59. Common Lisp, Scheme, Clojure, And Elisp Compared
    http://irreal.org/blog/?p=725
  60. Does Elisp Suck?
    http://irreal.org/blog/?p=675
  61. Emacs pro mírně pokročilé (9): Elisp
    https://www.root.cz/clanky/emacs-elisp/
  62. If I want to learn lisp, are emacs and elisp a good choice?
    https://www.reddit.com/r/e­macs/comments/2m141y/if_i_wan­t_to_learn_lisp_are_emacs_an­d_elisp_a/
  63. Clojure(Script) Interactive Development Environment that Rocks!
    https://github.com/clojure-emacs/cider
  64. An Introduction to Emacs Lisp
    https://harryrschwartz.com/2014/04/08/an-introduction-to-emacs-lisp.html
  65. Emergency Elisp
    http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html
  66. Racket
    https://racket-lang.org/
  67. The Racket Manifesto
    http://felleisen.org/matthi­as/manifesto/
  68. MIT replaces Scheme with Python
    https://www.johndcook.com/blog/2009/03/26/mit-replaces-scheme-with-python/
  69. Adventures in Advanced Symbolic Programming
    http://groups.csail.mit.e­du/mac/users/gjs/6.945/
  70. Why MIT Switched from Scheme to Python (2009)
    https://news.ycombinator.com/i­tem?id=14167453
  71. Starodávná stránka XLispu
    http://www.xlisp.org/
  72. AutoLISP
    https://en.wikipedia.org/wi­ki/AutoLISP
  73. Seriál PicoLisp: minimalistický a výkonný interpret Lispu
    https://www.root.cz/serialy/picolisp-minimalisticky-a-vykonny-interpret-lispu/
  74. Common Lisp
    https://common-lisp.net/
  75. Getting Going with Common Lisp
    https://cliki.net/Getting%20Started
  76. Online Tutorial (Common Lisp)
    https://cliki.net/online%20tutorial
  77. Guile Emacs
    https://www.emacswiki.org/e­macs/GuileEmacs
  78. Guile Emacs History
    https://www.emacswiki.org/e­macs/GuileEmacsHistory
  79. Guile is a programming language
    https://www.gnu.org/software/guile/
  80. MIT Scheme
    http://groups.csail.mit.e­du/mac/projects/scheme/
  81. SIOD: Scheme in One Defun
    http://people.delphiforum­s.com/gjc//siod.html
  82. CommonLispForEmacs
    https://www.emacswiki.org/e­macs/CommonLispForEmacs
  83. Elisp: print, princ, prin1, format, message
    http://ergoemacs.org/emac­s/elisp_printing.html
  84. Special Forms in Lisp
    http://www.nhplace.com/ken­t/Papers/Special-Forms.html
  85. Basic Building Blocks in LISP
    https://www.tutorialspoin­t.com/lisp/lisp_basic_syn­tax.htm
  86. Introduction to LISP – University of Pittsburgh
    https://people.cs.pitt.edu/~mi­los/courses/cs2740/Lectures/Lis­pTutorial.pdf
  87. Why don't people use LISP
    https://forums.freebsd.org/threads/why-dont-people-use-lisp.24572/
  88. Structured program theorem
    https://en.wikipedia.org/wi­ki/Structured_program_the­orem
  89. Clojure: API Documentation
    https://clojure.org/api/api
  90. Tutorial for the Common Lisp Loop Macro
    http://www.ai.sri.com/pkarp/loop.html
  91. Common Lisp's Loop Macro Examples for Beginners
    http://www.unixuser.org/~e­uske/doc/cl/loop.html
  92. A modern list api for Emacs. No 'cl required.
    https://github.com/magnars/dash.el
  93. The LOOP Facility
    http://www.lispworks.com/do­cumentation/HyperSpec/Body/06_a­.htm

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.