Files
emacs.d/config.org

46 KiB
Raw Blame History

Meine Emacs-Konfiguration

Benutzerangaben

Name und Emailadresse

  (setq user-full-name "Ariane Troche")
  (setq user-mail-address "ariane@familie-troche.de")

Secrets

Mit einem GPG (GnuPG) Schlüssel lassen sich private Dateien verschlüsseln. Emacs hilft beim Verschlüsseln und Entschlüsseln: Keeping Secrets in Emacs with GnuPG

  (setq auth-sources
        '((:source "~/.secrets/.authinfo.gpg")))

Start

Startfenster

Einige Einstellungen, die den Startbildschirm betreffen:

Splash Screen

Der übliche Emacs-Startbildschirm soll nicht angezeigt werden. Damit öffnet sich direkt der scratch-Buffer, welcher komplett leer sein soll.

  (setq inhibit-splash-screen t)
  (setq initial-scratch-message nil)

Scrollbar, Toolbar, Menubar

Scrollbar, Toolbar und Menubar werden ausgeblendet.

  (scroll-bar-mode -1)
  (tool-bar-mode -1)
  (menu-bar-mode -1)

Vollbildschirm

Das Fenster wird im Vollbild geöffnet.

  (setq initial-frame-alist '((fullscreen . maximized)))

Server

Damit beim Start von Emacs nicht immer ein neuer Prozess gestartet wird, wird Emacs hier schon als Server aufgesetzt. Using Emacs as a Server

  (server-start)

Backup und Autosave

Die Backup- und Autosave-Dateien stören eher, da ich sie noch nie gebraucht habe, sollen sie erst gar nicht angelegt werden. Help keeping ~/.emacs.d clean

  (use-package no-littering
    :config (with-eval-after-load 'recentf
              (add-to-list 'recentf-exclude no-littering-var-directory)
              (add-to-list 'recentf-exclude no-littering-etc-directory))

    (setq auto-save-file-name-transforms  ; autosaved-file-name~
          `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))
          custom-file (no-littering-expand-etc-file-name "custom.el"))

    (if (file-exists-p custom-file)
        (load-file custom-file)))

Konfigurationsdatei

Konfigurationsdatei

Ich bastel sehr gerne an meiner Konfigurationsdatei herum. Mit <f1> kann ich sie ganz schnell öffnen und mit <f2> neu laden.

Key Funktion
F1 Öffne Konfigurationsdatei in anderem Fenster
F2 Konfiguration neu laden, ohne Emacs-Neustart
  ;; Pfade
  (setq artr/file-init (expand-file-name "init.el" user-emacs-directory))
  (setq artr/file-config (expand-file-name "config.org" user-emacs-directory))
  ;; Öffnen
  (defun artr/find-config-file ()
    "Edit my init file in another window."
    (interactive)
    (find-file artr/file-config))
  ;; Laden
  (defun artr/reload-emacs-configuration ()
    "Reload init.el"
    (interactive)
    (load-file artr/file-init))
  ;; Keys
  (global-set-key (kbd "<f1>") 'artr/find-config-file)
  (global-set-key (kbd "<f2>") 'artr/reload-emacs-configuration)

Neustart

Mit <F12> kann ich Emacs neu starten.

Key Funktion
F12 Emacs-Neustart
  (use-package restart-emacs
    :ensure t
    :bind ("<f12>" . 'restart-emacs))

Look and Feel

Font

Key Funktion
C Schriftgröße schrittweise verkleinern
C-* Schriftgröße schrittweise vergrößern
C-0 Schriftgröße auf Default zurücksetzen

Font

  ;; for unicode
  (when (display-graphic-p)
    (set-fontset-font "fontset-default" nil
                      (font-spec :size 20 :name "Symbola")))
  ;; for emoji
  (set-fontset-font
   t
   '(#x1f300 . #x1fad0)
   (cond
    ((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
    ((member "Noto Emoji" (font-family-list)) "Noto Emoji")
    ((member "Segoe UI Emoji" (font-family-list)) "Segoe UI Emoji")
    ((member "Symbola" (font-family-list)) "Symbola")
    ((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji")))

  ;; font to use
  (defconst artr/default-font-family "Source Code Pro")
  (defconst artr/default-font-size 100)
  (defconst artr/default-icon-size 15)

  (set-face-attribute 'default nil
                      :family artr/default-font-family
                      :height artr/default-font-size)

Schriftgröße anpassen

  (defun artr/adjust-font-size (height)
    "Adjust font size by given height. If height is '0', reset font
  size. This function also handles icons and modeline font sizes."
    (interactive "nHeight ('0' to reset): ")
    (let ((new-height (if (zerop height)
                          artr/default-font-size
                        (+ height (face-attribute 'default :height)))))
      (set-face-attribute 'default nil :height new-height)
      (set-face-attribute 'mode-line nil :height new-height)
      (set-face-attribute 'mode-line-inactive nil :height new-height)
      (message "Font size: %s" new-height))
    (let ((new-size (if (zerop height)
                        artr/default-icon-size
                      (+ (/ height 5) treemacs--icon-size))))
      (when (fboundp 'treemacs-resize-icons)
        (treemacs-resize-icons new-size))
      (when (fboundp 'company-box-icons-resize)
        (company-box-icons-resize new-size))))

Schrift vergrößern

  (defun artr/increase-font-size ()
    "Increase font size by 0.5 (5 in height)."
    (interactive)
    (artr/adjust-font-size 5))

Schrift verkleinern

  (defun artr/decrease-font-size ()
    "Decrease font size by 0.5 (5 in height)."
    (interactive)
    (artr/adjust-font-size -5))

Schriftgröße zurücksetzen

  (defun artr/reset-font-size ()
    "Reset font size according to the `artr/default-font-size'."
    (interactive)
    (artr/adjust-font-size 0))

Keybindings

  (global-set-key (kbd "C--") 'artr/decrease-font-size)
  (global-set-key (kbd "C-*") 'artr/increase-font-size)
  (global-set-key (kbd "C-0") 'artr/reset-font-size)

Icons

domtronn /all-the-icons.el

  (use-package all-the-icons)

Modeline

doom-modeline - A fancy and fast mode-line inspired by minimalism design. A minor-mode menu for the mode line - minions anzu.el - displays match information in the mode-line in various search modes

  (use-package doom-modeline
    :custom (doom-modeline-icon t)
    (doom-modeline-minor-modes t)
    (doom-modeline-unicode-fallback t)
    (doom-modeline-mu4e nil)
    (doom-modeline-buffer-encoding nil)
    :init
    :hook (after-init . doom-modeline-mode))

  (use-package minions
    :hook (doom-modeline-mode . minions-mode))

  (use-package anzu
    :after isearch
    :config (global-anzu-mode))

Theme

Dired

Dired, the Directory Editor

  (use-package dired
    :ensure nil
    :config
    ;; Always delete and copy recursively
    (setq dired-recursive-deletes 'always
          dired-recursive-copies 'always)
    (when (executable-find "ls")
      ;; Using `insert-directory-program'
      (setq ls-lisp-use-insert-directory-program t)
      ;; Show directory first
      (setq dired-listing-switches "-alh --group-directories-first")))
  ;; Show git info in dired
  (use-package dired-git-info
    :bind (:map dired-mode-map
                (")" . dired-git-info-mode)))
  ;; Allow rsync from dired buffers
  (use-package dired-rsync
    :bind (:map dired-mode-map
                ("C-c C-r" . dired-rsync)))
  ;;Icons
  (use-package all-the-icons-dired
    :hook (dired-mode . all-the-icons-dired-mode))

Text

Textbreite

  (setq-default fill-column 90)
  (setq column-number-mode t)
  (use-package virtual-auto-fill
    :hook (text-mode . virtual-auto-fill-mode))

Whitespace

  (use-package whitespace
    :hook (before-save . whitespace-cleanup))
  (setq-default sentence-end-double-space nil)

Tabulators

  (setq-default
   indent-tabs-mode nil  ; Use spaces instead of tabs
   tab-width 4)

Copy/Paste

  (delete-selection-mode)

Klammern

  (electric-pair-mode)
  (show-paren-mode 1)

  (use-package rainbow-delimiters
    :hook
    (prog-mode . rainbow-delimiters-mode))

Fenster

teilen

Funktionen/Tastenkombination um neue Fenster zu erzeugen. Wenn ein neues Fenster erzeugt wird auch direkt dahin wechseln.

Key Funktion
C-1 Alle anderen Fenster schließen
C-2 Neues Fenster unterhalb
C-3 Neues Fenster daneben
  (defun artr/split-window-below-and-switch ()
    "Split the window below, then switch to the new window."
    (interactive)
    (split-window-below)
    (other-window 1))

  (defun artr/split-window-right-and-switch ()
    "Split the window right, then switch to the new window."
    (interactive)
    (split-window-right)
    (other-window 1))

  (global-set-key (kbd "C-1") 'delete-other-windows)
  (global-set-key (kbd "C-2") 'artr/split-window-below-and-switch)
  (global-set-key (kbd "C-3") 'artr/split-window-right-and-switch)

wechseln

ace-window Bei mehr als 2 Fenstern in der Konfiguration werden die Fenster "durchnummeriert". So können Aktionen gezielt durchgeführt werden. Die möglichen Aktionen werden mit ? aufgelistet. Bei 2 Fenstern wird das Fenster einfach gewechselt.

Key Funktion
M-o ace-windows (? zeigt mögliche Aktionen)
M-O ace-swap-windows
  (use-package ace-window
    :init (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
                aw-scope 'frame)
    :bind (("M-o" . ace-window)
           ("M-O" . ace-swap-window)))

anordnen

Key Funktion
C-c <left> vorherige Fensterkonfiguration
C-c <right> nächste Fensterkonfiguration
  (use-package winner
    :config (winner-mode))

eyebrowse Es können Fensterkonfigurationen angelegt und wiederhergestellt werden. Das Speichern der Konfigurationen passiert in sogenannten Slots, die von 0,… durchnummeriert werden. Mit C-c w 0 kann dann direkt die zugehörige Konfiguration wiederhergestellt werden.

Key Funktion
C-c w key-map
C-c w n neue Fensterkonfiguration
C-c w . Fensterkonfiguration wechseln
C-c w , Fensterkonfiguration benennen
  (use-package eyebrowse
    :bind (("C-c w ." . eyebrowse-switch-to-window-config)
           ("C-c w ," . eyebrowse-rename-window-config)
           ("C-c w DEL" . eyebrowse-close-window-config)
           ("C-c w k" . eyebrowse-close-window-config)
           ("C-c w n" . eyebrowse-create-window-config))
    :init (setq eyebrowse-keymap-prefix (kbd "C-c w")
                eyebrowse-wrap-around t
                eyebrowse-mode-line-style 'always
                eyebrowse-mode-line-separator "|")
    (eyebrowse-mode t))

bezeichnen

Die Fenster werden mit "Projektname | Dateiname" bezeichnet.

  (setq-default frame-title-format
                '((:eval
                   (let ((project-name (projectile-project-name)))
                     (unless (string= "-" project-name)
                       (format "%s| " project-name))))
                  "%b"))  ; project-name| file-name

Treemacs

Treemacs - a tree layout file explorer for Emacs

  (use-package treemacs
    :diminish
    :commands (treemacs-follow-mode
               treemacs-filewatch-mode
               treemacs-fringe-indicator-mode
               treemacs-git-mode
               treemacs)
    :bind (([f8] . treemacs)
           ("M-0"       . treemacs-select-window)
           ("C-x 1"     . treemacs-delete-other-windows)
           ("C-x t 1"   . treemacs-delete-other-windows)
           ("C-x t t"   . treemacs)
           ("C-x t b"   . treemacs-bookmark)
           ("C-x t C-t" . treemacs-find-file)
           ("C-x t M-t" . treemacs-find-tag)))

  (use-package treemacs-magit
    :after magit
    :commands treemacs-magit--schedule-update
    :hook ((magit-post-commit
            git-commit-post-finish
            magit-post-stage
            magit-post-unstage)
           . treemacs-magit--schedule-update))

Tools

Magit

Magit ist ein git-Client für Emacs: Magit User Manual

  (use-package magit
    :bind ("C-x g" . magit-status))

  (use-package git-gutter
    :config
    (global-git-gutter-mode +1))

Helpful

Helpful - Eine Context-Hilfe mit mehr Informationen

  (use-package helpful
    :bind (([remap describe-function] . helpful-callable)
           ([remap describe-variable] . helpful-variable)
           ([remap describe-key] . helpful-key)
           :map emacs-lisp-mode-map
           ("C-c C-d" . helpful-at-point)))

Helm

A Package in a league of its own: Helm Helm ist eine Schnittstelle, mit der man in einer Auswahl von Kandidaten suchen und filtern kann. Diese Schnittstelle kann in verschiedensten Anwendungen eingesetzt werden, wie z.B. Dateien, Buffer, Funktionen, Variablen und noch vieles mehr. Es gibt viele Erweiterungen für Helm.

Key Aktion
M-x Funktionsaufruf
C-c h helm-mini mit Buffer, Recent-Files und Bookmarks
C-h a Tastenkombinationen
C-x C-f Datei
C-x b Buffer
C-x f Recent-Files
C-x c b Bookmarks
C-x c SPC Mark-Rings
M-y Kill-Ring
C-x c o Suche in Datei mit Occur
C-x c s Suche in Datei mit Swoop
  (use-package helm
    :demand
    :bind ("M-x" . helm-M-x)
    ("C-h a" . helm-apropos)
    ("C-c h" . helm-mini)
    ("C-x C-f" . helm-find-files)
    ("C-x f" . helm-recentf)
    ("C-x b" . helm-buffers-list)
    ("C-x c b" . helm-filtered-bookmarks)
    ("C-x c o" . helm-occur)
    ("C-x c s" . helm-swoop)
    ("C-x c SPC" . helm-all-mark-rings)
    ("M-y" . helm-show-kill-ring)
    :preface (require 'helm-config)
    :config (helm-mode 1))

  (use-package helm-icons
    :after helm
    :config
    (treemacs-resize-icons artr/default-icon-size)
    (helm-icons-enable))

  (use-package helm-swoop
    :after helm
    :chords
    ("js" . helm-swoop)
    ("jp" . helm-swoop-back-to-last-point)
    :init
    (bind-key "M-m" 'helm-swoop-from-isearch isearch-mode-map))

  (use-package helm-descbinds
    :init
    (setq helm-descbinds-window-style 'split-window)
    :bind ("C-h b" . helm-descbinds))

Company

  (use-package company
    :bind ("M-/" . company-complete)
    :hook (after-init . global-company-mode)
    :init (setq company-idle-delay 0))

  (use-package helm-company
    :after company helm
    :bind (:map company-mode-map
                ("C-:" . helm-company)
                :map company-active-map
                ("C-:" . helm-company)))

Snippets

Mit Yasnippet lassen sich Templates definieren und mit einer Tastenkombination belegen. Die Templates werden im Ordner snippets jeweils unter einem Mode-spezifischen Ordner gespeichert.

Das Paket yasnippet-snippets stellt eine Auswahl an Templates zur Verfügung. Mit helm-c-yasnippet lassen sich die Snippets mit Helm durchsuchen und filtern.

Key Aktion
C-c & C-n neues Template anlegen
C-c & C-s Template einfügen
C-c & C-v Template öffnen
C-c y Templates auswählen
  (use-package yasnippet
    :diminish yas-minor-mode
    :hook (after-init . yas-global-mode))

  (use-package yasnippet-snippets
    :after yasnippet)

  (use-package helm-c-yasnippet
    :bind (("C-c y" . helm-yas-complete)))

Projectile

  (use-package projectile
    :config
    (define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
    (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
    (projectile-mode 1)
    :init
    (setq projectile-completion-system 'helm))

Which-Key

  (use-package which-key
    :init
    (which-key-mode))

Org

Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system.

https://de.wikipedia.org/wiki/Org-mode

Konfiguration

Dateien und Ordner

  (setq artr/dir-nextcloud "~/Nextcloud/")
  (setq artr/dir-org (concat artr/dir-nextcloud "Notes/org/"))
  (setq artr/dir-notes (concat artr/dir-nextcloud "Notes/org/notes/"))
  (setq artr/dir-archive (concat artr/dir-org "archives/"))

  (setq artr/dir-gtd (concat artr/dir-org "gtd/"))
  (setq artr/dir-home (concat artr/dir-gtd "home/"))
  (setq artr/dir-parcit (concat artr/dir-gtd "parcit/"))
  (setq artr/file-inbox (concat artr/dir-org "inbox.org"))
  (setq artr/file-areas (concat artr/dir-home "areas.org"))
  (setq artr/file-projects (concat artr/dir-home "projects.org"))
  (setq artr/file-grocery (concat artr/dir-home "grocery.org"))
  (setq artr/file-meals (concat artr/dir-home "meals.org"))
  (setq artr/file-calendar (concat artr/dir-home "calendar.org"))

Basics

  (use-package org
    :ensure org-plus-contrib
    :mode (("\\.org\\'" . org-mode))
    :bind
    ;; ("\C-cl" . 'org-store-link)
    ("\C-ca" . 'org-agenda)
    ("\C-cb" . 'org-switchb)
    ("\C-ct" . 'org-todo)
    :init
    (add-to-list 'org-modules 'org-contacts t)
    (add-to-list 'org-modules 'ol-notmuch t)
    (add-to-list 'org-modules 'org-tempo t)
    (add-to-list 'org-modules 'org-habit t)
    (add-to-list 'org-modules 'org-checklist t)
    ;; Ein bisschen größerer Abstand zwischen den Zeilen
    (add-hook 'org-mode-hook
              '(lambda () (setq line-spacing 0.3)))
    :config
    ;; Symbole als Symbole anzeigen
    (setq org-pretty-entities t)
    ;; Emphasise
    (setq org-hide-emphasis-markers t)
    ;; Folding Symbol
    ;; (setq org-ellipsis " ⏷")
    ;; Refile bis Level 3 und Suche mit helm
    (setq org-refile-use-outline-path 'file)
    (setq org-outline-path-complete-in-steps nil)
    (setq org-completion-use-ido nil)
    (setq org-refile-targets '((org-agenda-files :maxlevel . 5)))
    (setq org-return-follows-link t)
    ;; Code-Blocks
    (setq org-src-fontify-natively t)
    (setq org-src-tab-acts-natively t)
    (setq org-confirm-babel-evaluate nil)
    (org-babel-do-load-languages
     'org-babel-load-languages
     '((latex     . t)
       (plantuml  . t)
       (python    . t)
       (shell     . t)
       (calc      . t)
       (ditaa     . t)
       (org       . t)))
    ;; Ditaa und PlantUML
    (setq
     org-plantuml-jar-path "/usr/share/plantuml/plantuml.jar"
     org-ditaa-jar-path "/usr/share/ditaa/ditaa.jar")
    ;; Archive
    (setq org-archive-location (concat artr/dir-archive "%s::"))
    ;; Speed-Commands
    (setq org-use-speed-commands t
          org-speed-commands-user
          '(("N" org-narrow-to-subtree)
            ("A" org-archive-subtree)
            ("W" widen)
            ("k" org-cut-subtree)
            ("m" org-mark-subtree)))
    (setq org-agenda-window-setup 'current-window))

Kalender

Unerwünschte Kalender ausblenden
  (setq holiday-hebrew-holidays nil)
  (setq holiday-islamic-holidays nil)
  (setq holiday-bahai-holidays nil)
  (setq holiday-oriental-holidays nil)
  (setq holiday-solar-holidays nil)
Die Woche beginnt am Montag und deutsche Wochentage und Monate
  (setq calendar-week-start-day 1
        calendar-day-name-array ["Sonntag" "Montag" "Dienstag"
                                 "Mittwoch" "Donnerstag" "Freitag" "Samstag"]
        calendar-day-header-array ["So" "Mo" "Di" "Mi" "Do" "Fr" "Sa"]
        calendar-month-name-array ["Januar" "Februar" "März" "April" "Mai" "Juni"
                                   "Juli" "August" "September" "Oktober" "November" "Dezember"])
Feiertage (NRW)
  (setq holiday-general-holidays
        '((holiday-fixed 1 1 "Neujahr")
          (holiday-fixed 5 1 "1. Mai")
          (holiday-fixed 10 3 "Tag der Deutschen Einheit")))
  (setq holiday-christian-holidays
        '((holiday-float 12 0 -4 "1. Advent" 24)
          (holiday-float 12 0 -3 "2. Advent" 24)
          (holiday-float 12 0 -2 "3. Advent" 24)
          (holiday-float 12 0 -1 "4. Advent" 24)
          (holiday-fixed 12 25 "1. Weihnachtstag")
          (holiday-fixed 12 26 "2. Weihnachtstag")
          (holiday-easter-etc -48 "Rosenmontag")
          (holiday-easter-etc  -2 "Karfreitag")
          (holiday-easter-etc   0 "Ostersonntag")
          (holiday-easter-etc  +1 "Ostermontag")
          (holiday-easter-etc +39 "Christi Himmelfahrt")
          (holiday-easter-etc +49 "Pfingstsonntag")
          (holiday-easter-etc +50 "Pfingstmontag")
          (holiday-easter-etc +60 "Fronleichnam")
          (holiday-fixed 11 1 "Allerheiligen")))

Bullets

Zeigt unterschiedliche Bullets für die Org-Mode Levels.

  (use-package org-superstar
    :ensure t
    :hook (org-mode . org-superstar-mode)
    :init
    (setq org-superstar-headline-bullets-list '("⚫" "⚫" "⚫" "⚫"))
    (setq org-hide-leading-stars nil)
    (setq org-superstar-leading-bullet ?\s))

TODO

TODO-Keywords

Meine TODO-Sequenz. Die Keywords haben folgende Bedeutung:

TODO
Eine offene Aufgabe
NEXT
Eine priorisierte Aufgabe
WAITING
Eine delegierte Aufgabe
EXPIRED
Eine abgelaufene Aufgabe
DONE
Eine erledigte Aufgabe
CANCELED
Eine gestrichene Aufgabe
  (setq org-todo-keywords
        '((sequence "TODO(t)" "NEXT(n)" "WAITING(w)" "EXPIRED"
                    "|" "DONE(x!)" "CANCELLED(c)")))
  (setq org-log-into-drawer t)

Capture

Mit den Capture-Templates lassen sich schnell Dinge erfassen und an der gewünschten Stelle speichern. Ich nutze als Speicherort vor allem die Inbox diese sollte ich dann spätestens am Abend im Daily-Review leeren. In der Inbox wird folgendes gespeichert

TODO (C-c c ia)
Eine einfache Aufgabe in der Inbox
Email (C-c c ie)
Eine Mail aus Notmuch, die ich zu beantworten habe
Link
Eine Internetseite, die ich noch lesen möchte

Für Internetseiten habe ich mehrere Möglichkeiten

org-cliplink (C-c c l)
URL aus der Zwischenablage direkt in Inbox speichern
org-protocol (C-c c w)
Link wird direkt aus dem Browser in Inbox gespeichert
DOCT
  (use-package doct
    ;;recommended: defer until calling doct
    :commands (doct))
Templates
  (setq org-default-notes-file artr/file-inbox)
  (global-set-key (kbd "C-c c") 'org-capture)
  (setq org-capture-templates
        (doct '(("org-protocol-capture"
                 :keys "w"
                 :file artr/file-inbox
                 :todo-state "TODO"
                 :headline   "Internet"
                 :template "* %{todo-state} [[%:link][%:description]]\n\n %i"
                 :immediate-finish t)
                ("Inbox" :keys "i"
                 :file artr/file-inbox
                 :prepend t
                 :todo-state "TODO"
                 :children (("Aufgabe" :keys "a"
                             :headline "Aufgaben"
                             :template "* %{todo-state} %?")
                            ("Email" :keys "e"
                             :headline   "Emails"
                             :template  "* %{todo-state} Mail: %a")
                            ("Internet"  :keys "i"
                             :headline   "Internet"
                             :template "* %{todo-state} %(org-cliplink-capture)"
                             :immediate-finish t)
                            )))))

Agenda

Konfiguration
  ;; Agenda-Dateien
  (setq org-directory artr/dir-org)
  (setq org-agenda-files ())
  (add-to-list 'org-agenda-files artr/dir-home)
  (add-to-list 'org-agenda-files artr/dir-parcit)
  (add-to-list 'org-agenda-files artr/file-inbox)
  ;; Fensterverhalten
  ;;(setq org-agenda-window-setup 'current-window)
  (setq org-agenda-restore-windows-after-quit t)
  ;; Vordefinierte Agendas zurücksetzen
  (setq org-agenda-custom-commands nil)
  ;; Darstellung
  (setq org-agenda-compact-blocks nil)
  (setq org-agenda-block-separator (string-to-char "-"))
  (setq org-habit-graph-column 45)
  ;; Skip
  (setq org-agenda-skip-function-global '(artr/skip-entry-if-tag "skip"))
  (setq org-agenda-skip-deadline-if-done t)
  (setq org-agenda-skip-scheduled-if-done t)
  ;; Bulk Functions
  (setq org-agenda-bulk-custom-functions '((?C (lambda nil (org-agenda-todo "")))))
  ;; Stuck Projects
  (setq org-stuck-projects
        '("+LEVEL=1+Projekt={.}-DONE" ("NEXT" "TODO") nil ""))
Funktionen
Skip-Funktionen
  (defun artr/skip-entry-if-tag (tag)
    "Alle Einträge mit dem Tag tag werden ignoriert."
    (let ((subtree-end (save-excursion (org-end-of-subtree t))))
      (if (member tag
                  (split-string
                   (or (org-entry-get (point) "ALLTAGS") "")
                   ":"))
          subtree-end
        nil)))
Mouse-Face
  (add-hook 'org-agenda-finalize-hook
            (lambda () (remove-text-properties
                        (point-min) (point-max) '(mouse-face t))))
Super-Agenda
  (use-package org-super-agenda
    :after org-agenda
    :init
    (org-super-agenda-mode))
Agendas
Gruppierung
  (add-to-list 'org-agenda-custom-commands
               '("g" . "Getting Things Done...") t)
  (add-to-list 'org-agenda-custom-commands
               '("p" . "Planung...") t)
Aufgaben

** ACTIVE Übersicht

  (add-to-list 'org-agenda-custom-commands
               '("g1" "(1) Übersicht - Heute"
                 ((agenda "" ((org-agenda-overriding-header "Heute")
                              (org-agenda-span 'day)
                              (org-super-agenda-groups
                               '((:name "Termine..."
                                        :time-grid t)
                                 (:name "Jeden Tag..."
                                        :habit t)
                                 (:name "Heute..."
                                        :scheduled today)
                                 (:name "Überfällig..."
                                        :scheduled past)
                                 (:name "Bald..."
                                        :scheduled future)
                                 (:discard (:anything t))))))
                  (alltodo "" ((org-agenda-overriding-header "Refile")
                               (org-agenda-files (list artr/file-inbox))
                               (org-agenda-sorting-strategy '(alpha-up))))
                  (todo "TODO" ((org-agenda-overriding-header "Areas")
                                (org-agenda-files (list artr/file-areas))
                                (org-agenda-todo-ignore-scheduled t)
                                (org-super-agenda-groups
                                 '((:auto-group t))))))) t)
Die nächsten 3 Tage

Zeigt alle Termine und Aufgaben, die in den nächsten 3 Tagen geplant sind.

  (add-to-list 'org-agenda-custom-commands
               '("g2" "(2) Übersicht - Die nächsten 3 Tage"
                 ((agenda "" ((org-agenda-overriding-header "Die nächsten 3 Tage")
                              (org-agenda-span 4))))) t)
Mahlzeiten
  (add-to-list 'org-agenda-custom-commands
               '("g3" "(3) Übersicht - Mahlzeiten für diese Woche"
                 ((todo "TODO|DONE" ((org-agenda-overriding-header "Mahlzeiten")
                                     (org-agenda-files (list artr/file-meals))
                                     (org-super-agenda-groups
                                      '((:auto-planning))))))) t)
Einkaufsliste
  (add-to-list 'org-agenda-custom-commands
               '("g4" "(4) Übersicht - Einkaufsliste"
                 ((alltodo "" ((org-agenda-overriding-header "Einkaufsliste")
                               (org-agenda-files (list artr/file-grocery))
                               (org-super-agenda-groups
                                '((:auto-parent))))))) t)
Projekte
  (add-to-list 'org-agenda-custom-commands
               '("g5" "(5) Übersicht - Projekte"
                 ((stuck "" ((org-agenda-overriding-header "Stuck")))
                  (todo "TODO" ((org-agenda-overriding-header "offen")
                                (org-agenda-skip-function '(or (artr/skip-entry-if-tag "DAILY") (artr/skip-entry-if-tag "RECURRING")))
                                (org-super-agenda-groups
                                 '((:auto-property "Projekt")))))
                  (tags-todo "DAILY|+RECURRING|+TODO=\"NEXT\""
                             ((org-agenda-overriding-header "geplant")
                              (org-super-agenda-groups
                               '((:auto-property "Projekt")))))
                  (todo "DONE" ((org-agenda-overriding-header "erledigt")
                                (org-super-agenda-groups
                                 '((:auto-property "Projekt"))))))
                 ((org-agenda-files (list artr/file-projects)))) t)

Kategorien

Farben für Kategorien
  • Achtung: es wird jede Zeile eingefärbt, wenn sie nur das entsprechende Wort enthält. Das ist eventuell zu verbessern. Kann man dies auf Kategorie einschränken?
  (add-hook 'org-agenda-finalize-hook
            (lambda ()
              (save-excursion
                (color-org-header "Geburtstag:" "violet red")
                (color-org-header "Feiertag:" "orchid")
                (color-org-header "Ferien:" "medium orchid")
                )))
  (defun color-org-header (tag color)
    ""
    (interactive)
    (goto-char (point-min))
    (while (re-search-forward tag nil t)
      (add-text-properties (match-beginning 0) (point-at-eol) `(face (:foreground, color)))))

Breaking down Tasks

Checkbox
  (defun artr/org-checkbox-todo ()
    "Switch header TODO state to DONE when all checkboxes are ticked, to TODO otherwise"
    (let ((todo-state (org-get-todo-state)) beg end)
      (unless (not todo-state)
        (save-excursion
          (org-back-to-heading t)
          (setq beg (point))
          (end-of-line)
          (setq end (point))
          (goto-char beg)
          (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                                 end t)
              (if (match-end 1)
                  (if (equal (match-string 1) "100%")
                      (unless (string-equal todo-state "DONE")
                        (org-todo 'done))
                    (unless (string-equal todo-state "TODO")
                      (org-todo 'todo)))
                (if (and (> (match-end 2) (match-beginning 2))
                         (equal (match-string 2) (match-string 3)))
                    (unless (string-equal todo-state "DONE")
                      (org-todo 'done))
                  (unless (string-equal todo-state "TODO")
                    (org-todo 'todo)))))))))
  (add-hook 'org-checkbox-statistics-hook 'artr/org-checkbox-todo)
Todos
  (defun artr/org-summary-todo (n-done n-not-done)
    "Switch entry to DONE when all subentries are done, to TODO otherwise."
    (let (org-log-done org-log-states)   ; turn off logging
      (org-todo (if (= n-not-done 0) "DONE" "TODO"))))

  (add-hook 'org-after-todo-statistics-hook 'artr/org-summary-todo)

Einkaufsliste

  (defun artr/clean-grocery ()
    "Entfernt in der Datei grocery.org alle CLOSED-Einträge und Leerzeilen"
    (interactive)
    (save-window-excursion
      (find-file-at-point artr/file-grocery)
      (outline-next-heading)
      (flush-lines "CLOSED:.*")
      (flush-lines "^$")))

Erweiterungen

Org-Rifle

Org-Rifle stellt Funktionen zum Suchen in Org-Dateien zur Verfügung

  (use-package helm-org-rifle
    :ensure t
    :bind
    ("C-c r r" . helm-org-rifle)
    ("C-c r a" . helm-org-rifle-agenda-files)
    ("C-c r b" . helm-org-rifle-current-buffer)
    ("C-c r d" . helm-org-rifle-directories))

Org-Helm

Stellt folgende Funktionen zur Verfügung:

helm-org-agenda-files-headings
Suche in Überschriften aller Org-Agenda-Dateien
helm-org-in-buffer-headings
Suche in Überschriften der aktuellen Org-Datei
helm-org-capture-templates
Suche in Capture-Templates
  (use-package helm-org
    :ensure t
    :bind
    ("C-c f b" . helm-org-in-buffer-headings)
    ("C-c f a" . helm-org-agenda-files-headings)
    :init
    :config
    (add-to-list 'helm-completing-read-handlers-alist
                 '(org-capture . helm-org-completing-read-tags))
    (add-to-list 'helm-completing-read-handlers-alist
                 '(org-set-tags-command . helm-org-completing-read-tags))
    )

Org-Cliplink

Mit Org-Cliplink lassen sich URLs aus der Zwischenablage direkt als Link in ein Dokument einfügen. Die Beschreibung des Links ist der Titel der Webpage.

  (use-package org-cliplink
    :ensure t
    :bind ("C-x c i" . org-cliplink))

Org-Notmuch

Schnittstelle zu Notmuch. So lassen sich Links zu Emails erstellen. Achtung: Das Paket heißt jetzt ol-notmuch und nicht org-notmuch

  (use-package ol-notmuch
    :ensure nil
    :after org)

Org-CalDav

Ich übertrage meine Termine aus der Datei kalender.org in meinen Nextcloud-Klalender. Es gibt einen Familienkalender und jedes Familienmitglied hat seinen eigenen Kalender. Für den Tennisverein und die IGP gibt es jeweils einen eigenen Kalender.

  (use-package org-caldav
    :ensure t
    :init
    ;; This is the sync on close function; it also prompts for save after syncing so
    ;; no late changes get lost
    (defun org-caldav-sync-at-close ()
      (org-caldav-sync)
      (save-some-buffers))
    ;; This is the delayed sync function; it waits until emacs has been idle for
    ;; "secs" seconds before syncing.  The delay is important because the caldav-sync
    ;; can take five or ten seconds, which would be painful if it did that right at save.
    ;; This way it just waits until you've been idle for a while to avoid disturbing
    ;; the user.
    (defvar org-caldav-sync-timer nil
      "Timer that `org-caldav-push-timer' used to reschedule itself, or nil.")
    (defun org-caldav-sync-with-delay (secs)
      (when org-caldav-sync-timer
        (cancel-timer org-caldav-sync-timer))
      (setq org-caldav-sync-timer
            (run-with-idle-timer
             (* 1 secs) nil 'org-caldav-sync)))
    ;; Actual calendar configuration edit this to meet your specific needs
    (setq org-icalendar-timezone "Europe/Berlin")
    (setq org-caldav-url "https://cloud.troche.koeln/remote.php/dav/calendars/ariane")
    (setq org-caldav-exclude-tags ())
    (setq org-caldav-files ())
    (add-to-list 'org-caldav-exclude-tags "skip")
    (add-to-list 'org-caldav-files (concat artr/dir-home "calendar.org"))
    (setq org-caldav-calendars
          '((:calendar-id "ariane"
                          :inbox (concat org-directory "caldav/inbox-ariane.org")
                          :select-tags ("ariane"))
            (:calendar-id "markus"
                          :inbox (concat org-directory "caldav/inbox-markus.org")
                          :select-tags ("markus"))
            (:calendar-id "jonathan"
                          :inbox (concat org-directory "caldav/inbox-jonathan.org")
                          :select-tags ("jonathan"))
            (:calendar-id "philipp"
                          :inbox (concat org-directory "caldav/inbox-philipp.org")
                          :select-tags ("philipp"))
            (:calendar-id "kilian"
                          :inbox (concat org-directory "caldav/inbox-kilian.org")
                          :select-tags ("kilian"))
            (:calendar-id "familie"
                          :inbox (concat org-directory "caldav/inbox-familie.org")
                          :select-tags ("familie"))
            (:calendar-id "igp"
                          :inbox (concat org-directory "caldav/inbox-igp.org")
                          :select-tags ("igp"))
            (:calendar-id "tggwv"
                          :inbox (concat org-directory "caldav/inbox-tggwv.org")
                          :select-tags ("tggwv"))
            ))
    :config
    (setq org-icalendar-alarm-time 0)
    (setq org-caldav-save-directory "~/.emacs.d/caldav/"))
  ;; Add the delayed save hook with a five minute idle timer
  ;; (add-hook 'after-save-hook
  ;;          (lambda ()
  ;;            (when (eq major-mode 'org-mode)
  ;;              (org-caldav-sync-with-delay 300)))))

Org-Journal

Funktionen
Funktionen zur Berechnung eines Zeitwerts
  (defun iso-week-to-time (year week day)
    "Gibt zu m Input 'Jahr - Woche - Tag' den Internen Zeitwert zurück, gerechnet vom 01.01.1970"
    (pcase-let ((`(,m ,d ,y)
                 (calendar-gregorian-from-absolute
                  (calendar-iso-to-absolute (list week day year)))))
      (encode-time 0 0 0 d m y)))

  (defun iso-beginning-of-week (year week)
    "Gibt den internen Zeitwert zurück zum 1. Tag der angegebenen Woche und dem angegegbenen Jahr"
    (iso-week-to-time year week 1))

  (defun iso-end-of-week (year week)
    "Gibt den internen Zeitwert zurück zum 1. Tag der angegebenen Woche und dem angegegbenen Jahr"
    (iso-week-to-time year week 7))

  (defun iso-next-month ()
    (org-read-date nil t "+1m"))
Hilfsfunktionen zum Erzeugen der Titel
  (defun artr/journal-weekly-header (time)
    "Definiert den Titel für ein Weekly-Journal im Format 'Woche 04 (20.01-26.01.2020)'"
    (let ((week (string-to-number (format-time-string "%W" time)))
          (year (string-to-number (format-time-string "%Y" time))))
      (concat
       "#+TITLE: Journal: "
       (format-time-string "Woche %V (%d.%m-" (iso-beginning-of-week year week))
       (format-time-string "%d.%m.%Y)" (iso-end-of-week year week))
       "\n#+STARTUP: folded")))

  (defun artr/journal-monthly-header (time)
    "Definiert den Titel für ein Monthly-Journal im Format '2020 Februar'"
    (concat
     "#+TITLE: Journal: "
     (format-time-string "%Y - %B" time)
     "\n#+STARTUP: folded"))

  (defun artr/org-journal-file-header (time)
    "Definiert den Titel eines Journal-Eintrags."
    (concat
     (pcase org-journal-file-type
       (`daily "#+TITLE: Daily Journal\n#+STARTUP: showeverything")
       (`weekly (artr/journal-weekly-header time))
       (`monthly (artr/journal-monthly-header time))
       (`yearly "#+TITLE: Yearly Journal\n#+STARTUP: folded"))))
Jornal für nächsten Monat
Konfiguration

Org-Journal zum führen eines Tagebuchs. Ich habe pro Monat eine Datei. Ich nutze folgende Funktionen:

Key Aktion
C-c n j Neuer Eintrag mit aktuellem Zeitstempel
C-c n t Öffne Eintrag von heute und erzeuge einen neuen Eintrag
  (use-package org-journal
    :bind
    ("C-c n j" . org-journal-new-entry)
    ("C-c n t" . org-journal-today)
    :config
    (setq org-journal-dir artr/dir-journal
          org-journal-file-type 'monthly
          org-journal-file-format "journal-%Y-%m-%b.org"
          org-journal-carryover-items nil
          org-journal-date-format "%A, %d.%B %Y"
          org-journal-date-prefix "* ")
    (defun org-journal-today ()
      (interactive)
      (org-journal-new-entry t))
    (setq org-journal-file-header 'artr/org-journal-file-header))

Org-Books

  (use-package org-books
    :ensure t
    :init (setq org-books-file (concat artr/dir-gtd "books.org")))