doom-conf/config.org

14 KiB
Raw Blame History

Misc

Lexical bindings

Enable lexical binding, of course…

;;; -*- lexical-binding: t; -*-

Dir local variables

Disable these because I don't use them and don't want to get prompted by them in some projects.

(setq enable-dir-local-variables nil)

Theme

Main theme

A list of all doom themes can be found here:

https://github.com/hlissner/emacs-doom-themes

(setq doom-theme 'doom-solarized-light)

Dark theme toggle

I've come to prefer using a light theme during the day, and a dark theme at night. Using a dark theme with daylight leads to cranking up the screen brightness, which hurts my eyes more than using the light theme.

Set my light and dark themes:

(setq my/light-theme doom-theme
      my/dark-theme 'doom-one)

Function to toggle between the two easily:

(defun my/toggle-dark-theme ()
  (interactive)
  (if (eq my/dark-theme doom-theme)
      (load-theme my/light-theme t)
    (load-theme my/dark-theme t)))

Bind this to SPC t d:

(map! :leader
      (:prefix-map ("t" . "toggle")
       :desc "Dark theme" "d" #'my/toggle-dark-theme))

Font

Doom exposes five (optional) variables for controlling fonts in Doom. Here are the three important ones:

  • doom-font
  • doom-variable-pitch-font
  • doom-big-font used for doom-big-font-mode; use this for presentations or streaming.

They all accept either a font-spec, font string (Input Mono-12), or xlfd font string. You generally only need these two:

(setq doom-font
      (font-spec :family "Input Mono Narrow" :size 12 :style 'regular))

Line numbers

Possible values of display-line-numbers-type are nil, t, and 'relative.

(setq display-line-numbers-type nil)

Battery indicator

I'm on a laptop, so let's display my battery in the modeline:

(display-battery-mode 1)

Programming

Smart parens

Disable smart parens because half of the time it doesn't do what I want:

(remove-hook 'doom-first-buffer-hook #'smartparens-global-mode)

Rust

By default rustic-mode uses rls, I want to use rust-analyzer instead.

(setq rustic-lsp-server 'rust-analyzer)

I don't want to enable format-on-save globally in Doom, but having it in rust is nice.

(after! rustic
  (setq rustic-format-trigger 'nil))

rustfmt limits lines to 100 characters, let's display it correctly.

(add-hook! rustic-mode
  (set-fill-column 100))

C/C++

Default style

Setup the default format for C/C++ editing.

(add-hook! (c-mode c++-mode)
  (setq c-default-style "gnu")
  (setq c-basic-offset 2))

Flycheck

Flycheck never works well for C / C++ without configuration or a CMake build system. Let's disable it.

(after! flycheck
  (setq flycheck-global-modes '(not c-mode c++-mode)))

Org mode

Directory

Set a default directory for all my org-mode files.

(setq org-directory "~/org/")

Appearance

Disable fancy stars

(remove-hook 'org-mode-hook #'org-superstar-mode)

Don't hide leading stars

Currently doesn't work due to hlissner/doom-emacs#3076

(after! org
  (setq org-hide-leading-stars nil
        org-startup-indented nil
        org-adapt-indentation nil))

Fancier ellipsis indicator

(setq org-ellipsis " ▼ ")

Agenda setup

Default task keywords

Here are the keywords I'm using to track task progress. I'm also making use of some automatic state changes.

keyword meaning
TODO Self explanatory
DONE This task is finished, no longer displayed in the agenda
CANCELLED This task isn't finished but is no longer relevant
(after! org
  (setq org-todo-keywords
        '((sequence
           "TODO(t)"
           "|"
           "DONE(d!)"
           "CANCELLED(c@/!)")
          (sequence
           "[ ](T)"
           "|"
           "[X](D)"))))

Org capture setup

Of course I also need to setup capture templates:

The first one just prompts me for a new task to add to my inbox, I can then refile them where I want later.

The second one exists because I like to keep a separate list of articles / papers / books to read.

(after! org
  (setq org-capture-templates
        '(("t" "New entry" entry (file "inbox.org")
           "* TODO %?")
          ("T" "Task" entry (file "tasks.org")
           "* TODO %?")
          ("r" "Reading" entry (file "reading.org")
           "* TODO %x"
           :immediate-finish t)
          ("w" "Watching" entry (file "watching.org")
           "* TODO %x"
           :immediate-finish t))))

I also change the default Doom binding for #'org-capture to be SPC x instead of SPC X. Also need to rebind what was previously bound to SPC x, to SPC X.

(map! :leader
      :desc "Org Capture"           "x" #'org-capture
      :desc "Pop up scratch buffer" "X" #'doom/open-scratch-buffer)

Main agenda view

All these tasks, once captured, are then centralized in my agenda view.

I'm using multiple categories to organize tasks, depending on their triage / status (inspired by https://blog.jethro.dev/posts/org_mode_workflow_preview/).

(after! org-agenda
  (setq org-agenda-custom-commands
        '((" " "Agenda"
           ((agenda ""
                    ((org-agenda-span 'day)
                     (org-agenda-start-day nil)
                     (org-deadline-warning-days 365)))
            (todo "TODO"
                  ((org-agenda-overriding-header "Triage")
                   (org-agenda-files '("~/org/inbox.org"))))
            (todo "TODO"
                  ((org-agenda-overriding-header "School")
                   (org-agenda-files '(
                                       "~/org/image.org"
                                       "~/org/rdi.org"
                                       ))
                   (org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
                                                                        'scheduled))))
            (todo "TODO"
                  ((org-agenda-overriding-header "Assistant")
                   (org-agenda-files '("~/org/assistant.org"))
                   (org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
                                                                        'scheduled))))
            (todo "TODO"
                  ((org-agenda-overriding-header "Tasks")
                   (org-agenda-files '("~/org/tasks.org"))
                   (org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
                                                                        'scheduled))))
            (todo "TODO"
                  ((org-agenda-files '("~/org/watching.org"))
                   (org-agenda-overriding-header "To Watch")))
            (todo "TODO"
                  ((org-agenda-files '("~/org/reading.org"))
                   (org-agenda-overriding-header "To Read")))
            (todo "TODO"
                  ((org-agenda-files '("~/org/notes.org"))
                   (org-agenda-overriding-header "Note Taking")))
            (todo "TODO"
                  ((org-agenda-files '("~/org/project.org"))
                   (org-agenda-overriding-header "Personal projects")))
            )))))

I want the default agenda view to be a weekly view, with a log of what I've done during the day.

(after! org-agenda
  (setq org-agenda-span 'week)
  (setq org-agenda-start-on-weekday 1)
  (setq org-agenda-start-with-log-mode '(clock)))

I also remove the block separators in the agenda view:

(after! org-agenda
  (setq org-agenda-block-separator ""))

Habits

Let's enable the org-habit module:

(add-to-list 'org-modules 'org-habit)

Save all org buffers shortcut

By default bound to C-x C-s, rebind it to SPC m s in org-agenda-mode :

(map! :after org-agenda
      :map org-agenda-mode-map
      :localleader
      "s" #'org-save-all-org-buffers)

Org IDs

Org can link to entries using UUIDs, but we need the module to be loaded for links to work:

(add-to-list 'org-modules 'org-id)

Roam

Setup for org-roam.

Roam Directory

First, set a directory where org-roam will index things.

(setq org-roam-directory (expand-file-name "notes/" org-directory))

Graph browser

Instruct org-roam to use firefox-developer-edition to open the graph:

(setq org-roam-graph-viewer (executable-find "firefox-developer-edition"))

Roam link font face

Change link color for org-roam links, to distinguish them from standard Org links:

(after! org-roam
  (set-face-attribute 'org-roam-link nil :foreground "#FF8860"))

Roam capture template

Customize the capture templates:

  • the first one is the default one, I just removed the timestamp from the file title.
  • the second one I use to create new entries about website links, blog posts, articles… The %x in the template is replaced by the content of my X clipboard, so I just have to copy the website URL before capturing it.
(after! org-roam
  (setq org-roam-capture-templates
        '(("d" "default" plain (function org-roam-capture--get-point)
           "%?"
           :file-name "${slug}"
           :head "#+TITLE: ${title}\n"
           :unnarrowed t)
          ("i" "instant" plain (function org-roam-capture--get-point)
           "%?"
           :file-name "${slug}"
           :head "#+TITLE: ${title}\n"
           :unnarrowed t
           :immediate-finish t)
          ("w" "website" plain (function org-roam-capture--get-point)
           ""
           :file-name "websites/${slug}"
           :head "#+TITLE: ${title}\n#+ROAM_KEY: %x\n"
           :unnarrowed t)
          ("p" "paper" plain (function org-roam-capture--get-point)
           "%?"
           :file-name "papers/${slug}"
           :head "#+TITLE: ${title}\n"
           :unnarrowed t))))
Roam daily capture templates

Also setup daily captures templates, mainly used to store them in a journal/ directory instead of at the root.

(after! org-roam
  (setq org-roam-dailies-capture-templates
        '(("d" "daily" plain (function org-roam-capture--get-point)
           ""
           :immediate-finish t
           :file-name "journal/%<%Y-%m-%d>"
           :head "#+TITLE: %<%Y-%m-%d>"))))

Org Roam Server

org-roam-server provides a fancy JS interface to visualize the graph. Just needs to be loaded, along with its dependency simple-httpd.

(use-package! simple-httpd)
(use-package! org-roam-server)

Export backends

Sometimes I need to export an Org subtree to a file, which is quite easy with the org export backend. It doesn't seem to be enabled by default, so let's add it to the list:

(after! org
  (add-to-list 'org-export-backends 'org))

Doom specific

Doom replaces the default tab behavior on headings, this restores the default one. Taken from here.

(after! evil-org
  (remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h))