grszkth.fr blog


My Doom Emacs configuration

Published: 25 Aug 2020
Updated: 09 Mar 2021
Table of Contents

Personal configuration file for Doom Emacs.

Me 🔗

You might know me, doom does not.

(setq user-full-name "Jonas D. Großekathöfer"
      user-mail-address "grszkthfr@outlook.com")

Font and appearance 🔗

I like to customize things. Here you can see how I did it for my editor of choice.

Font 🔗

monospace means to use system default font for code, i.e. monospaced fonts, and sans for variable pitch font.

(setq doom-font (font-spec :family "FiraCode" :size 18)
      doom-variable-pitch-font (font-spec :family "sans" :size 14))

Color theme 🔗

Actually, the color palette which initially inspired my website design, coming originally from here.

(setq doom-theme 'doom-gruvbox)

Transparency 🔗

Not used at the moment.

(set-frame-parameter nil 'alpha 50)

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")

Keybindings 🔗

Some modifications/additions to the given Keybindings.

Insert lines, without entering insert mode 🔗

New keybindings to insert a line below/above without entering insert mode, because [ SPC / ] SPC are hard to hard to reach for me on a German keyboard.

(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 🔗

I prefer the + to increase and = to reset the font size. Default is the other way round.

(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)))

Orgmode 🔗

Orgmode is at the moment my preferred tool to store notes and TODOs and organize my work in general.

General 🔗

This is the root of all evil, well organization.

Paths 🔗

(setq org-directory "~/org/"
      org-agenda-files (list
                        "~/org/"
                        ;; "~/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 🔗

Writing a book?

;; (use-package! ox-leanpub
;;   :after org)

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:

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 🔗

org-ref 🔗

org-ref provides rich support and information for citations in orgmode. Not needed at the moment + some trouble with initiation, therefore not active.

(use-package! org-ref
  :config
  (setq org-ref-completion-library 'org-ref-ivy-cite
        org-ref-get-pdf-filename-function 'org-ref-get-pdf-filename-ivy-bibtex
        org-ref-default-bibliography (list "~/meine-bibliothek/meine-bibliothek.bib")
        org-ref-bibliography-notes (concat org-directory "meine-bibliothek.org")
        ;; org-ref-note-title-format (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"
        ;;  "* Notes\n"
        ;;  ":PROPERTIES:\n"
        ;;  ":Custom_ID: ${=key=}\n"
        ;;  ":NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n"
        ;;  ":AUTHOR: ${author-abbrev}\n"
        ;;  ":JOURNAL: ${journaltitle}\n"
        ;;  ":DATE: ${date}\n"
        ;;  ":YEAR: ${year}\n"
        ;;  ":DOI: ${doi}\n"
        ;;  ":URL: ${url}\n"
        ;;  ":END:\n\n")
        org-ref-notes-directory (concat org-directory "zettelkasten/")
        org-ref-notes-function 'orb-edit-notes
        )
)

ivy-bibtex 🔗

The package of my choice (don’t ask why I choose ivy over helm 🤷). I got some headaches from the fact that you actually find ivy-bibtex in the helm-bibtex repository.

To configure it, tell Emacs where the .bib-files are and where the according pdf-files can be found.

(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"
       "* Notes\n"
       ":PROPERTIES:\n"
       ":Custom_ID: ${=key=}\n"
       ":NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n"
       ":AUTHOR: ${author-abbrev}\n"
       ":JOURNAL: ${journaltitle}\n"
       ":DATE: ${date}\n"
       ":YEAR: ${year}\n"
       ":DOI: ${doi}\n"
       ":URL: ${url}\n"
       ":END:\n\n"
       )
      bibtex-completion-format-citation-functions
      '((org-mode      . bibtex-completion-format-citation-org-link-to-PDF)
        (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
      bibtex-completion-cite-prompt-for-optional-arguments nil)

To see additional actions press M-o or C-o. Both is supposed2 to be a super handy ivy-thing to pop-up further options, such as open in other windows and useful stuff!

After opening ivy-action with C-o some options (highlighted) are given, but further options are possible but not shown. For now, I am not sure how to fix/improve this.

Key What
b Insert BibTex entry
a Attach PDF to email
e Edit notes
s Show entry
l Add PDF to library
f Fallback options
b Open the citation to the bibtex entry
u Open the citation URL
p Open the citation PDF (if it exists)
n Open the citation notes
c Open Web of Science citing articles
e Email the bibtex entry and pdf
f Copy a formatted entry string
g Open Google Scholar
w Copy the key at point
y Paste the key in an existing link

Hydra for ivy 🔗

Hydras for ivy are invoked with M-o. This section requires some more work to actually do what I want it to do.

(defun gkh-bibtex-completion-open-pdf-external (keys &optional fallback-action)
  (let ((bibtex-completion-pdf-open-function
         (lambda (fpath) (start-process "evince" "*helm-bibtex-evince*" "/usr/bin/evince" fpath))))
    (bibtex-completion-open-pdf keys fallback-action)))
;; throws error on startup
;; (ivy-bibtex-ivify-action gkh-bibtex-completion-open-pdf-external ivy-bibtex-open-pdf-external)

;; (ivy-add-actions
;;  'ivy-bibtex
;;  '(
;;    ("P" ivy-bibtex-open-pdf-external "Open PDF file in external viewer (if present)")
;;    )
;;  )

Choose from:

What How
Open PDF, URL or DOI ivy-bibtex-completion-open-any
Open PDF file (if present) ivy-bibtex-completion-open-pdf
Open URL or DOI in browser ivy-bibtex-completion-open-url-or-doi
Insert citation ivy-bibtex-completion-insert-citation
Insert reference ivy-bibtex-completion-insert-reference
Insert BibTeX key ivy-bibtex-completion-insert-key
Insert BibTeX entry ivy-bibtex-completion-insert-bibtex
Attach PDF to email ivy-bibtex-completion-add-PDF-attachment
Edit notes ivy-bibtex-completion-edit-notes
Show entry ivy-bibtex-completion-show-entry
Add PDF to library ivy-bibtex-completion-add-pdf-to-library

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" "ref" plain (function org-roam-capture--get-point)
           ""
           :file-name "${slug}"
           :head "#+TITLE: ${=key=}: ${title}\n#+ROAM_KEY: ${ref}

- tags ::
- keywords :: ${keywords}

\n* ${title}\n  :PROPERTIES:\n  :Custom_ID: ${=key=}\n  :URL: ${url}\n  :AUTHOR: ${author-or-editor}\n  :NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n  :NOTER_PAGE: \n  :END:\n\n"
           :unnarrowed t))))

🔗

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 🔗

🔗

(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)
  )

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.

;; ;; Load
;; (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)
;;          ))
;;   )

  1. https://orgmode.org/manual/Capture.html ↩︎

  2. Normally, I expected all options to be shown and then pick by key. However, ivy-hydra let’s you scroll through additional options with w and s↩︎