Updated: 05 Apr 2025
Note, I haven’t used Doom / my config below in a couple of years, as I have switched to a lightwight vanilla config.
Personal configuration file for Doom Emacs.
To get started from scratch, follow the instructions at
github.com/hlissner/doom-emacs#install and run doom sync.
Me 🔗
(setq user-full-name "Jonas D. Großekathöfer"
      user-mail-address "mail@grszkth.fr")
Font and appearance 🔗
Font 🔗
(setq doom-font (font-spec :family "FiraCode" :size 18)
      doom-variable-pitch-font (font-spec :family "sans" :size 14))
Color theme 🔗
(setq doom-theme 'doom-gruvbox)
Transparency 🔗
(set-frame-parameter nil 'alpha 75)
Line numbers 🔗
Use relative line numbers, but disable them for text buffer.
(setq display-line-numbers-type 'relative)
(remove-hook! 'text-mode-hook
  #'display-line-numbers-mode)
Spell checker 🔗
Default for the spell checker is english.
(setq ispell-dictionary "en")
Fill width 🔗
(setq fill-column 100)
Keybindings 🔗
Some modifications/additions to the given Keybindings.
Insert lines, without entering insert mode 🔗
(map! :leader
    ;;; <leader> i --- insert
    (:prefix-map ("i" . "insert")
    :desc "Insert line above"             "k"   #'+evil/insert-newline-above
    :desc "Insert line below"             "j"   #'+evil/insert-newline-below))
Increase and decrease font size 🔗
(map! :n "C-="    #'doom/reset-font-size
      ;; Buffer-local font resizing
      :n "C-+"    #'text-scale-increase
      :n "C--"    #'text-scale-decrease)
Avy 🔗
Navigating through emacs, across buffer.
(setq avy-all-windows t)
Workspace 🔗
Overwrite keybinding to quickly switch between workspaces by double TAB.
(map! :leader
      (:when (featurep! :ui workspaces)
       (:prefix-map ("TAB" . "workspace")
        :desc "Switch to last workspace"  "TAB"   #'+workspace/other)))
Dired 🔗
(use-package! dired
  :custom ((dired-listing-switches "-agho --group-directories-first")))
Orgmode 🔗
General 🔗
Paths 🔗
(setq org-directory "~/org/"
      org-agenda-files (list
                        "~/org/"
                        "~/org/jobs2021/"
                        "~/lehre/ws21_empra/"
                        "~/Documents/doktorarbeit/"
                        ;; "~/org/zettelkasten/"
                        "\.org$")
      org-archive-location (concat org-directory ".archive/%s::"))
Style 🔗
Styling of the appearance of my org buffer to please my liking.
First, define visual appearance for an org buffer.
(defun gkh/org-mode-visual()
  (setq visual-fill-column-width 100
        visual-fill-column-center-text t
        display-fill-column-indicator nil
        display-line-numbers nil)
  (visual-fill-column-mode 1))
Change symbol for folded headings and start with an overview of all headings when opening an org file.
(after! org
  (setq org-startup-folded 'overview
        org-ellipsis " ▾ "
        org-list-demote-modify-bullet '(("+" . "-") ("-" . "+"))))
(add-hook! 'org-mode-hook
           #'+org-pretty-mode #'mixed-pitch-mode #'gkh/org-mode-visual)
Font settings: Use different font sizes for headlines and define sections for a fixed-pitch font.
(after! org
  (custom-set-faces!
    '(org-document-title :height 1.3)
    '(org-level-1 :inherit outline-1 :weight extra-bold :height 1.4)
    '(org-level-2 :inherit outline-2 :weight bold :height 1.15)
    '(org-level-3 :inherit outline-3 :weight bold :height 1.12)
    '(org-level-4 :inherit outline-4 :weight bold :height 1.09)
    '(org-level-5 :inherit outline-5 :weight semi-bold :height 1.06)
    '(org-level-6 :inherit outline-6 :weight semi-bold :height 1.03)
    '(org-level-7 :inherit outline-7 :weight semi-bold)
    '(org-level-8 :inherit outline-8 :weight semi-bold)
    ;; Ensure that anything that should be fixed-pitch in org buffers appears
    ;; that way
    '(org-block nil :foreground nil :inherit 'fixed-pitch)
    '(org-code nil   :inherit '(shadow fixed-pitch))
    '(org-table nil   :inherit '(shadow fixed-pitch))
    '(org-verbatim nil :inherit '(shadow fixed-pitch))
    '(org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
    '(org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
    '(org-checkbox nil :inherit 'fixed-pitch)))
Timing is everything 🔗
This is a not very sophisticated way of handling TODOs.
(after! org
  (setq org-log-done 'time
        org-log-into-drawer 't
        org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d!)"    "CANCELLED(c@)"))
        org-todo-keyword-faces
        '(("TODO" :foreground "#7c7c75" :weight normal :underline t)
          ("WAITING" :foreground "#9f7efe" :weight normal :underline t)
          ("DONE" :foreground "#50a14f" :weight normal :underline t)
          ("CANCELLED" :foreground "#ff6480" :weight normal :underline t))))
Export settings 🔗
From ox-extra the headline tag :ignore: enables to export content without the
headline. Additionally the mimosis for thesis’ is made available as export
#+latex_class.
(after! ox
  (require 'ox-extra)
  (ox-extras-activate '(ignore-headlines)))
(use-package! ox-latex
  :after ox
  :init (setq org-latex-pdf-process
              '("%latex -interaction nonstopmode -output-directory %o %f"
                "bibtex %b"
                "%latex -interaction nonstopmode -output-directory %o %f"
                "%latex -interaction nonstopmode -output-directory %o %f"))
  :config
  ;; Mimosis is a class I used to write my Ph.D. thesis.
  (add-to-list 'org-latex-classes
               '("mimosis"
                 "\\documentclass{mimosis}
   [NO-DEFAULT-PACKAGES]
   [PACKAGES]
   [EXTRA]
  \\newcommand{\\mboxparagraph}[1]{\\paragraph{#1}\\mbox{}\\\\}
  \\newcommand{\\mboxsubparagraph}[1]{\\subparagraph{#1}\\mbox{}\\\\}"
                 ("\\chapter{%s}" . "\\chapter*{%s}")
                 ("\\section{%s}" . "\\section*{%s}")
                 ("\\subsection{%s}" . "\\subsection*{%s}")
                 ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                 ("\\mboxparagraph{%s}" . "\\mboxparagraph*{%s}")
                 ("\\mboxsubparagraph{%s}" . "\\mboxsubparagraph*{%s}"))))
  ;; (use-package! ox-leanpub
  ;;   :after org)
;; alternative org-latex-pdf-process?
(setq org-latex-pdf-process
      '("latexmk -pdflatex='pdflatex -shell-escape -interaction nonstopmode' -pdf -bibtex -f %f"))
Capture 🔗
From the documentation for capture1:
Capture lets you quickly store notes with little interruption of your work flow.
How does it do it?
It opens a mini-buffer (or so) where you can enter your note or to do entry.
Depending on what template you choose this note will be added to a certain .org
file to a certain heading (if wanted).
personal templates 🔗
My templates let me control to which file/heading a to do note goes. Below I have 3 types of notes:
- t for general or not-easy to sort notes
 - p for projects I am currently working on, it opens a menu for further
specification:
- m for my meta analysis
 - j for Julius master thesis
 - v for vrrl study
 
 - b for the browser extension, to capture
- l links to websites
 - q quotes from websites
 
 
For my templates to work I require these packages. I don’t know why, but I am
happy when it works.
(require 'org-protocol)
(require 'org-capture)
Here are the above mentioned templates specified.
(setq org-capture-templates
      '(("t" "todo" entry (file "~/org/todo.org")
         "* TODO %?")
        ("p" "projekte")
        ("pm" "Meta-Analyse Gaze cueing" entry (file+headline "~/org/projects.org" "ma_gazecueing" )
         "** TODO %?")
        ("pj" "Julius Masterarbeit" entry (file+headline "~/org/projects.org" "Lab-intern Meta-Analysis (Julius)" )
         "** TODO %?\n")
        ("pv" "vrrl" entry (file+headline "~/org/projects.org" "vrrl" )
         "** TODO %?")
        ("l" "lehre (ss20)" entry (file+headline    "~/org/zettelkasten/ss20empra.org" "orga" )
         "** TODO %?")
        ;; browser extension
        ("b" "browser extension")
        ("bq" "with quote" entry (file "~/org/todo.org")
         "* %^{Title}\nSource: %u, %c\n #+begin_quote\n%i\n#+END_QUOTE\n\n\n%?")
        ("bl" "only link" entry (file "~/org/todo.org")
         "* %? [[%:link][%:description]] :web:\nCaptured On: %U")))
Org-Roam 🔗
There is a lot of momentum around roam and note taking in general, and therefore although for org-roam. This is my basic configuration. For an general introduction I would start at org-roams documentation.
Although I am not yet a 100% sold, this is my configuration, taken unchanged from the docs.
(setq org-roam-directory (concat org-directory "zettelkasten/"))
For further reading and inspiration one can have a look here.
Browser extensions 🔗
See org-roam protocol how to setup your os and browser for the communication between org-roam and your browser.
Markdown 🔗
(defun gkh/md-mode-visual()
  (setq visual-fill-column-width 100
        visual-fill-column-center-text t
        display-fill-column-indicator nil
        markdown-header-scaling t
        display-line-numbers nil)
  (visual-fill-column-mode 1))
Change symbol for folded headings and start with an overview of all headings when opening an org file.
(add-hook! 'markdown-mode-hook #'gkh/md-mode-visual)
Bibliography 🔗
(setq bibtex-completion-bibliography "~/meine-bibliothek/meine-bibliothek.bib"
      bibtex-completion-library-path "~/meine-bibliothek/"
      bibtex-completion-notes-path (concat org-directory "zettelkasten/")
      ;; bibtex-completion-notes-template-multiple-files
      ;; (concat
      ;;  "${title}\n"
      ;;  "#+ROAM_KEY: cite:${=key=}\n"
      ;;  "#+ROAM_ALIAS: ${=key=} cite:${=key=}\n"
      ;;  ;; does not work, tags with spaces need "x"
      ;;  ;; "#+ROAM_TAGS: ${keywords}\n"
      ;;  "\n"
      ;;  "* Notes\n"
      ;;  ":PROPERTIES:\n"
      ;;  ":Custom_ID: ${=key=}\n"
      ;;  ":NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n"
      ;;  ":AUTHOR: ${author-abbrev}\n"
      ;;  ":JOURNAL: ${journal}\n"
      ;;  ":YEAR: ${year}\n"
      ;;  ":DOI: ${doi}\n"
      ;;  ":URL: ${url}\n"
      ;;  ":TIMESTAMP: ${timestamp}\n"
      ;;  ":END:\n\n"
      ;;  "** What\n"
      ;;  "** Why\n"
      ;;  "** How\n"
      ;;  "** And?")
      ;; bibtex-completion-format-citation-functions
      ;; '((org-mode      . org-ref-bibtex-completion-format-org)
      ;;   (latex-mode    . bibtex-completion-format-citation-cite)
      ;;   (markdown-mode . bibtex-completion-format-citation-pandoc-citeproc)
      ;;   (default       . bibtex-completion-format-citation-default))
      ;; ivy-bibtex-default-action 'ivy-bibtex-insert-citation
      ;; ;; no pre or post note
      ;; bibtex-completion-cite-prompt-for-optional-arguments nil
      ;; ;; how to open odfs
      ;; bibtex-completion-pdf-open-function (lambda (fpath) (call-process    "microsoft-edge" nil 0 nil fpath))
      ;; ;;
      ;; bibtex-completion-pdf-symbol "📰"
      ;; bibtex-completion-notes-symbol "🗒"
      ;; ;; bibtex-completion-pdf-symbol "⌘"
      ;; ;; bibtex-completion-notes-symbol "✎"
      )
org-roam-bibtex 🔗
This configures a nice integration of BibTex notes with an org-roam workflow.
;; (use-package! org-roam-bibtex
;;   :after (org-roam)
;;   :hook (org-roam-mode . org-roam-bibtex-mode)
;;   :config
;;   (setq org-roam-bibtex-preformat-keywords
;;         '("=key=" "title" "url" "file" "author-or-editor" "keywords"))
;;   (setq orb-templates
;;         '((\"r\" \"reference\" plain (function org-roam-capture--get-point)
;;            "#+ROAM_KEY: %^{=key=}%? %^{author} published %^{entry-type} in  %^{date}: fullcite:%\\1."
;;            :file-name "references/${=key=}"
;;            :head "#+title: ${title}"
;;            :unnarrowed t))))
R 🔗
If you do statistics with emacs you need ESS, which (also) has a mode for R.
Together with polymode, this is how I want my editor to handle and ease my work
with .R scripts and .RMD files.
ESS 🔗
-  Map nice and easy keybindings for assignment arrow 
<- -  get a function for the pipe 
%>%working & map nice keybindings 
R 🔗
(after! ess-mode
  (setq ess-style 'C++
        ;; don't wait when evaluating
        ess-eval-visibly-p 'nowait
        ;; scroll buffer to bottom
        comint-scroll-to-bottom-on-output t))
    ;; Open ESS R window to the left iso bottom.
        ;; (set-popup-rule! "^\\*R.*\\*$" :side 'left :size 0.38 :select nil :ttl nil :quit nil :modeline t)
- 
Pipe
I found a code snippet online. Not sure how I like it.
(defun gkh-r-add-pipe () (interactive) (end-of-line) (unless (looking-back "%>%" nil) (just-one-space 1) (insert "%>%")) (newline-and-indent)) 
- 
Rmarkdown snippet
And also found this snippet online.
(defun gkh-rmd-insert-r-chunk (header) "Insert an r-chunk in markdown mode. Necessary due to interactions between polymode and yas snippet" (interactive "sHeader: ") (insert (concat "```{r " header "}\n\n```")) (forward-line -1)) 
Julia 🔗
(setq lsp-julia-default-environment "~/.julia/environments/v1.0")
CSV 🔗
In german .csv-files often =,= is reserved as a decimal separator (as in 3,14),
consequently we need another column separator ;.
But now it splits the .csv-file at both separators. This is not helpful at all!
(setq csv-separators '("," "	" ";"))
Polymode 🔗
Polymode handles multiple modes in emacs. I need it to ease my work with
.Rmarkdown files, using markdown mode together with ESS. However, it does not
give me a nice time, so I prefer using org babel within emacs and fallback to
Rstudio regularly. I suspect, there are problem with the syntax checker…
Again I found this code-snippet, but I mainly keep it just in case to have it as a reference.
(use-package! poly-R
  :config
  (map! (:localleader
         :map polymode-mode-map
         :desc "Export"   "e" 'polymode-export
         :desc "Errors" "$" 'polymode-show-process-buffer
         :desc "Weave" "w" 'polymode-weave
         ;; (:prefix ("n" . "Navigation")
         ;;   :desc "Next" "n" . 'polymode-next-chunk
         ;;   :desc "Previous" "N" . 'polymode-previous-chunk)
         ;; (:prefix ("c" . "Chunks")
         ;;   :desc "Narrow" "n" . 'polymode-toggle-chunk-narrowing
         ;;   :desc "Kill" "k" . 'polymode-kill-chunk
         ;;   :desc "Mark-Extend" "m" . 'polymode-mark-or-extend-chunk)
         )))
Other inspriring configs 🔗
Dotfiles 🔗
Tangle all .org files in ~/.dotfiles/
(defun gkh/tangle-dotfiles ()
  "If the current file is in '~/.dotfiles', the code blocks are tangled"
  (when (equal (file-name-directory (directory-file-name buffer-file-name))
               (concat (getenv "HOME") "/.dotfiles/"))
    (org-babel-tangle)
    (message "%s tangled" buffer-file-name)))
  (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'gkh/tangle-dotfiles)))
.dir-locals.el 🔗 
Not sure, if this is a good idea, but in emacs one can apply settings for a
directory (recursively) with a .dir-locals.el file. I would like to
automatically tangle files on save.
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'gkh/tangle-dotfiles))))