Dies ist meine persönliche, kommentierte Emacs-Konfiguration. Sie ist in der Syntax des Emacs Org-mode geschrieben. Der enthaltene Emacs Lisp Code wird beim Start des Emacs extrahiert und zur Konfiguration abgearbeitet; vgl. dazu meinen Text zur Systematik der Emacs-Konfiguration.
Versionsangaben:
Zunächst werden die Kernelemente meines Emacs konfiguriert.
Heutzutage installiert man Emacs-Pakete nicht mehr manuell, sondern man verwendet das Emacs-eigene Paketmanagement.
(require 'package)
(setq package-enable-at-startup nil)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "http://orgmode.org/elpa/")
("gnu" . "http://elpa.gnu.org/packages/")
("marmalade" . "https://marmalade-repo.org/packages/")))
(package-initialize)
use-package
ist ein sehr praktisches Paket von John Wiegley, das die
Strukturierung und Optimierung der Emacs-Konfiguration
ermöglicht. Weitere Informationen finden sich auf der Seite des
Github-Projekts.
;; Bootstrap `use-package'
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(load-theme 'wombat)
Und die Schrift:
(add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-16"))
Mich stören die in der Grundeinstellung automatisch erstellten Backup- und Autosave-Dateien. Also, hinfort damit:
(setq make-backup-files nil) ;; stop creating those backup~ files
(setq auto-save-default nil) ;; stop creating those #autosave# files
;; ausgewählten Text bei Eingabe löschen
(delete-selection-mode 1)
;; keine "yes-or-no"-Fragen - "y-or-n" reicht aus
(defalias 'yes-or-no-p 'y-or-n-p)
;; Zusammengehörende Klammern hervorheben
(show-paren-mode 1)
;; Text zwischen den Klammern nicht hervorheben
(setq show-paren-style 'parenthesis)
;; Aktuelle Spaltennummer in der Mode Line anzeigen
(column-number-mode nil)
Auch sehr praktisch: Popups mit Erläuterungen zu Tastenkombinationen,
Beispiel C-x
und dann warten.
(use-package which-key
:ensure t
:config
(which-key-mode))
Schöneres Springen in andere Windows mit C-x o
(Anzeige der Nummer
zum Direktanspringen).
(use-package ace-window
:ensure t
:init
(progn
(global-set-key [remap other-window] 'ace-window)
(custom-set-faces
'(aw-leading-char-face
((t (:inherit ace-jump-face-foreground :height 3.0)))))))
Und:
;; Buffer Menu
(global-set-key (kbd "C-x C-b") 'buffer-menu)
Die Breite des Neotree-Fensters ist mir in der Grundeinstellung zu schmal.
(use-package neotree
:ensure t
:config (setq neo-window-width 40))
(define-key global-map (kbd "<f1>") 'neotree)
mode-line
mit powerline
(use-package powerline
:ensure t)
(require 'powerline)
(powerline-default-theme)
Smex is a M-x
enhancement for Emacs. Built on top of IDO, it provides
a convenient interface to your recently and most frequently used
commands. And to all the other commands, too.
(ido-mode t)
(setq ido-enable-flex-matching t) ;; fuzzy matching is a must have
(setq ido-enable-last-directory-history nil) ;; forget latest selected directory names
(use-package smex
:ensure t
:bind (("M-x" . smex))
:config (smex-initialize))
;; SMEX
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)
(global-set-key (kbd "C-c C-c M-x") 'execute-extended-command) ;; This is your old M-x:
(use-package boxquote
:ensure t)
Mit boxquote-region
Text so hübsch „wrappen“:
,----
| tls-cipher DHE-RSA-AES256-SHA
| cipher AES-256-CBC
`----
Die folgenden Einstellungen sollen nur dann greifen, wenn die graphische Version des Emacs gestartet wird.
(if window-system
(progn
;; Frame Size and Position at Startup
(add-to-list 'default-frame-alist '(height . 36))
(add-to-list 'default-frame-alist '(width . 110))
(setq initial-frame-alist '((left . 220) (top . 65)))
;; Klick-Kram entfernen:
(tool-bar-mode -1)
(scroll-bar-mode -1)))
;; Das Menü soll immer ausgeblendet sein
(menu-bar-mode -1)
Magit ist eine Oberfläche für die Versionsverwaltung Git. Eine Killer-App des Emacs.
(use-package magit
:ensure t
:config (setq magit-display-buffer-function ;; Make Magit Fullscreen
(lambda (buffer)
(if magit-display-buffer-noselect
;; the code that called `magit-display-buffer-function'
;; expects the original window to stay alive, we can't go
;; fullscreen
(magit-display-buffer-traditional buffer)
(delete-other-windows)
;; make sure the window isn't dedicated, otherwise
;; `set-window-buffer' throws an error
(set-window-dedicated-p nil nil)
(set-window-buffer nil buffer)
;; return buffer's window
(get-buffer-window buffer)))))
(global-set-key "\C-xg" 'magit-status)
(use-package org
:mode (("\\.\\(org\\|org_archive\\)$" . org-mode))
:ensure org-plus-contrib
:config
(progn
(setq org-hide-leading-stars 'hidestars)
(setq org-return-follows-link t)
(setq org-drawers (quote ("PROPERTIES" "CLOCKTABLE" "LOGBOOK" "CLOCK")))
(setq org-completion-use-ido t)
(setq org-tags-exclude-from-inheritance '("review"))))
Um meine Einstellungen ausführlich kommentieren zu können, definiere
ich die weiteren Konfigurationen außerhalb der
use-package
-Definition.
(use-package htmlize
:ensure t)
org-download - Drag and drop images to Emacs org-mode.
(use-package org-download
:ensure t)
Der Org-mode verfügt über eine sehr einfache Funktion, um schnell neue
Aufgaben, Notizen und ähnliche Dinge zu erfassen, ohne dass man erst
viel in seinen Dateien navigieren müsste oder in seiner anderen Arbeit
im Emacs unterbrochen würde. Wenn man beispielsweise gerade im Emacs
einen Text schreibt, ein Anruf kommt und eine Notiz erfassen möchte,
so kann man durch Eingabe von C-c c
einen Buffer aufrufen, in dem
man diese erfasst und wenn man dann C-c C-c
betätigt, wird die Notiz
an der vorgesehenen Stelle gespeichert und man befindet sich wieder im
ursprünglichen Textdokument, welches man bearbeitet. Auf diese Weise
können Unterbrechnungen des Arbeitsflusses durch Anrufe, eigene
spontane Ideen und anderes gering gehalten werden.
(setq org-capture-templates
'(("t" "Aufgabe in tasks.org" entry (file+headline "~/projects/org/tasks.org" "Inbox")
"* TODO %?")
("w" "Waiting For Reply (Mail)" entry (file+headline "~/projects/org/tasks.org" "Inbox")
"* WAITING Antwort auf %a")
("m" "Aufgabe aus Mail" entry (file+headline "~/projects/org/tasks.org" "Inbox")
"* TODO %? , Link: %a")
("z" "Zeiteintrag in tasks.org" entry (file+headline "~/projects/org/tasks.org" "Inbox")
"* ZKTO %? \n %i" :clock-in t :clock-resume t)
("c" "Contacts" entry (file "~/projects/org/contacts.org")
"* %(org-contacts-template-name) \n :PROPERTIES: %(org-contacts-template-email) \n :BIRTHDAY: \n :END:")
("j" "Journal" entry (file+datetree "~/projects/org/journal.org")
"* %?\nEntered on %U\n %i")
("p" "password" entry (file "~/projects/org/passwords.gpg")
"* %^{Title}\n %^{PASSWORD}p %^{USERNAME}p")))
;; Automatische Anpassung des Links zu einer E-Mail.
;; Alle Mails werden im Folder 'Archive' gespeichert.
(add-hook 'org-capture-prepare-finalize-hook 'hs/search)
(defun hs/search ()
(interactive)
(goto-char 1)
(replace-string "INBOX" "Archive"))
Häufig erreichen mich neue Aufgaben per E-Mail. Dann kann es praktisch sein, einen Link zu dieser E-Mail mit der Aufgabe zu speichern. Es gibt mittlerweile Lösungen für die verschiedensten E-Mail-Programme. Als Emacs-Geek verwendet man natürlich ohnehin ein E-Mail-Programm direkt im Emacs; es gibt aber auch Erweiterungen für externe Programme. Der Org mode unterstützt nativ eine Reihe dieser Programme wie VM, Wanderlust, Gnus, notmuch oder MH-E. Siehe dazu die Sektion External Links in der Org mode Dokumentation. Die nötigen Befehle sind zu finden im Kapitel Handling Links.
C-c l
(org-store-link
) wird der Link zu der aktuellen
Nachricht in die Zwischenablage kopiert.
C-c c
kann dann mit C-c C-l
(org-insert-link
)
der Link eingefügt werden.
In der Grundeinstellung verfügt der Org-mode lediglich über die
Todo-Stadien TODO
und DONE
. Ich verwende ein paar mehr:
Eine „normale“ Aufgabe kann die offenen Stadien TODO
, STARTED
,
WAITING
, DELEGATED
und die geschlossenen Stadien DONE
oder
CANCELED
haben. Daneben habe ich für Termine APPT
, für Projekte
PROJ
und für Zeitkonten ZKTO
vorgesehen.
;; Ein "!" bedeutet Zeitstempel
;; Ein "@" bedeutet Notiz
(setq org-todo-keywords
'((sequence "TODO(t)" "STARTED(s!)" "WAITING(w@/!)" "APPT(a)" "PROJ(p)" "NOTIZ(n)" "BESPROCHEN(b)"
"DELEGATED(g@/!)" "|" "DONE(d!)" "ZKTO(z)" "CANCELED(c@)")))
;; Farben anpassen
(setq org-todo-keyword-faces
'(("TODO" . (:foreground "#b70101" :weight bold))
("STARTED" . (:foreground "#b70101" :weight bold))
("APPT" . (:foreground "sienna" :weight bold))
("PROJ" . (:foreground "lightblue" :weight bold))
("NOTIZ" . (:foreground "yellow" :weight bold))
("ZKTO" . (:foreground "orange" :weight bold))
("WAITING" . (:foreground "orange" :weight bold))
("BESPROCHEN" . (:foreground "darkorange" :weight bold))
("REVIEWED" . (:foreground "forestgreen" :weight bold))
("DONE" . (:foreground "forestgreen" :weight bold))
("DELEGATED" . (:foreground "forestgreen" :weight bold))
("CANCELED" . shadow)))
;; Fast TODO Selection
(setq org-use-fast-todo-selection t)
Einen Zeitstempel eintragen, wenn eine Aufgabe als erledigt markiert wird.
(setq org-log-done 'time)
Einen eigenen Drawer benutzen:
(setq org-log-into-drawer t)
;; Aktuelle Zeile in der Agenda hervorheben
(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1 )))
(setq org-agenda-format-date
"%Y-%m-%d ---------------------------------------------------------------------")
;; Tasks mit Prioriäten unterschiedlich darstellen:
(setq org-agenda-fontify-priorities
(quote ((65 (:foreground "Red")) (66 (:foreground "Blue")) (67 (:foreground "Darkgreen")))))
(setq org-agenda-date-weekend (quote (:foreground "Yellow" :weight bold)))
;; Tasks mit Datum in der Agenda ausblenden, wenn sie bereits erledigt sind:
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-scheduled-if-done t)
Nach der Methode Getting Things Done gibt es Aufgaben, die man zwar erfasst, die man aber nicht zu einem bestimmten Zeitpunkt oder in absehbarer Zukunft erledigen möchte. Diese Aufgaben tagge ich mit „someday“. Sie werden in der Standardansicht meiner Agenda ausgeblendet und ich kann sie nur (im Rahmen des Weekly-Review) mit einer speziellen Agenda-Ansicht ausdrücklich anzeigen lassen.
(setq org-agenda-filter-preset '("-someday"))
Die Agenda nicht in der Wochenansicht, sondern Tagesansicht starten:
(setq org-agenda-span 1)
(setq org-agenda-include-diary t)
(setq org-agenda-custom-commands
(quote (
("g" . "GTD-Workflow")
("gn" "Next Actions" tags-todo "next" ((org-use-tag-inheritance nil)))
("gd" "DONE" tags-todo "done" ((org-use-tag-inheritance nil)))
("gw" "Waiting" todo "WAITING")
("gs" "SOMEDAY" tags "someday" ((org-agenda-filter-preset
'("+someday"))(org-agenda-todo-ignore-with-date nil)))
("gz" "ZKTO" tags "zkto")
("gf" "Agenda + flagged + Zeitkonten"
((tags "zkto")
(todo "WAITING")
(todo "DELEGATED")
(tags "flagged")
(agenda "")))
("p" . "People")
("pb" "Stefan" tags-todo "stefan" ((org-use-tag-inheritance nil)))
("w" . "Privates")
("wo" "Org-Mode-Konfiguration" tags-todo "orgmode" ((org-use-tag-inheritance nil))))))
(setq org-agenda-files (quote
("~/projects/org/tasks.org"
"~/projects/org/journal.org"
"~/projects/emacs-config/emacs-config.org"
"~/projects/org/notes/")))
(setq org-agenda-window-setup 'current-window)
log-mode
In der Agenda kann man mit l
den log-mode
aktivieren. Dann werden
die geloggten Aktivitäten des jeweiligen Tages angezeigt.
l
startet den log-mode
in der
Grundeinstellung: Closed und Clocked Tasks
C-u l
zeigt alles: Closed, Clocked und State-Änderungen (z.B. auf
Waiting gesetzt)
C-u C-u l
blendet die offenen Tasks aus und zeigt nur die
Logging-Informationen
;;(setq org-agenda-log-mode-items '(closed state))
(setq org-agenda-log-mode-items '(closed clock))
Eine sehr interessante und praktische Funktion ist die Möglichkeiten, Zeiten für die einzelnen Aufgaben zu erfassen und beliebige Auswertungen der aufgezeichneten Zeiten zu generieren.
Die Zeiteinträge sollen in einem eigenen Drawer abgelegt werden:
(setq org-clock-into-drawer "CLOCK")
Das Ein- und Ausclocken erfolgt über F5
und F8
oder I
und O
direkt in der Agenda.
(fset 'my-clock-in "\C-c\C-x\C-i")
(global-set-key (kbd "<f5>") 'my-clock-in)
(fset 'my-clock-out "\C-c\C-x\C-o")
(global-set-key (kbd "<f8>") 'my-clock-out)
Die folgende Einstellung sorgt dafür, dass der Org-mode dann, wenn ein Task mit „clocknote“ getaggt ist, beim Ausclocken eine Notiz abfragt. Ich nutze dieses dafür, um eine nähere Beschreibung zu Zeiten, die ich auf Zeitkonten wie „Allgemeine Verwaltung“ buche, einzugeben. Auf diese Weise muss ich nicht immer dann, wenn ich eine Kleinigkeit erledige, einen neuen Zeiteintrag mit Hilfe der Capture-Funktion erstellen. Ich habe also die folgenden Varianten der Generierung von Zeiteinträgen zur Verfügung:
(defun hs/check-for-clock-out-note()
(interactive)
(save-excursion
(org-back-to-heading)
(let ((tags (org-get-tags)))
(and tags (message "tags: %s " tags)
(when (member "clocknote" tags)
(org-add-note))))))
(add-hook 'org-clock-out-hook 'hs/check-for-clock-out-note)
Weitere Einstellungen:
;; Resume clocking tasks when emacs is restarted
;;(org-clock-persistence-insinuate)
;; Yes it's long... but more is better ;)
(setq org-clock-history-length 35)
;; Resume clocking task on clock-in if the clock is open
(setq org-clock-in-resume t)
;; Change task state to STARTED when clocking in
;(setq org-clock-in-switch-to-state "STARTED")
;; Sometimes I change tasks I'm clocking quickly
;; this removes clocked tasks with 0:00 duration
;;(setq org-clock-out-remove-zero-time-clocks t)
;; Don't clock out when moving task to a done state
(setq org-clock-out-when-done nil)
;; Save the running clock and all clock history when exiting Emacs,
;; load it on startup
(setq org-clock-persist t)
;; Disable auto clock resolution
(setq org-clock-auto-clock-resolution nil)
(setq org-global-properties (quote (("Effort_ALL" .
"0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 8:00"))))
Nachdem ich lange Zeit mit Clocktables gearbeitet hatte, habe ich dann doch noch herausgefunden, dass man sich die aufgezeichneten Zeiten auch in der Agenda anzeigen lassen kann. Darüber hatte ich zwar schon häufiger nachgedacht, dass das eine nette Sache wäre, aber mir ist nie aufgefallen, dass es auch diese tolle Funktion bereits gibt.
;; Agenda direkt mit dem jeweiligen Clock-Report starten:
(setq org-agenda-start-with-clockreport-mode t)
;; Auch die Zeit einer aktuell laufenden Uhr einbeziehen:
(setq org-clock-report-include-clocking-task t)
;; Keine Links, maximal bis Level 3 herunter:
;;(setq org-agenda-clockreport-parameter-plist (quote (:link nil :maxlevel 3)))
(setq org-agenda-clockreport-parameter-plist
(quote (:link t :maxlevel 4 :fileskip0 t :compact t :narrow 80)))
Die Clocking-Tabelle in der Agenda kann mit "R" aus- und wieder eingeblendet werden.
Folgende Sprachen in Babel aktivieren:
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)
(shell . t)
(js . t)
(latex . t)
(org . t)
(dot . t)
(gnuplot . t)
(ruby . t)
(screen . nil)
(ledger . t)
(C . t)
(sql . t)
(ditaa . t)))
Syntax Highlighting in Source Code Blocks:
(setq org-src-fontify-natively nil)
Wenn man mit Sprachen wie Python arbeitet, bei denen die Einrückung des Codes „Erklärungswert“ hat, sind folgende Einstellungen sinnvoll:
(setq org-edit-src-content-indentation 0)
(setq org-src-tab-acts-natively t)
(setq org-src-preserve-indentation t)
Der Org-mode verfügt mit der Column-View über eine spezielle Ansicht, die meines Wissens nach einer Funktion der Aufgabenverwaltung Omnifocus for Mac nachgebildet wurde.
(setq org-columns-default-format
"%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM")
Führt man einfache Aufgabenlisten, dann eignen sich die „normalen“ Org mode Tasks sehr gut. Verwendet man den Org mode allerdings dazu, umfangreichere Notizen oder Texte zu schreiben, die man mit dem Org mode als Outliner strukturiert, kollidiert dies mit der Definition von Aufgaben in diesen Dokumenten. Was man dann benötigt, ist eine Möglichkeit, Aufgaben zu definieren, die keinen Einfluss haben auf die Strukturelemente. Und dies sind die sog. Inline Tasks.
;;(use-package org-inlinetask
;; :bind (:map org-mode-map
;; ("C-c C-x t" . org-inlinetask-insert-task))
;; :after (org)
;; :commands (org-inlinetask-insert-task)
;; :config (setq org-inlinetask-export t))
(require 'org-inlinetask)
Ein Beispiel:
Dies ist ein Inline Task. Er wird grundsätzlich genauso behandelt wie ein „normaler“ Tasks, allerdings wird er nicht mit in das Visibility Cycling mit einbezogen.
Damit die Source Code Blocks im Export mit Syntax Highlighting versehen werden:
;;(use-package htmlize
;; :ensure t
;; :config (setq org-html-htmlize-output-type nil)) ;; standard: inline-css
Ich deaktiviere htmlize
zwischendurch, da ich org-notes
für meine
Website ohne Syntax Highlighthing exportieren möchte. Mein Custom
Exporter versieht die Source Code Blocks statt dessen mit einer der
Sprache entsprechenden Markierung, die von highlight.js erkannt
wird. Das Syntax Highlighthing auf meiner Website wird dann durch
highlight.js im Webbrowser des Betrachters vorgenommen.
Und nun Custom CSS:
(setq org-html-head "<style type='text/css'>
body {
font-family: Helvetica, Arial, sans-serif;
text-align: left;
width: 920px;
padding: 10px;
padding-top: 10px;
line-height: 1.5em;
margin: 0 auto;
font-size: 18px;
line-height: 1.6em;
color: #505050;
hyphens: auto;
}
.title {
padding-bottom: 20px;
}
pre {
color: #c6c6c6;
background-color: #292929;
padding: 0.5em;
font-size: 16px;
}
code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
border-radius: 4px;
}
pre.src {
padding: 0.5em;
}
table, th, td {
border: 1px solid #b1b1b1;
}
th {
background: #dadada;
}
.PROJ { color: blue; }
.WAITING { color: orange; }
.org-ul p { color: grey; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; }
#postamble {
margin-top: 10px;
margin-left: -10px;
font-size: 10pt;
line-height: 13px;
background-color: #eeeeee;
border: 1px solid #cccccc;
padding: 5px;
}
#postamble a {
display: none;
}
#postamble .creator a {
display: inline;
color: black;
text-decoration: none;
}
</style>")
org-reveal
Reveal.js ist eine gute Möglichkeit, auf einfache Weise ansprechende
Präsentationen zu erstellen. Mit org-reveal
wird es noch besser.
(use-package ox-reveal
:ensure t)
Es folgt eine angepasste LaTeX-Vorlage. Verwendet werden kann sie so:
#+TITLE: Titel
#+LaTeX_CLASS: myscrartcl
(add-to-list 'org-latex-classes
'("myscrartcl"
"\\documentclass{scrartcl}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\usepackage{listings,xcolor}
\\usepackage{hyperref}
\\usepackage[scaled=.90]{helvet} % Helvetica für Überschriften
\\usepackage{mathptmx} % Times für den Fließtext
\\renewcommand{\\contentsname}{Inhaltsverzeichnis}
\\hypersetup{unicode=false,colorlinks=true,linkcolor=blue,filecolor=cyan,citecolor=green,urlcolor=magenta}
[NO-DEFAULT-PACKAGES][NO-PACKAGES]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
;; PDFs visited in Org-mode are opened in Evince (and not in the default choice) https://stackoverflow.com/a/8836108/789593
(add-hook 'org-mode-hook
'(lambda ()
(delete '("\\.pdf\\'" . default) org-file-apps)
(add-to-list 'org-file-apps '("\\.pdf\\'" . "evince %s"))))
(require 'ox-odt)
(setq org-odt-preferred-output-format "docx")
Org-Support für Ditaa.
(setq org-ditaa-jar-path "/usr/bin/ditaa")
Die folgenden Zeilen sorgen dafür, dass der Emacs alle Dateien mit der
Endung .gpg
verschlüsselt speichert. Beim Öffnen werden sie direkt
wieder entschlüsselt.
(require 'epa-file)
(epa-file-enable)
Wenn man nur einzelne Bereiche einer Org mode Datei verschlüsseln
möchte, braucht man zusätzlich org-crypt
. Diese Erweiterung
verschlüsselt den Text unter einer Überschrift beim Speichern, wenn
der Tag crypt
vergeben wurde. Erst durch den Befehl
org-decrypt-entries
bzw. org-decrypt-entry
werden die
entsprechenden Inhalte wieder entschlüsselt.
;(require 'org-crypt)
;(org-crypt-use-before-save-magic)
;(setq org-tags-exclude-from-inheritance (quote ("crypt")))
;(setq org-crypt-key nil)
;; GPG key to use for encryption
;; Either the Key ID or set to nil to use symmetric encryption.
;(setq auto-save-default nil)
;; Auto-saving does not cooperate with org-crypt.el: so you need
;; to turn it off if you plan to use org-crypt.el quite often.
;; Otherwise, you'll get an (annoying) message each time you
;; start Org.
;; To turn it off only locally, you can insert this:
;;
;; # -*- buffer-auto-save-file-name: nil; -*-
Fußnoten definiere ich direkt im Text.
(setq org-footnote-define-inline t)
(use-package org-contacts
:config
(setq org-contacts-files '("~/projects/org/contacts.org")))
;; Targets include this file and any file contributing to the agenda - up to 5 levels deep
;;(setq org-refile-targets (quote ((org-agenda-files :maxlevel . 5) (nil :maxlevel . 5))))
;; Targets start with the file name - allows creating level 1 tasks
(setq org-refile-use-outline-path (quote file))
;; Targets complete in steps so we start with filename, TAB shows the next level of targets etc
(setq org-outline-path-complete-in-steps t)
Meine private Website basiert auf Python und Django. Texte, die ich in
der Rubrik „GNU Emacs“ pflege, schreibe ich im Emacs org-mode
– das
finde ich praktischer als sie in HTML oder einem WYSIWYG-Editor zu
schreiben. Für den Export verwende ich einen angepassten Exporter, der
die org-mode
-Dateien in Django-Templates schreibt.
(add-to-list 'load-path "~/projects/emacs-config/")
(require 'ox-django-website)
Um nicht jede einzelne Datei manuell in HTML exportieren zu müssen,
verwende ich ox-publish
.
(require 'ox-publish)
(setq org-publish-project-alist
'(
("org-notes"
:base-directory "~/projects/org-notes/"
:base-extension "org"
:publishing-directory "~/projects/website/website/apps/core/templates/core/emacs/"
:publishing-function org-twbs-publish-to-django-html
)
("emacs-config"
:base-directory "~/projects/emacs-config/"
:base-extension "org"
:publishing-directory "~/projects/website/website/apps/core/templates/core/emacs/"
:publishing-function org-twbs-publish-to-django-html
)))
;;; Switches off use of time-stamps when publishing. I would prefer to publish
;;; everything every time
(setq org-publish-use-timestamps-flag nil)
(use-package auto-complete
:ensure t)
(use-package projectile
:ensure t)
(use-package paredit
:ensure t)
(use-package web-mode
:ensure t
:config
(progn
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(setq web-mode-engines-alist
'(("django" . "\\.html\\'")))
(setq web-mode-ac-sources-alist
'(("css" . (ac-source-css-property))
("html" . (ac-source-words-in-buffer ac-source-abbrev))))
(setq web-mode-markup-indent-offset 2)
(setq web-mode-code-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-enable-current-element-highlight t)
(setq web-mode-enable-auto-closing t)
(setq web-mode-enable-auto-quoting t)
(setq web-mode-enable-auto-pairing t)
(setq web-mode-enable-auto-expanding t)
(setq web-mode-enable-css-colorization t)))
(use-package go-mode
:ensure t)
Es gibt viele unterschiedliche Modi und Pakete für die Arbeit mit Python-Dateien. Ein einfacher Python-Modus ist bereits im Standardumfang des Emacs enthalten.
(use-package epc
:ensure t)
(use-package jedi
:ensure t)
(use-package anaconda-mode
:ensure t)
(use-package company
:ensure t)
(use-package company-anaconda
:ensure t)
(global-font-lock-mode t)
(setq font-lock-maximum-decoration t)
;; no tabs but four spaces for indentation
(setq-default indent-tabs-mode nil)
(setq default-tab-width 4)
Derzeit verwende ich den anaconda-mode
.
(add-hook 'python-mode-hook 'anaconda-mode)
(add-hook 'python-mode-hook 'eldoc-mode)
;; company mode
(add-hook 'after-init-hook 'global-company-mode)
;; company-anaconda
(eval-after-load "company"
'(progn
(add-to-list 'company-backends 'company-anaconda)))
;; start in python mode
(add-hook 'python-mode-hook 'anaconda-mode)
Mit den Jahren sind eine Reihe von MUAs für den Emacs entwickelt worden. Ich verwende notmuch.
(setq user-full-name "Hendrik Sünkler"
user-mail-address "mailbox@suenkler.info")
Weitere Header-Zeilen:
(setq message-default-headers
(concat "X-OS: Debian GNU/Linux"))
Ich halte meine E-Mails zentral auf dem IMAP-Server meines Providers
und synchronisiere den Account mit einem lokalen Maildir-Verzeichnis.
Auf dieses Verzeichnis lasse ich dann das Programm notmuch
los. Als
MUA verwende ich den mit notmuch
mitgelieferten MUA notmuch.el
.
Meine ~/.mbsyncrc
:
IMAPAccount suenkler-info
Host imap.example.com
User XXXXXXXXX
Pass XXXXXXXXX
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore suenkler-info-remote
Account suenkler-info
MaildirStore suenkler-info-local
Path ~/.mail/suenkler-info/
Inbox ~/.mail/suenkler-info/INBOX
Trash trash
Channel suenkler-info-folders
Master :suenkler-info-remote:
Slave :suenkler-info-local:
Patterns *
Create Both
Expunge Both
SyncState *
Group suenkler-info
Channel suenkler-info-folders
Mit folgenem Skript stoßte ich die Synchronisation an:
#!/bin/bash
# Sync mail when online
if ping -c1 8.8.8.8 &>/dev/null; then
# Sync Maildir
/usr/bin/mbsync suenkler-info
# Index Mail
/usr/local/bin/notmuch new
fi
Und dieses Skript soll alle fünf Minuten ausgeführt werden:
$ crontab -l
*/5 * * * * /home/hendrik/bin/sync_mail.sh > /dev/null
Die Distributionspakete von notmuch
sind in der Regel recht alt,
daher habe ich das Programm aus den Quellen übersetzt. Auch der
Emacs-MUA ist im Source-Paket enthalten. Achtung: Nicht die Version
aus dem Emacs-Paketmanagement installieren; die MUA-Version muss mit
der CLI-Version übereinstimmen; ab besten scheint daher die
Installation direkt aus den Quellen.
Bei Aufruf von ./configure
zeigt sich ggf., dass nicht alle
Abhängigkeiten erfüllt sind. Die Fehlermeldung hat aber eine schöne
Auflistung der Abhängigkeiten samt apt
-Befehl zur Installation unter
Debian-artigen Betriebssystemen geliefert. Anschließend ließ sich
notmuch
kompilieren.
Nun den MUA im Emacs einbinden:
(add-to-list 'load-path "~/bin/notmuch-0.24.2/emacs/")
(require 'notmuch)
(global-set-key "\C-xm" 'notmuch)
E-Mails versende ich über das Emacs-eigene SMTP-Modul. Bei mir hat das
bisher immer sehr gut funktioniert. Wenn man etwas mehr möchte, bietet
sich beispielsweise msmtp
an.
(use-package smtpmail
:config
(setq
user-full-name "Hendrik Sünkler"
smtpmail-local-domain "suenkler.info"
user-mail-address (concat "mailbox@" smtpmail-local-domain)
send-mail-function 'smtpmail-send-it
smtpmail-smtp-server "smtp.suenkler.info"
smtpmail-stream-type 'starttls
smtpmail-smtp-service 587))
Die Version von deft
in den ELPA-Repositories funktionierte bei mir
nicht korrekt. Daher lade ich deft
manuell:
(add-to-list 'load-path "~/projects/emacs-config/lib/")
(require 'deft)
(use-package deft
;; :ensure t
:config (setq deft-directory "~/projects/org/notes/")
(setq deft-strip-title-regexp "\\(?:^%+\\|^#\\+TITLE: *\\|^#\\+COMMENT: *\\|^[#* ]+\\|-\\*-[[:alpha:]]+-\\*-\\|^Title:[ ]*\\|#+$\\)")
(setq deft-directory "~/projects/org/notes/")
(setq deft-text-mode 'org-mode)
(setq deft-extension "org")
(setq deft-extensions '("org"))
(setq deft-default-extension "org")
(setq deft-use-filename-as-title nil)
(setq deft-use-filename-as-title nil)
(setq deft-use-filter-string-for-filename nil)
(setq deft-use-filter-string-for-filename nil))
(defun show-notes ()
(interactive)
(hs-kill-buffers "*Deft*")
(when deft-directory "~/projects/bep/org/"
(setq-default deft-directory "~/projects/org/notes/"))
(deft))
(defun show-website ()
(interactive)
(hs-kill-buffers "*Deft*")
(setq-default deft-directory "~/projects/org-website/")
(deft))
(defun show-itsec-notes ()
(interactive)
(hs-kill-buffers "*Deft*")
(setq-default deft-directory "~/projects/org/itsec-notes/")
(deft))
(defun show-programming-notes ()
(interactive)
(hs-kill-buffers "*Deft*")
(setq-default deft-directory "~/projects/org/programming-notes/")
(deft))
;; Deft mit Notizen auf C-c n
(global-set-key "\C-cn" 'show-notes)
(global-set-key "\C-cw" 'show-website)
;; Deft mit programming notes auf C-c p
(global-set-key "\C-cp" 'show-programming-notes)
(global-set-key "\C-ci" 'show-itsec-notes)
;; Start Deft in insert-mode
;;(evil-set-initial-state 'deft-mode 'insert)
Wenn man Deft mit C-c C-q
beendet, besteht ein Buffer mit dem Namen
„Deft“ fort. Solange dieser Buffer existent ist, greift die
Neudefinition insbesondere des Verzeichnisses (deft-directory
)
nicht. Daher wird kill-matiching-buffers
verwendet. Die
Emacs-Funktion kill-matching-buffers
erwartet allerdings eine
Bestätigung durch den Anwender (yes or no), wenn der betreffende
Buffer geändert wurde. Dies ist beim Deft-Buffer stets der Fall. Die
folgende Funktion ermöglicht das Schließen von Buffern ohne eine
solche Abfrage – und wird in den oben definierten Funktionen
verwendet.
(require 'cl)
(defun hs-kill-buffers (regexp)
"Kill buffers matching REGEXP without asking for confirmation."
(interactive "sKill buffers matching this regular expression: ")
(flet ((kill-buffer-ask (buffer) (kill-buffer buffer)))
(kill-matching-buffers regexp)))
Unused files can be archived by pressing C-c C-a
. Files will be
moved to deft-archive-directory
, which is a directory named
`archive` within your deft-directory by default.
Es ergibt sich dann jedoch das Problem, wie man bei Bedarf die archivierten Notizen durchsuchen kann. Die Lösung scheint eine rekursive Suche:
By default, Deft only searches for files in deft-directory but not in
any subdirectories. Set deft-recursive
to a non-nil value to enable
recursive searching for files in subdirectories:
(setq deft-recursive t)
(use-package ledger-mode
:ensure t
:mode "\\.ledger\\'"
:config
(define-key ledger-mode-map (kbd "C-c c") 'ledger-mode-clean-buffer)
(setq ledger-post-amount-alignment-at :decimal
ledger-post-amount-alignment-column 49
ledger-clear-whole-transactions t)
(use-package flycheck-ledger))
;; Emacs-Konfigurationsdatei auf C-c e
(global-set-key "\C-ce" '(lambda ()
(interactive)
(find-file "~/projects/emacs-config/emacs-config.org")))
;; Tasks-Datei auf C-c g
(global-set-key "\C-cg" '(lambda ()
(interactive)
(find-file "~/projects/org/tasks.org")))
;; Übersichtsseite auf C-c s
(global-set-key "\C-cs" '(lambda ()
(interactive)
(find-file "~/projects/org/start.org")))
;; Org Store Link
(global-set-key "\C-cl" 'org-store-link)
;; Agenda
(global-set-key "\C-ca" 'org-agenda)
;; Meine Hauptagenda auf F12
(defun org-agenda-show-myagenda (&optional arg)
(interactive "P")
(org-agenda arg "gf"))
(global-set-key (kbd "<f12>") 'org-agenda-show-myagenda)
;; Org Capture
(define-key global-map "\C-cc" 'org-capture)
(global-set-key (kbd "<f9>") 'org-capture)
Damit ich nicht bei jeder Kleinigkeit manuell „committen“ muss, habe ich automatische stündliche Commits konfiguriert.
Zunächst sollen alle orgmode
-Buffer immer eine Minute vor jeder
vollen Stunde gespeichert werden, damit sie in die Versionsverwaltung
eingecheckt werden können:
(run-at-time "00:59" 3600 'org-save-all-org-buffers)
Und hier das Shellscript:
#!/bin/sh
# Add org file changes to the repository
REPOS="org emacs-config"
for REPO in $REPOS
do
echo "Repository: $REPO"
cd ~/projects/$REPO
# Remove deleted files
git ls-files --deleted -z | xargs -0 git rm >/dev/null 2>&1
# Add new files
git add . >/dev/null 2>&1
git commit -m "$(date)"
done
Über den folgenden Crojob wird das Script zu jeder vollen Stunde ausgeführt:
0 * * * * ~/bin/org-git-sync.sh >/dev/null
Ich habe ein paar zusätzliche, vertrauliche Einstellungen, die ich
nicht in dieser öffentlich geteilten Fassung wiedergeben möchte. Sie
finden sich in der Datei secret.el
, die nicht mit in die
Versionsverwaltung eingecheckt wird.
(require 'secret)
Beim Start des Emacs soll die Datei tasks.org
geladen werden.
;; Keinen Splash-Screen
(setq inhibit-splash-screen t)
(find-file "~/projects/org/tasks.org")