This is my literate doom emacs config.
Basic sets up some basic emacs and doom configurations.
Doom Modules contains the configuration all packages and tries to mirror the structure of doom’s init.el
.
- Each top-level heading under doom modules corresponds to a Doom module category (e.g., :lang, ui), as declared in the
doom!
macro ininit.el
. - Each second-level heading corresponds to an individual module within that category (e.g., org, modeline).
- Each third-level heading represents any flags applied to that module (e.g., +pretty, +roam2), which alter the module’s behavior or dependencies.
- Subsequent headings:
- Core packages enabled by those flags (e.g., org-modern)
- Manually installed packages related to that module (e.g., org-modern-indent)
- Configuration snippets or tweaks logically grouped by package or functionality
Make this file run slightly faster (see this blog post).
;;; config.el -*- lexical-binding: t; -*-
Make emacs faster.
(use-package! gcmh
:init
(setq gcmh-idle-delay 5
gcmh-high-cons-threshold (* 256 1024 1024)) ; 256MB during idle
:config
(gcmh-mode 1))
(setq gc-cons-threshold 200000000) ; previous 33554432
;; credentials
(setq user-full-name "Michael Neuper"
user-mail-address "michael@michaelneuper.com")
;; autosave and backup
(setq auto-save-default t
make-backup-files t)
;; kill emacs without confiming
(setq confirm-kill-emacs nil)
;; remap <localleader> from SPC m to SPC l
(setq doom-localleader-key "SPC l"
doom-localleader-alt-key "M-SPC l")
Some which-key
adjustments.
(use-package! which-key
:init
(setq which-key-idle-delay 0.5
which-key-allow-multiple-replacements t)
:config
(which-key-mode 1)
;; copied from https://tecosaur.github.io/emacs-config/config.html#which-key
(pushnew!
which-key-replacement-alist
'(("" . "\\`+?evil[-:]?\\(?:a-\\)?\\(.*\\)") . (nil . "◂\\1"))
'(("\\`g s" . "\\`evilem--?motion-\\(.*\\)") . (nil . "◃\\1"))))
Some macOS specific settings.
- For better font rendering on macos run
defaults write org.gnu.Emacs AppleFontSmoothing -int 0
- To revert run
defaults delete org.gnu.Emacs AppleFontSmoothing
(if (featurep :system 'macos)
(setq mac-command-modifier 'meta
mac-option-modifier 'none
mac-right-option-modifier 'super
ns-use-proxy-icon nil ; disable file icon in titlebar
ns-use-native-fullscreen t))
Use the gruvbox theme and set some fonts.
The fonts need to be installed on your machine and make sure to run M-x nerd-icons-install-fonts
.
(setq doom-theme 'doom-gruvbox)
(if (featurep :system 'macos)
(progn
(defconst my/serif-font "New York")
(defconst my/sans-serif-font "SF Pro")
(defconst my/mono-font "SF Mono"))
(progn
(defvar my/serif-font "Latin Modern Roman")
(defvar my/sans-serif-font "Inter")
(defvar my/mono-font "JetBrainsMono Nerd Font")))
(setq doom-font (font-spec :family my/mono-font :size 15)
doom-variable-pitch-font (font-spec :family my/serif-font)
doom-emoji-font (font-spec :family "Apple Color Emoji"))
Enable relative line numbers and make their slant normal (not italic).
;; FIXME incorrect numbers when org headings are folded
(setq display-line-numbers-type 'relative)
(setq-default line-spacing 0.1)
(add-hook! display-line-numbers-mode
(custom-set-faces!
'((line-number line-number-current-line)
:slant normal)))
Only highlight the current line in programming modes and dired
.
(setq global-hl-line-modes '(prog-mode dired-mode))
Display a fill indicator at 80 characters in prog-mode
.
;; (setq display-fill-column-indicator-column 80)
;; (add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)
Start emacs in a 100x40 window.
(add-to-list 'default-frame-alist '(width . 100))
(add-to-list 'default-frame-alist '(height . 40))
Format the title.
;; copied from https://hieuphay.com/doom-emacs-config/#some-good-defaults
;; (setq frame-title-format
;; '(""
;; (:eval
;; (if (s-contains-p org-roam-directory (or buffer-file-name ""))
;; (replace-regexp-in-string
;; ".*/[0-9]*-?" "☰ "
;; (subst-char-in-string ?_ ? buffer-file-name))
;; "%b"))
;; (:eval
;; (let ((project-name (projectile-project-name)))
;; (unless (string= "-" project-name)
;; (format (if (buffer-modified-p) " ◉ %s" " ● %s") project-name))))))
(setq frame-title-format '("" (:eval buffer-name) "%b"))
Disable corfu’s auto-popups and preselect the first candidate.
(after! corfu
(setq corfu-auto nil
corfu-preselect 'first
+corfu-want-tab-prefer-expand-snippets t))
Add keybindings for copilot and copilot-chat with <leader> e prefix.
(after! (evil copilot)
(evil-define-key 'insert 'global (kbd "<tab>") 'copilot-accept-completion))
(map! :leader
(:prefix ("e" . "copilot")
:desc "Enable Copilot Mode"
"c" #'copilot-mode
:desc "Display Chat Window"
"d" #'copilot-chat-display
:desc "Explain Selected Code"
"e" #'copilot-chat-explain
:desc "Review Selected Code"
"r" #'copilot-chat-review
:desc "Fix Selected Code"
"f" #'copilot-chat-fix
:desc "Optimize Selected Code"
"o" #'copilot-chat-optimize
:desc "Write Test for Code"
"t" #'copilot-chat-test
:desc "Add Current Buffer"
"a" #'copilot-chat-add-current-buffer
:desc "Document Selected Code"
"D" #'copilot-chat-doc
:desc "Reset Chat History"
"R" #'copilot-chat-reset
:desc "Remove Current Buffer"
"x" #'copilot-chat-del-current-buffer))
Quickly search and filter through +roam2 notes.
(after! deft
(setq deft-recursive t
deft-use-filter-string-for-filename t
deft-default-extension "org"
deft-directory org-roam-directory))
(map! :leader
:prefix "r"
:desc "Search with deft"
"s" #'deft)
Remove the shortmenu and footer from the dashboard.
(remove-hook! '+doom-dashboard-functions
#'doom-dashboard-widget-shortmenu
#'doom-dashboard-widget-footer)
Add a random custom message along with the emacs icon in the footer like the dashboard package.
Also disable modeline, hl-line-mode
, and enable read-only-mode
.
;; copied from https://github.com/emacs-dashboard/emacs-dashboard/blob/master/dashboard-widgets.el
(defcustom my/dashboard-footer-messages
'("The one true editor, Emacs!"
"Who the hell uses VIM anyway? Go Evil!"
"Free as free speech, free as free Beer"
"Happy coding!"
"Vi Vi Vi, the editor of the beast"
"Welcome to the church of Emacs"
"While any text editor can save your files, only Emacs can save your soul"
"I showed you my source code, pls respond")
"A list of messages, one of which dashboard chooses to display.")
(add-hook! '+doom-dashboard-functions :append
(let* ((icon (propertize #(" " 0 1 (display (height 1.5))) 'face `(:foreground ,(doom-color 'grey))))
(msg (nth (random (length my/dashboard-footer-messages))
my/dashboard-footer-messages))
(line (concat icon msg)))
(insert "\n" (+doom-dashboard--center +doom-dashboard--width line) "\n"))
(setq mode-line-format nil)
(hl-line-mode 0)
(read-only-mode +1))
(setq-hook! '+doom-dashboard-mode-hook evil-normal-state-cursor (list nil))
Set a custom ascii banner for when emacs is used in the terminal, and a splash image for GUI mode.
;; modified from https://discourse.doomemacs.org/t/how-to-change-your-splash-screen/57
(defun my-weebery-is-always-greater ()
(let* ((banner '("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀"
"⢸⠉⣹⠋⠉⢉⡟⢩⢋⠋⣽⡻⠭⢽⢉⠯⠭⠭⠭⢽⡍⢹⡍⠙⣯⠉⠉⠉⠉⠉⣿⢫⠉⠉⠉⢉⡟⠉⢿⢹⠉⢉⣉⢿⡝⡉⢩⢿⣻⢍⠉⠉⠩⢹⣟⡏⠉⠹⡉⢻⡍⡇"
"⢸⢠⢹⠀⠀⢸⠁⣼⠀⣼⡝⠀⠀⢸⠘⠀⠀⠀⠀⠈⢿⠀⡟⡄⠹⣣⠀⠀⠐⠀⢸⡘⡄⣤⠀⡼⠁⠀⢺⡘⠉⠀⠀⠀⠫⣪⣌⡌⢳⡻⣦⠀⠀⢃⡽⡼⡀⠀⢣⢸⠸⡇"
"⢸⡸⢸⠀⠀⣿⠀⣇⢠⡿⠀⠀⠀⠸⡇⠀⠀⠀⠀⠀⠘⢇⠸⠘⡀⠻⣇⠀⠀⠄⠀⡇⢣⢛⠀⡇⠀⠀⣸⠇⠀⠀⠀⠀⠀⠘⠄⢻⡀⠻⣻⣧⠀⠀⠃⢧⡇⠀⢸⢸⡇⡇"
"⢸⡇⢸⣠⠀⣿⢠⣿⡾⠁⠀⢀⡀⠤⢇⣀⣐⣀⠀⠤⢀⠈⠢⡡⡈⢦⡙⣷⡀⠀⠀⢿⠈⢻⣡⠁⠀⢀⠏⠀⠀⠀⢀⠀⠄⣀⣐⣀⣙⠢⡌⣻⣷⡀⢹⢸⡅⠀⢸⠸⡇⡇"
"⢸⡇⢸⣟⠀⢿⢸⡿⠀⣀⣶⣷⣾⡿⠿⣿⣿⣿⣿⣿⣶⣬⡀⠐⠰⣄⠙⠪⣻⣦⡀⠘⣧⠀⠙⠄⠀⠀⠀⠀⠀⣨⣴⣾⣿⠿⣿⣿⣿⣿⣿⣶⣯⣿⣼⢼⡇⠀⢸⡇⡇⠇"
"⢸⢧⠀⣿⡅⢸⣼⡷⣾⣿⡟⠋⣿⠓⢲⣿⣿⣿⡟⠙⣿⠛⢯⡳⡀⠈⠓⠄⡈⠚⠿⣧⣌⢧⠀⠀⠀⠀⠀⣠⣺⠟⢫⡿⠓⢺⣿⣿⣿⠏⠙⣏⠛⣿⣿⣾⡇⢀⡿⢠⠀⡇"
"⢸⢸⠀⢹⣷⡀⢿⡁⠀⠻⣇⠀⣇⠀⠘⣿⣿⡿⠁⠐⣉⡀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⠳⠄⠀⠀⠀⠀⠋⠀⠘⡇⠀⠸⣿⣿⠟⠀⢈⣉⢠⡿⠁⣼⠁⣼⠃⣼⠀⡇"
"⢸⠸⣀⠈⣯⢳⡘⣇⠀⠀⠈⡂⣜⣆⡀⠀⠀⢀⣀⡴⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢽⣆⣀⠀⠀⠀⣀⣜⠕⡊⠀⣸⠇⣼⡟⢠⠏⠀⡇"
"⢸⠀⡟⠀⢸⡆⢹⡜⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⣾⡏⡇⡎⡇⠀⡇"
"⢸⠀⢃⡆⠀⢿⡄⠑⢽⣄⠀⠀⠀⢀⠂⠠⢁⠈⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠄⡐⢀⠂⠀⠀⣠⣮⡟⢹⣯⣸⣱⠁⠀⡇"
"⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁"))
(longest-line (apply #'max (mapcar #'length banner))))
(put-text-property
(point)
(dolist (line banner (point))
(insert (+doom-dashboard--center
+doom-dashboard--width
(concat line (make-string (max 0 (- longest-line (length line))) 32)))
"\n"))
'face 'doom-dashboard-banner)))
(setq +doom-dashboard-ascii-banner-fn #'my-weebery-is-always-greater
fancy-splash-image (concat doom-private-dir "images/logo.svg"))
Make the modeline look a bit nicer.
(remove-hook 'doom-modeline-mode-hook #'size-indication-mode)
(after! doom-modeline
;; see https://github.com/seagle0128/doom-modeline?tab=readme-ov-file#customize
(setq doom-modeline-buffer-file-name-style 'auto
doom-modeline-always-show-macro-register t
doom-modeline-enable-word-count nil
doom-modeline-buffer-encoding t
doom-modeline-major-mode-icon t
doom-modeline-buffer-modification-icon nil
doom-modeline-bar-width 0
doom-modeline-height 30
doom-modeline-modal nil
doom-modeline-spc-face-overrides `(:family ,my/mono-font))
(setq mode-line-right-align-edge 'right-fringe)
;; see https://discourse.doomemacs.org/t/how-to-switch-customize-or-write-themes/37#tweak-the-current-theme-3
(custom-set-faces!
`(doom-modeline-buffer-file
:foreground ,(doom-color 'fg-alt)
:family ,my/sans-serif-font)
`(mode-line
:background ,(doom-color 'bg)
:foreground ,(doom-color 'fg-alt)
:overline ,(doom-color 'base4)
:family ,my/sans-serif-font)
`(mode-line-inactive
:overline ,(doom-color 'base4)
:family ,my/sans-serif-font
:box nil)
`(mode-line-active
:foreground ,(doom-color 'fg-alt)
:box nil)
'(header-line
:overline nil)))
We expect the file encoding to be LF UTF-8
so, only display it in modeline when it’s something else.
;; copied from https://tecosaur.github.io/emacs-config/config.html#file-encoding
(defun doom-modeline-conditional-buffer-encoding ()
"We expect the encoding to be LF UTF-8, so only show the modeline when this is not the case"
(setq-local doom-modeline-buffer-encoding
(unless (and (memq (plist-get (coding-system-plist buffer-file-coding-system) :category)
'(coding-category-undecided coding-category-utf-8))
(not (memq (coding-system-eol-type buffer-file-coding-system) '(1 2))))
t)))
(add-hook 'after-change-major-mode-hook #'doom-modeline-conditional-buffer-encoding
F438
)
Change the filename showed in the modline in an org-roam
buffer to be (<date>) <name>.org
.
Only relevant if you have +roam2.
;; TODO show the name of the note instead of the name of the file
;; modified from https://tecosaur.github.io/emacs-config/config.html#modeline-file-name
;; (defadvice! doom-modeline--buffer-file-name-roam-aware-a (orig-fun)
;; :around #'doom-modeline-buffer-file-name ; takes no args
;; (if (string-match-p (regexp-quote org-roam-directory) (or buffer-file-name ""))
;; (replace-regexp-in-string
;; "\\(?:^\\|.*/\\)\\([0-9]\\{4\\}\\)\\([0-9]\\{2\\}\\)\\([0-9]\\{2\\}\\)[0-9]*-"
;; "(\\1-\\2-\\3) "
;; (subst-char-in-string ?_ ? buffer-file-name))
;; (funcall orig-fun)))
Disable tabs by default and make them toggleable.
(use-package! centaur-tabs
:init
(remove-hook 'doom-first-file-hook #'centaur-tabs-mode)
(when (daemonp)
(remove-hook 'server-after-make-frame-hook #'centaur-tabs-mode))
(map! :leader
:prefix "t"
:desc "Tabs"
"t" #'centaur-tabs-mode
:desc "Local tabs"
"T" #'centaur-tabs-local-mode)
:config
(centaur-tabs-change-fonts my/sans-serif-font 140)
:bind
(:map evil-normal-state-map
("g t" . centaur-tabs-forward)
("g T" . centaur-tabs-backward)))
(after! unicode
(if (featurep :system 'macos)
(setq doom-symbol-font (font-spec :family "Symbola"))))
Use doom-variable-pitch-font
in the following modes:
org-mode
org-roam-mode
(only relevant if you have +roam2)LaTeX-mode
(only relevant if you have latex)doom-docs-org-mode
;; modified from https://discourse.doomemacs.org/t/cant-size-doom-variable-pitch-font/4572/2
(use-package! mixed-pitch
:hook ((org-mode . mixed-pitch-mode)
(org-roam-mode . mixed-pitch-mode)
(LaTeX-mode . mixed-pitch-mode)
(doom-docs-org-mode . mixed-pitch-mode))
:config
(setq mixed-pitch-set-height t
variable-pitch-serif-font doom-variable-pitch-font)
(pushnew! mixed-pitch-fixed-pitch-faces
'warning
'org-drawer 'org-cite-key 'org-list-dt 'org-hide
'corfu-default 'font-latex-math-face)
(set-face-attribute 'variable-pitch nil :height 1.1))
Reduce text indent in org
buffers caused by mixed-pitch-mode
.
;; copied from https://tecosaur.github.io/emacs-config/config.html#reduced-text-indent
(defadvice! +org-indent--reduced-text-prefixes ()
:after #'org-indent--compute-prefixes
(setq org-indent--text-line-prefixes
(make-vector org-indent--deepest-level nil))
(when (> org-indent-indentation-per-level 0)
(dotimes (n org-indent--deepest-level)
(aset org-indent--text-line-prefixes
n
(org-add-props
(concat (make-string (* n (1- org-indent-indentation-per-level))
?\s)
(if (> n 0)
(char-to-string org-indent-boundary-char)
"\u200b"))
nil 'face 'org-indent)))))
;; TODO use unicode symbols for [1], [2], ...
(after! persp-mode
(custom-set-faces!
`(+workspace-tab-face
:family ,my/sans-serif-font)
`(+workspace-tab-selected-face
:box (:color ,(doom-color 'fg-alt)
:line-width 1
:style nil)
:background ,(doom-color 'fg-alt)
:foreground ,(doom-color 'bg-alt)
:family ,my/sans-serif-font
:weight bold)))
Add padding to emacs frames and windows with spacious-padding.
;; https://protesilaos.com/emacs/spacious-padding
(use-package! spacious-padding
:ensure t
:config
(setq spacious-padding-widths
'( :internal-border-width 20
:header-line-width 8
:mode-line-width 8
:tab-width 4 ;; ?
:right-divider-width 15
:left-fringe-width 8))
(spacious-padding-mode 1))
Set some evil
variables.
(after! evil
(setq evil-move-cursor-back nil ; don't move the block cursor when toggling insert mode
evil-kill-on-visual-paste nil ; don't put overwritten text in the kill ring
evil-want-fine-undo t
evil-move-beyond-eol t
+evil-want-o/O-to-continue-comments nil))
Set quick-access-entries
for dirvish
.
Ensure these programs are installed to enable file previews.
(setq dired-mouse-drag-files t
mouse-drag-and-drop-region-cross-program t)
(after! dired-x
(setq dired-omit-files ; hide "dotfiles"
(concat dired-omit-files "\\|^\\..*$")))
(after! dirvish
(setq dirvish-attributes
(append
'(vc-state subtree-state nerd-icons collapse)
'(git-msg file-size)))
(setq! dirvish-quick-access-entries
`(("h" "~/" "Home")
("c" "~/Developer/" "Code")
("d" "~/Downloads/" "Downloads")
("g" "~/GitHub/" "GitHub")
("t" "~/.Trash/" "Trash")
("o" "~/OneDrive - Stellenbosch University/" "OneDrive")
;; - `scp` ensures large files are transferred out of band
;; via `scp` rather than encoded in the shell session.
;; - `x` ensures the session is opened with `/bin/sh -i`
;; via `-o RemoteCommand`.
("n" "/scpx:NARGA:" "NARGA"))))
(map! :leader
:prefix "o"
:desc "Dirvish Quick Access"
"q" #'dirvish-quick-access)
(after! dape
(setq dape-breakpoint-margin-string "●")) ;; or use •
(after! gptel
(setq gptel-model '4o
gptel-backend (gptel-make-gh-copilot "Copilot")
gptel-default-mode 'org-mode))
Change some of eglot
’s faces.
(after! eglot
(custom-set-faces!
`(eglot-inlay-hint-face
:foreground ,(doom-color 'base5)
:family ,my/sans-serif-font)))
Improve eglot
performance.
NOTE: Requires building emacs-lsp-booster.
(use-package! eglot-booster
:after eglot
:config (eglot-booster-mode))
;; TODO add continuous scroll
(add-hook 'pdf-view-mode-hook #'pdf-view-midnight-minor-mode)
(map! :map pdf-view-mode-map
:localleader
(:prefix ("h" . "history")
:desc "Go forward in history"
"f" #'pdf-history-forward
:desc "Go backward in history"
"b" #'pdf-history-backward))
Set indentation level for cc-mode
to 2 and fix issue where two new lines are inserted after {
.
(after! cc-mode
(setq c-basic-offset 2))
(add-hook! c-mode
(c-toggle-auto-newline -1))
Set indentation level for java-mode
to 2.
(after! java-mode
(setq c-basic-offset 2))
Requires lsp +eglot and requires pyright
to be installed on your machine.
Install with npm install -g pyright
.
(after! eglot
(add-to-list 'eglot-server-programs '(python-mode . ("pyright-langserver" "--stdio"))))
(add-hook! python-mode
(setq python-shell-interpreter "python3.11"
doom-modeline-env-python-executable "python3.11"))
My CDLaTeX templates.
(after! cdlatex
(map! :map cdlatex-mode-map
:i "TAB" #'cdlatex-tab)
(setq cdlatex-math-symbol-alist ; expand when prefixed with `
;; TODO change prefix key to something like ;
'((?e ("\\varepsilon" "\\epsilon"))
(?f ("\\varphi" "\\phi"))
(?0 ("\\varnothing" "\\emptyset"))
(?> ("\\to" "\\implies"))
(?= ("\\iff" "\\equiv"))
(?| ("\\mid" "\\vert"))
(?: ("\\coloneqq")))
cdlatex-math-modify-alist ; modify text with '
'((?b "\\mathbb" nil t nil nil)
(?c "\\mathcal" nil t nil nil)
(?f "\\mathbf" nil t nil nil)
(?m "\\mathrm" nil t nil nil)
(?r "\\mathrel" nil t nil nil)
(?s "\\mathsf" nil t nil nil)
(?o "\\operatorname" nil t nil nil))
cdlatex-command-alist ; expand with <TAB>
'(("eqn" "Insert an EQUATION* environment template" "" cdlatex-environment ("equation*") t nil)
("aln" "Insert an ALIGN* environment template" "" cdlatex-environment ("align*") t nil)
("sum" "Insert \\sum\\limits_{}^{}" "\\sum\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("prod" "Insert \\prod\\limits_{}^{}" "\\prod\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("bun" "Insert \\bigcup\\limits_{}^{}" "\\bigcup\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("bin" "Insert \\bigcap\\limits_{}^{}" "\\bigcap\\limits_{?}^{}" cdlatex-position-cursor nil nil t)
("lim" "Insert \\lim_\\limits{{} \\to {}}" "\\lim_\\limits{{?} \\to {}}" cdlatex-position-cursor nil nil t)
("sr" "Insert {}^2" "{?}^2" cdlatex-position-cursor nil nil t)
("cb" "Insert {}^3" "{?}^3" cdlatex-position-cursor nil nil t)
("op" "Insert \\operatorname{}()" "\\operatorname{?}()" cdlatex-position-cursor nil nil t))))
Set some org
variables.
(setq org-directory "~/Documents/Org"
org-use-property-inheritance t ; fix weird issue with src blocks
org-startup-with-inline-images t
org-edit-src-content-indentation 0)
;; FIXME blurry previews when using #+attr_org: :width
;; (setq org-image-actual-width (/ (display-pixel-width) 3)) ; set images to a third of the width of the screen
;; org-image-actual-width (min (/ (display-pixel-width) 3) 800)
Customise org
faces to for links and src blocks and scale headings.
(after! org
(custom-set-faces!
`((org-link)
:weight normal
:underline nil)
;; `((highlight)
;; :underline t
;; :foreground nil
;; :foreground ,(face-attribute 'highlight :background)
;; :background nil)
;; scale headings
`((org-document-title)
:foreground ,(doom-color 'fg)
:height 1.3 :weight bold)
`((org-level-1)
;; :foreground ,(doom-color 'green)
:foreground ,(face-attribute 'outline-1 :foreground)
:height<
EE86
/span> 1.1 :weight medium)
`((org-level-2)
;; :foreground ,(doom-color 'yellow)
:foreground ,(face-attribute 'outline-2 :foreground)
:weight medium)
`((org-level-3)
;; :foreground ,(doom-color 'dark-yellow)
:foreground ,(face-attribute 'outline-3 :foreground)
:weight medium)
`((org-level-4)
;; :foreground ,(doom-color 'orange)
:foreground ,(face-attribute 'outline-4 :foreground)
:weight medium)
`((org-level-5)
;; :foreground ,(doom-color 'red)
:foreground ,(face-attribute 'outline-5 :foreground)
:weight medium)))
Use native highlighting for LaTeX
related syntax in org
buffers.
By using native highlighting the org-face
gets added which we want to avoid.
(setq org-highlight-latex-and-related '(native script))
(after! org-src
(add-to-list 'org-src-block-faces
`("latex" (:background ,(doom-color 'bg)
:extend t))))
Enable evil-tex-mode
in LaTeX source blocks.
Requires latex and evil to be enabled.
(add-hook! 'org-src-mode-hook
(when (string= major-mode "latex-mode")
(evil-tex-mode 1)))
Set up LaTeX
previews in org
buffers.
;; TODO enable latex previews in org-roam and latex buffers (use xenops)
(after! org
(dolist (pkg '("amsmath" "amssymb" "mathtools" "mathrsfs"))
(add-to-list 'org-latex-packages-alist `("" ,pkg t))))
;; modified from https://abode.karthinks.com/org-latex-preview/
(use-package! org-latex-preview
:after org
:hook (org-mode . org-latex-preview-auto-mode)
:init (setq org-startup-with-latex-preview t)
:config
(plist-put org-latex-preview-appearance-options
;; :page-width 0.8)
:page-width 1.0)
(setq org-latex-preview-auto-ignored-commands
'(next-line previous-line mwheel-scroll ultra-scroll
scroll-up-command scroll-down-command
evil-scroll-up evil-scroll-down evil-scroll-line-up evil-scroll-line-down)
org-latex-preview-numbered t
org-latex-preview-live t
org-latex-preview-live-debounce 0.25)
;; code for centering LaTeX previews -- a terrible idea
(defun my/org-latex-preview-uncenter (ov)
(overlay-put ov 'before-string nil))
(defun my/org-latex-preview-recenter (ov)
(overlay-put ov 'before-string (overlay-get ov 'justify)))
(defun my/org-latex-preview-center (ov)
(save-excursion
(goto-char (overlay-start ov))
(when-let* ((elem (org-element-context))
((or (eq (org-element-type elem) 'latex-environment)
(string-match-p "^\\\\\\[" (org-element-property :value elem))))
(img (overlay-get ov 'display))
(prop `(space :align-to (- center (0.55 . ,img))))
(justify (propertize " " 'display prop 'face 'default)))
(overlay-put ov 'justify justify)
(overlay-put ov 'before-string (overlay-get ov 'justify)))))
(define-minor-mode org-latex-preview-center-mode
"Center equations previewed with `org-latex-preview'."
:global nil
(if org-latex-preview-center-mode
(progn
(add-hook 'org-latex-preview-overlay-open-functions
#'my/org-latex-preview-uncenter nil :local)
(add-hook 'org-latex-preview-overlay-close-functions
#'my/org-latex-preview-recenter nil :local)
(add-hook 'org-latex-preview-overlay-update-functions
#'my/org-latex-preview-center nil :local))
(remove-hook 'org-latex-preview-overlay-close-functions
#'my/org-latex-preview-recenter)
(remove-hook 'org-latex-preview-overlay-update-functions
#'my/org-latex-preview-center)
(remove-hook 'org-latex-preview-overlay-open-functions
#'my/org-latex-preview-uncenter))))
Some eye candy in org
buffers provided.
;; modified from https://sophiebos.io/posts/beautifying-emacs-org-mode/
(after! org-modern
(setq org-auto-align-tags t
org-tags-column 0
org-fold-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
org-modern-table nil
org-modern-todo nil
org-modern-priority nil
org-modern-progress 6
;; agenda
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"⭠ now ─────────────────────────────────────────────────"
;; text replacements
org-modern-fold-stars
`(("◉" . "○" )
("◈" . "◇" )
("◉" . "○" )
("◈" . "◇" )
("◉" . "○" ))
org-modern-checkbox
;; requires nerd font
'((88 . "")
(45 . "")
(32 . ""))
org-modern-list
'((43 . "•")
(45 . "–")
(42 . "↪")))
(custom-set-faces!
`(org-modern-tag
:background ,(doom-color 'fg-alt)
:foreground ,(doom-color 'bg-alt)
:family ,my/sans-serif-font
:height 0.7)))
(after! org-appear
(setq org-hide-emphasis-markers t
org-pretty-entities nil
;; org-appear-autoentities t
org-appear-autosubmarkers t
org-appear-inside-latex t
org-appear-autolinks 'just-brackets))
Modern block styling from org-modern-indent.
;; (use-package! org-modern-indent
;; :hook (org-mode . org-modern-indent-mode)
;; :config
;; (custom-set-faces!
;; `((org-block-begin-line)
;; :inherit default
;; :background nil)
;; `((org-block-end-line)
;; :inherit org-block-begin-line
;; :background nil))
;; (setq org-modern-block-name
;; '((t . t)
;; ("src" "──»" "──«")
;; ("example" "─»»" "─««")
;; ("quote" "─ ❝" "─ ❞")
;; ("export" "⏩" "⏪"))))
Align tables with images and hidden markup correctly with valign.
NOTE: Can be slow, especially with large org
files.
(use-package! valign
:hook (org-mode . valign-mode)
:config
(setq valign-fancy-bar t))
Customise drag-and-drop support for images and files, insert them into the images/
directory.
(use-package! org-download
:init
(setq-default org-download-image-dir "images")
:config
(setq org-download-method 'directory
org-download-link-format"[[file:images/%s]]\n"
org-download-heading-lvl nil))
(map! :map org-mode-map
:localleader
:prefix "a"
:desc "Rename image at point"
"C" #'org-download-rename-at-point)
Set up org-roam
and org-roam-ui
along with their keybindings that have the <leader> r prefix.
;; TODO set up capture templates
(use-package! org-roam
:defer t
:config
(setq org-roam-directory (file-truename "~/Notes")
org-roam-db-location (file-truename "~/Notes/org-roam.db")
org-attach-id-dir "assets/")
(org-roam-db-autosync-enable))
(use-package! websocket
:after org-roam)
(use-package! org-roam-ui
:after org-roam
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t
org-roam-mode-sections
(list #'org-roam-backlinks-section
#'org-roam-reflinks-section
#'org-roam-unlinked-references-section)))
;; custom org-roam functions
(defun my/org-roam--after-point ()
"If in evil normal state and not at EOL, move one char forward."
(when (and (bound-and-true-p evil-mode)
(evil-normal-state-p)
(not (eolp)))
(forward-char)))
(defun my/org-roam-insert-lowercase ()
"Insert an org-roam link after point, forcing the link text to lower-case."
(interactive)
(let ((org-roam-node-formatter
(lambda (node) (downcase (org-roam-node-title node)))))
(my/org-roam--after-point)
(call-interactively #'org-roam-node-insert)))
(defun my/org-roam-insert-custom-title ()
"Pick a node, then prompt for a verbatim link description."
(interactive)
(my/org-roam--after-point)
(let* ((node (org-roam-node-read))
(desc (read-string "Description: "))
(link (org-link-make-string
(concat "id:" (org-roam-node-id node))
desc)))
(insert link)
(org-roam-link-replace-at-point link)
(run-hooks 'org-roam-insert-node-hook)
(forward-char)))
;; copied from https://hieuphay.com/doom-emacs-config/#customizing-main-interface
(defun my/org-roam-node-find-by-mtime ()
"Find a node by last modified date."
(interactive)
(find-file
(org-roam-node-file
(org-roam-node-read nil nil #'org-roam-node-read-sort-by-file-mtime))))
(map! :map evil-org-mode-map
:leader
(:prefix ("r" . "roam")
:desc "Add alias"
"a" #'org-roam-alias-add
:desc "Remove alias"
"A" #'org-roam-alias-remove
:desc "Toggle roam buffer"
"b" #'org-roam-buffer-toggle
:desc "Find node"
"f" #'my/org-roam-node-find-by-mtime
:desc "Insert node"
"i" #'my/org-roam-insert-lowercase
:desc "Insert node (prompt title)"
"I" #'my/org-roam-insert-custom-title
:desc "Add tag"
"t" #'org-roam-tag-add
:desc "Remove tag"
"T" #'org-roam-tag-remove
:desc "Visit node"
"v" #'org-roam-node-visit
:desc "Open ORUI"
"u" #'org-roam-ui-open))