Emacs [1] ist ein freies Textbearbeitungsprogramm, das sowohl in der Konsole als auch mit grafischer Oberfläche genutzt werden kann, weitreichende Anpassung via Lisp [2] ermöglicht1 (lisp lernen [3]) und am Anfang der freie Software Bewegung stand (info [4]).
Es gibt ihn für fast alle Betriebssysteme, inklusive vieler exotischer, und er ist einer von zwei Editoren (=Textverarbeitungsprogrammen), um die eine eigene (ironisch gemeinte) Religion entstanden ist2. In Aktion sieht er z.B. so aus:
Die Zeile unten ist der Minibuffer, in dem Befehle eingegeben und Ausgaben angezeigt werden können. Das Bild habe ich aus meinem Eintrag Darum Emacs: Markdown mode [5] übernommen.
Hier sammle ich ein paar praktische Resourcen zu Emacs (=Links und Kurznotizen).
Eine Warnung sollte ich dir allerdings nicht vorenthalten: Emacs zu verwenden beinhaltet das Risiko, dass du immer größere Teile deiner Arbeitsabläufe in ihn verlagerst. Er ist inzwischen nicht mehr nur mein Editor, sondern auch LaTeX-IDE (mit grafischer Formelvorschau), Programmierplattform, Zeitplaner (org-mode, und ich kratze erst an der Oberfläche), GnuPG-verschlüsseltes Tagebuch, Darkroom-Schreibprogramm [6], Musikabspieler (emms), identi.ca client und vieles mehr. In emacs zu arbeiten wird Stück für Stück immer natürlicher und irgendwann wirkt alles andere unelegant und einschränkend. Und emacs funktioniert fast überall, selbst in der Text-Konsole und auf Android-Handies [7].
creating custom modes the easy way with generic-mode [8] – Eigene und seltene Dateiformate einfach selbst einbinden.
Rudel [9] – In Echtzeit mit mehreren Leuten an Dokumenten schreiben (übers Netz).
Das beinhaltet Dinge wie ein Mailprogramm oder Webbrowser, transparentes bearbeiten von verschlüsselten Dateien (wie in meinem Tagebuch [10]), Integration von Versionsverwaltungssystemen, Hervorhebung und Vervollständigung von Quellcode und vieles mehr; alles vom Benutzer aktivierbar (teils über die zahlreichen Erweiterungen im Emacs-Wiki [11]), wenn er es braucht, und trotzdem relativ schlank (im Vergleich zu vielen heutigen Texteditoren), ↩
Gemeint ist die „Church of Emacs [12]“. Der andere Editor ist vim [13], und was Features angeht, geben sich beide nichts. Sie haben aber völlig andere Grundannahmen, was Bedienbarkeit angeht3. ↩
Der Grundunterschied ist, dass man in Emacs direkt tippen kann und durch Kurzbefehle auf die verschiedenen Aktionen zugreift (‚Strg-x Strg-s‘ speichert, ‚Strg-x Strg-c‘ beendet), während in Vim (etwas vereinfacht) mit Escape und ‚i‘ zwischen dem Befehlsmodus und dem Tippmodus gewechselt werden kann (‚i‘ bringt einen in den Eingabemodus, ‚Escape :wq‘ speichert und beendet). Dabei ergingen sich Anhänger der beiden Editoren in oft immer weiter zugespitzten Diskussionen, die zu so freundlichen Bezeichnungen wie „Escape-Meta-Alt-Control-Shift“ für Emacs und Aussagen wie „Vim hat zwei Modi: Nur piepsen oder alles zerstören“ geführt haben (was beides eine Spur Wahrheit enthält und wohl nur im Rückblick lustig ist). Welchen von beiden man verwendet ist meist Geschmackssache (ich nutze z.B. meist Emacs). Was natürlich die Benutzer nicht daran hindert, endlos über ihren Geschmack zu streiten :) ↩
Ich habe letztens entdeckt [14], dass es einen Unicode-Modifier zum Durchstreichen gibt. Was lag also näher als eine Funktion zu schreiben, mit der ich in Plain-Text Worte durchstreichen kann?
Zum Glück macht emacs das einfach: Packt das folgende in eure .emacs
, dann könnt ihr mit M-x strikethrough
den aktuell markierten Text durchstreichen:
(defun strikethrough (start end) (interactive "r") (goto-char (min start end)) (while (< (point) (+ (max start end) (abs (- start end)))) (forward-char) (insert "̶")))
Achtet darauf, die Funktion wirklich zu kopieren. Der Bindestrich ist in Wirklichkeit 0x0336, auch bekannt als COMBINING LONG STROKE OVERLAY, 822, #o1466 oder #x336. Einfach Abtippen klappt also nicht.
Wenn ihr den Strich wirklich von Hand braucht, hilft euch M-x ucs-insert 336
.
Solche infos über ein Zeichen gibt euch übrigens M-x describe-key
.
Nun zum Test: strike C-SPACE M-b M-x strikethrough
.
Viel Spaß mit Emacs [15]!
Ich könnte vieles sagen, das ich an Emacs toll finde, aber ich werde mich hier auf ein einziges Bild beschränken:
Emacs [1] mit Markdown Mode [16] (und visual-line-mode [17]); nur eine seiner kleineren Stärken, aber die, die mich heute gepackt hat.
Anhang | Größe |
---|---|
2010-03-24-darum-emacs-markdown-mode.png [18] | 84.35 KB |
Das hier funktioniert seit dem Wechsel von web.de auf nur-SSL für mich nicht mehr. Ich habe noch nicht herausgefunden warum. Mein Bug-Report dazu [19].
Die Einrichtung von Emacs zum Verschicken von E-Mails hat mich etwas Zeit gekostet.
Bei web.de funktioniert das hier (EMAIL, NAME und PASSWORT ersetzen):
; email
(setq user-full-name "Arne Babenhauserheide"
mail-from-style 'angles
user-mail-address "EMAIL"
mail-default-reply-to user-mail-address)
(setq user-mail-address "EMAIL")
(setq smtpmail-default-smtp-server
"smtp.web.de")
(setq smtpmail-local-domain nil)
; disable “we now use message mode” warning.
(setq compose-mail-user-agent-warning nil)
(setq compose-mail-user-agent-warnings nil)
(setq message-default-headers "BCC: EMAIL
")
(require 'smtpmail)
; MailMode
(setq send-mail-function
'smtpmail-send-it)
; MessageMode
(setq message-send-mail-function
'message-smtpmail-send-it)
(setq starttls-extra-arguments
'("--insecure" "--verbose"))
(setq smtpmail-auth-credentials
'(("smtp.web.de" 25
"NAME" "PASSWORT")))
(setq smtpmail-default-smtp-server
"smtp.web.de")
(setq smtpmail-smtp-server "smtp.web.de")
(setq smtpmail-smtp-service 25)
Ich verwende nun seit einiger Zeit Emacs als Tagebuchprogramm. Mit ihm komme ich zum ersten Mal wirklich zum schreiben.
Der Aufruf bei mir ist schlicht
tagebuch
Den Grund, dass es für mich mit Emacs funktioniert, sehe ich darin, dass er mir genau das bietet, was ich brauche – und dabei verdammt schnell ist. Was ich brauche:
Verschlüsselung ohne Aufwand (epa-file integriert transparentes GnuPG, also wirklich sichere Verschlüsselung).
Sofort schreiben können (ist direkt bei der Zeile, bei der ich aufgehört habe).
Schnell. Ich will nicht warten müssen, bevor ich tippen kann (geht über eine eigene Initfile, die Codevervollständigung und so rauslässt).
Datum zum Eintrag (geht dank miniscript über „M-x datum“).
(Auch) Auf der (Text-)Konsole. Wenn ich am Systembasteln bin, will ich trotzdem Schreiben können.
Optional Versionsverwaltung (nur für backups; wenn es ein Mercurial repository gibt, speichere ich einen Schnappschuss via C-x v v
).
Und wenn ich mal was wo anders nutzen will, kann ich es einfach via emacs rüberkopieren, trotz verschlüsselter Datei. Und es gibt keine temporären Dateien, die ich entschlüsselt rumliegen haben muss.
Und es passt sich der Farbgebung meiner Konsole an :)
(benötigt emacs Version 23.1+ [1])
Meine Einrichtung sieht so aus:
.babrc (alias):
alias tagebuch='/usr/bin/emacs \
-nw --no-init-file --no-site-file \
--load ~/.emacs-init-tagebuch \
~/pfad/zum/Tagebuch.txt.gpg'
Dazu habe ich die Datei ~/.emacs-init-tagebuch [20].
Um deinen eigenen Emacs so zu nutzen (unter GNU/Linux),
~/.bashrc
, ~/.emacs-init-tagebuch
herunter und ~/.emacs.d/libs/markdown-mode/markdown-mode.el
. alias tagebuch='/usr/bin/emacs \
-nw --no-init-file --no-site-file \
--load ~/.emacs-init-tagebuch \
~/pfad/zum/Tagebuch.txt.gpg'
-nw --no-init-file und --no-site file sagen: In der Konsole anzeigen und kein Standarddateien laden → deutlich schneller (Emacs kann unglaublich viel, aber einige Sachen machen es langsam; z.B. die vollständige Programmierumgebung).
--load ~/.emacs-init-tagebuch: Fügt genau die Fähigkeiten hinzu, die ich brauche, keine mehr, keine weniger. Details weiter unten.
Der Pfad ist klar. Die ~/.emacs-init-tagebuch richtet Emacs so ein, dass es jede Datei, die auf .gpg endet, transparent entschlüsselt (heißt, ich muss nur das Passwort eingeben, dann kann ich arbeiten, als wäre es nur eine normale Textdatei). Außerdem wird in Dateien mit Endung .txt.gpg Markdown-Syntax hervorgehoben und ist so schöner zu lesen und schreiben (daran habe ich mich schlicht gewöhnt und will es auch in meinem Tagebuch).
Die init-Datei aktiviert einige Features, die ich brauche:
Sie bindet mir den Markdown Mode [22] ein, so dass ich Syntax-Highlighting habe.
(setq load-path (cons "~/.emacs.d/libs/markdown-mode" load-path))
(autoload 'markdown-mode "markdown-mode.el"
"Major mode for editing Markdown files" t)
Dann aktiviert sie markdown für verschlüsselte Textdateien:
(setq auto-mode-alist
(cons '("\\.txt\\.gpg" . markdown-mode)
auto-mode-alist))
Dazu liefert sie schöne Zeilenumbrüche (am Wortende):
(global-visual-line-mode)
und aktiviert transparente Ver- und Entschlüsselung:
(require 'epa-file)
(epa-file-enable)
Außerdem habe ich mir eine kleine Lisp-Funktion geschrieben, die mir das Datum als Titel (zweite Ebene, H2 in HTML) in Markdown-Syntax ausgibt. Sie wird einfach mit M-x datum
aufgerufen (im Code unten wird der Befehl durch das Schlüsselwort (interactive)
aktiviert). Und ja, ich könnte hier alles einfügen, das ich in Lisp generieren kann. Also so gut wie alles :) (echte Programmiersprache)
(defun datum ()
"print the current time in iso-format"
(interactive)
(insert (format-time-string "%Y-%m-%d %H:%M:%S") "\n-------------------\n\n"))
Abschließend legt sie fest, dass sich emacs die Zeilennummer merken soll (ich will beim nächsten Öffnen des Tagebuches wieder in der Zeile sein, in der ich aufgehört habe), dass ich keine Startinfo haben und Dateien in UTF-8 kodieren will (für Umlaute und Zeug wie ι∫→√).
(custom-set-variables
'(current-language-environment "UTF-8")
'(default-input-method "rfc1345")
'(inhibit-startup-screen t)
'(save-place t nil (saveplace)))
Damit habe ich ein Tagebuch-Programm, das alles kann, was ich brauche. Und wenn ich noch mehr brauche, kann ich das ohne Probleme später einfügen.
Viel Spaß beim Tagebuch-Schreiben mit Emacs!
Anhang | Größe |
---|---|
emacs-init-tagebuch [20] | 1 KB |
Um den Deutschen und Spanischen Muttertag in der Org-Agenda angezeigt zu bekommen, nutzt einfach
M-x customize-variable calendar-holidays
Und fügt die folgenden Zeilen ein:
(holiday-fixed 3 19 "Dia del Padre")
(holiday-float 5 0 2 "Muttertag")
(holiday-float 5 0 1 "Dia de la Madre")
(holiday-easter-etc 39 "Vatertag")
Dann nur noch C-x C-s
zum Speichern, und die Org-Agenda zeigt euch die richtigen Mutter- und Vatertage für Deutschland und Spanien an.
» Adding namespace support to emacs lisp in a macro with just 15 lines of code - it’s things like this which make lisp feel like the mother of all languages.«1
(defmacro namespace (prefix &rest sexps) (let* ((naive-dfs-map (lambda (fun tree) (mapcar (lambda (n) (if (listp n) (funcall naive-dfs-map fun n) (funcall fun n))) tree))) (to-rewrite (loop for sexp in sexps when (member (car sexp) '(defvar defmacro defun)) collect (cadr sexp))) (fixed-sexps (funcall naive-dfs-map (lambda (n) (if (member n to-rewrite) (intern (format "%s-%s" prefix n)) n)) sexps))) `(progn ,@fixed-sexps)))
(provide 'namespace)
(require 'namespace) (namespace foo (defun bar () "bar") (defun foo (s) "foo"))
(foo-foo (foo-bar))
Disclaimer: This code is not perfect. It will likely fail in unpredictable ways, and the number of not supported corner-cases is probably huge - and unknown. But (and that’s the relevant result) you can do this right. Rainer Joswig gives pointers for that [23] on Stackoverflow: “What you actually need is a so-called code-walker”. Also he shows examples where the code breaks.
(Der Hauptteil dieses Codes stammt von vpit3833 [24] und konr [25] und ich darf ihn verwenden [26]. Er funktioniert dank einer Korrektur von Stefan [27]. Er ist nicht perfekt, aber da er mir v.a. dazu dienen soll, meine eigenen Codeschnipsel besser zu organisieren, sollte ich das verschmerzen können)
Der Code mag schwer lesbar sein, hat aber riesige Implikationen: Du als einfacher Endnutzer des Lisp-Interpreters kannst Namespace-Support hinzufügen, ohne dass die Hauptentwickler dafür irgendetwas machen müssen.
Ich habe danach gesucht, weil ich in Python automatisch in jedem Modul einen Namespace habe, so dass der aktuelle Namensraum auch bei Verwendung von Zusatzmodulen sauber bleibt und ich immer weiß, woher eine Funktion oder Variable kommt, die ich verwende (das heißt, ich verwende kein from module import fun; fun()
, sondern nur noch import module; module.fun
oder bei sehr oft benutzten Modulen vielleicht noch import numpy as np; np.array()
).
Um das in Emacs Lisp zu realisieren, musste ich bis heute jede Funktion explizit mit dem Namensraum definieren - und auch in dem Modul mit dem Namensraum aufrufen. Mit dem namespace macro kann ich jetzt diesen Code
(defun foo-bar () "bar") (defun foo-baz () (foo-bar)) (defun foo-isastring (s) (stringp s)) (defun foo-foo (s) (if (foo-isastring s) "foo"))
(foo-foo (foo-bar))
In diesen Code umschreiben
(require 'namespace) (namespace foo (defun bar () "bar") (defun baz () (bar)) (defun isastring (s) (stringp s)) (defun foo (s) (if (isastring s) "foo")))
(foo-foo (foo-bar))
Spannend wäre jetzt noch ein require-namespaced
, um dem Code von anderen nachträglich einen Namensraum geben zu können:
(require-namespaced 'feature)
PS: In Guile Scheme [28] gibt es hierfür (use-modules ((foo) #:prefix foo-))
Der Code stammt größtenteils aus einer Diskussion auf Stackoverflow [29]. ↩
Ich bin gerade auf das Paper hier gestoßen:
“A Multi-Language Computing Environment for Literate Programming and Reproducible Research [30]” (PDF [31])
Es beschreibt schön, was mit emacs [32] org-mode [33] möglich ist. Dazu gehören so spannende Punkte wie im Dokument mitgelieferter Quellcode, dessen Ergebnisse automatisch eingebunden werden, so dass die Dokumente aktuell bleiben können.
Vor allem Neuerungen in Algorithmen können so sehr elegant gezeigt werden, und direkt erstellte Grafiken stellen sicher, dass keine veralteten Daten gezeigt werden und dokumentiert ist, woher die Daten eigentlich kommen.
Und der Quellcode sieht automatisch schön aus.
Das hier steht im paper (allerdings mit # statt \#):
\#+source: python-listdir \#+begin_src python import os return len(os.listdir('.')) \#+end_src
| number of files | |-----------------| | 28 | \#+TBLFM: @2$1='(sbe python-listdir)
Es wird zu dem hier:
import os return len(os.listdir('.'))
number of files |
---|
28 |
Und im PDF sieht es so aus:
Anhang | Größe |
---|---|
org-mode-babel-to-table.png [34] | 6.69 KB |
Links:
[1] http://www.gnu.org/software/emacs/
[2] http://de.wikipedia.org/wiki/LISP
[3] http://www.lisperati.com/casting-spels-emacs/html/casting-spels-emacs-1.html
[4] http://de.wikipedia.org/w/index.php?title=Freie_Software&stableid=73122325#Die_Geburt_Freier_Software
[5] https://www.draketo.de/licht/freie-software/darum-emacs-markdown-mode
[6] https://www.draketo.de/light/english/simple-emacs-darkroom
[7] http://www.emacswiki.org/emacs/EmacsOnAndroid
[8] http://emacs-fu.blogspot.com/2010/04/creating-custom-modes-easy-way-with.html
[9] http://www.emacswiki.org/emacs/Rudel
[10] https://www.draketo.de/licht/freie-software/emacs-als-tagebuch
[11] http://www.emacswiki.org/
[12] http://www.emacswiki.org/emacs/ChurchOfEmacs
[13] http://www.vim.org/
[14] http://identi.ca/notice/92711157
[15] http://gnu.org/software/emacs
[16] http://www.emacswiki.org/emacs/MarkdownMode
[17] http://www.emacswiki.org/emacs/LineWrap
[18] https://www.draketo.de/files/2010-03-24-darum-emacs-markdown-mode.png
[19] https://github.com/wanderlust/wanderlust/issues/55
[20] https://www.draketo.de/files/emacs-init-tagebuch
[21] http://jblevins.org/projects/markdown-mode/markdown-mode.el
[22] http://jblevins.org/projects/markdown-mode/
[23] http://stackoverflow.com/a/14731479/7666
[24] http://stackoverflow.com/users/346725/vpit3833
[25] http://stackoverflow.com/users/1130121/konr
[26] https://twitter.com/konr/status/299484276293001217
[27] http://stackoverflow.com/users/1283394/stefan
[28] http://gnu.org/s/guile
[29] http://stackoverflow.com/a/14731479
[30] http://www.jstatsoft.org/v46/i03/
[31] http://www.jstatsoft.org/v46/i03/paper
[32] https://www.draketo.de/licht/freie-software/emacs
[33] http://orgmode.org
[34] https://www.draketo.de/files/org-mode-babel-to-table.png