#+TITLE: Literate Doom Emacs config #+AUTHOR: Amolith ----- *Note:* you do not need to run ~doom sync~ after modifying this file! ----- Here are some additional functions/macros that could help configure Doom: - ~load!~ for loading external ~*.el~ files relative to this one - ~use-package!~ for configuring packages - ~after!~ for running code after a package has loaded - ~add-load-path!~ for adding directories to the ~load-path~, relative to this file. Emacs searches the ~load-path~ when loading packages with ~require~ or ~use-package~. - ~map!~ for binding new keys To get information about any of these functions/macros, move the cursor over the highlighted symbol at press ~K~ (non-evil users must press ~C-c c k~). This will open documentation for it, including demos of how they're used. ~gd~ (or ~C-c c d~) will also jump to their definition for viewing how they're implemented. First off, enable [[https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding][lexical binding]]: #+BEGIN_SRC emacs-lisp ;;; $DOOMDIR/config.el -*- lexical-binding: t; -*- #+END_SRC * Identity configuration Some functionality uses this to identify the user, e.g. GPG configuration, email clients, file templates and snippets. #+BEGIN_SRC emacs-lisp (setq user-full-name "Amolith" user-mail-address "amolith@secluded.site") #+END_SRC * UI settings 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. Generally, only these two are needed: #+BEGIN_SRC emacs-lisp (setq doom-font (font-spec :family "Triplicate A Code" :size 16) doom-variable-pitch-font (font-spec :family "Triplicate A Code" :size 16)) #+END_SRC There are two ways to load a theme. Both assume the theme is installed and available. Either set ~doom-theme~ or manually load a theme with the ~load-theme~ function. #+BEGIN_SRC emacs-lisp (setq doom-theme 'catppuccin) {{- if eq .theme_variant "dark"}} (setq catppuccin-flavor 'macchiato) {{- end }} {{- if eq .theme_variant "light"}} (setq catppuccin-flavor 'latte) {{- end }} #+END_SRC This determines the style of line numbers in effect. Disable line numbers by setting it this to ~nil~. For relative line numbers, set this to ~relative~. #+BEGIN_SRC emacs-lisp (setq display-line-numbers-type t) #+END_SRC Keep point in about the centre of the screen #+BEGIN_SRC emacs-lisp (use-package smooth-scrolling :ensure t :config (smooth-scrolling-mode 1) (setq smooth-scroll-margin 20)) #+END_SRC Use fancy lambdas #+BEGIN_SRC emacs-lisp (global-prettify-symbols-mode t) #+END_SRC When splitting windows, I want to switch to the new one immediately. By default, you have to press a few bindings. This makes that automatic. #+BEGIN_SRC emacs-lisp (defun amo/split-window-below-and-switch () "Split the window horizontally, then switch to the new pane." (interactive) (split-window-below) (balance-windows) (other-window 1)) (defun amo/split-window-right-and-switch () "Split the window vertically, then switch to the new pane." (interactive) (split-window-right) (balance-windows) (other-window 1)) (global-set-key (kbd "C-x 2") 'amo/split-window-below-and-switch) (global-set-key (kbd "C-x 3") 'amo/split-window-right-and-switch) #+END_SRC ** LSP Settings #+BEGIN_SRC emacs-lisp (setq lsp-ui-doc-max-height 13) (setq lsp-ui-doc-show-with-cursor t) #+END_SRC * Org Mode settings If you use ~org~ and don't want your org files in the default location below, change ~org-directory~. It must be set before org loads! #+BEGIN_SRC emacs-lisp (setq org-directory "~/Org/") #+END_SRC Prettify bullets #+BEGIN_SRC emacs-lisp (use-package org-bullets :init (add-hook 'org-mode-hook 'org-bullets-mode)) #+END_SRC Replace ellipsis with downward-pointing arrow #+BEGIN_SRC emacs-lisp (setq org-ellipsis " ⤵") #+END_SRC Format Org text and hide markers #+BEGIN_SRC emacs-lisp (setq org-hide-emphasis-markers t) #+END_SRC Prevent Emacs from indenting Org headers #+BEGIN_SRC emacs-lisp (setq org-adapt-indentation nil) #+END_SRC Allow export to Markdown and Beamer (for presentations). #+BEGIN_SRC emacs-lisp (require 'ox-md) (require 'ox-beamer) #+END_SRC Don't ask before evaluating code blocks #+BEGIN_SRC emacs-lisp (setq org-confirm-babel-evaluate nil) #+END_SRC Use =htmlize= to ensure that exported code blocks use syntax highlighting. #+BEGIN_SRC emacs-lisp (use-package htmlize) #+END_SRC Translate regular old straight quotes to typographically-correct curly quotes when exporting. #+BEGIN_SRC emacs-lisp (setq org-export-with-smart-quotes t) #+END_SRC Add ~ox-hugo~ for exporting ~blog.org~ files to Hugo-compatible markdown #+BEGIN_SRC emacs-lisp (use-package ox-hugo :ensure t :after ox) #+END_SRC #+BEGIN_SRC emacs-lisp (use-package helm-bibtex :custom (helm-bibtex-bibliography '("~/Documents/citations.bib")) (reftex-default-bibliography '("~/Documents/citations.bib")) (bibtex-completion-pdf-field "file") :hook (Tex . (lambda () (define-key Tex-mode-map "\C-ch" 'helm-bibtex)))) (use-package org-ref :custom (org-ref-default-bibliography "~/Documents/citations.bib")) (defun org-export-latex-no-toc (depth) (when depth (format "%% Org-mode is exporting headings to %s levels.\n" depth))) (setq org-export-latex-format-toc-function 'org-export-latex-no-toc) (add-to-list 'org-latex-classes '("apa6" "\\documentclass{apa6}" ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) (setq org-latex-pdf-process '("latexmk -pdflatex='pdflatex -interaction nonstopmode' -pdf -bibtex -f %f")) #+END_SRC * Email configuration Attempt to load encrypted config (doesn't work for some reason) #+INCLUDE: "~/.doom.d/extra/mu4e-config.el" src emacs-lisp * Other environments Use ~mail-mode~ for syntax highlighting and bindings in neomutt compositions #+BEGIN_SRC emacs-lisp (add-to-list 'auto-mode-alist '("/tmp/neomutt-*" . mail-mode)) #+END_SRC Always use =pdflatex= when compiling LaTeX documents. I don't really have any use for DVIs. #+BEGIN_SRC emacs-lisp (setq TeX-PDF-mode t) #+END_SRC ** Music I've taken to charting my guitar music out with [[https://www.chordpro.org][ChordPro]]. [[https://github.com/sciurius/chordpro-mode][Chordpro mode]] just adds a major mode for syntax highlighting and some keybinds. #+BEGIN_SRC emacs-lisp (setq auto-mode-alist (cons '("\\.cho$" . chordpro-mode) auto-mode-alist)) (autoload 'chordpro-mode "chordpro-mode") #+END_SRC I use [[https://lilypond.org/][LilyPond]] for writing standard sheet music. When you install the package, it comes with some elisp files that Emacs needs to load and configure. #+BEGIN_SRC emacs-lisp (require 'lilypond-mode) (add-to-list 'auto-mode-alist '("\\.ly$" . LilyPond-mode)) ;; Set PDF viewer to zathura, my personal preference (setq LilyPond-pdf-command "zathura") #+END_SRC ** General prose settings Define prose modes for enabling prose-related niceties #+BEGIN_SRC emacs-lisp (defvar prose-modes '(gfm-mode git-commit-mode markdown-mode message-mode mail-mode org-mode text-mode)) (defvar prose-mode-hooks (mapcar (lambda (mode) (intern (format "%s-hook" mode))) prose-modes)) #+END_SRC Enable spell-checking for all prose-related modes #+BEGIN_SRC emacs-lisp (use-package flyspell :config (dolist (hook prose-mode-hooks) (add-hook hook 'flyspell-mode))) #+END_SRC Wrap prose paragraphs automatically #+BEGIN_SRC emacs-lisp (dolist (hook prose-mode-hooks) (add-hook hook 'turn-on-auto-fill)) #+END_SRC - Associate ~.md~ files with GitHub-flavoured Markdown - Use ~pandoc~ to render the results - Apply syntax highlighting in code blocks #+BEGIN_SRC emacs-lisp (use-package markdown-mode :commands gfm-mode :mode (("\\.md$" . gfm-mode)) :config (custom-set-faces '(markdown-pre-face ((t nil)))) (setq markdown-command "pandoc --standalone --mathjax --from=markdown" markdown-fontify-code-blocks-natively t)) #+END_SRC Add a path both to the ~$PATH~ variable and to Emacs' exec-path #+BEGIN_SRC emacs-lisp (defun amo/append-to-path (path) (setenv "PATH" (concat (getenv "PATH") ":" path)) (add-to-list 'exec-path path)) #+END_SRC Look for various executables #+BEGIN_SRC emacs-lisp (amo/append-to-path "/usr/local/bin") (amo/append-to-path "~/.local/bin") #+END_SRC ** Python settings #+BEGIN_SRC emacs-lisp (add-hook 'python-mode-hook 'auto-virtualenv-set-virtualenv) #+END_SRC ** Go settings #+BEGIN_SRC emacs-lisp (gofmt-before-save) (setq lsp-go-use-placeholders nil) (setq lsp-go-link-target "godocs.io") (setq lsp-go-use-gofumpt t) ;;(setq lsp-go-build-flags ["mage"]) #+END_SRC ** SuperCollider #+BEGIN_SRC emacs-lisp (require 'sclang) (add-hook 'sclang-mode-hook 'sclang-extensions-mode) #+END_SRC ** TidalCycles #+BEGIN_SRC emacs-lisp (setq tidal-boot-script-path "/usr/share/x86_64-linux-ghc-9.0.2/tidal-1.7.10/BootTidal.hs") #+END_SRC ** Tree-sitter #+BEGIN_SRC emacs-lisp (global-tree-sitter-mode) (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode) #+END_SRC ** Editor metrics [[https://github.com/wakatime/wakatime-mode][wakatime-mode]] connected to self-hosted [[https://wakapi.dev/][Wakapi]] instance to get interesting stats about the time I spend in an editor #+BEGIN_SRC emacs-lisp (global-wakatime-mode) (setq wakatime-cli-path "/usr/bin/wakatime") #+END_SRC ** Magit Use git flow in magit status buffers #+BEGIN_SRC emacs-lisp (add-hook 'magit-mode-hook 'turn-on-magit-gitflow) #+END_SRC * Custom bindings Following established Doom conventions, bind ~SPC g p~ to ~magit-push-current-to-upstream~ #+BEGIN_SRC emacs-lisp (map! :leader :desc "Push upstream" "g p" #'magit-push-current-to-upstream) #+END_SRC * Copilot #+BEGIN_SRC emacs-lisp (use-package! copilot :hook (prog-mode . copilot-mode) :bind (("C-TAB" . 'copilot-accept-completion-by-word) ("C-" . 'copilot-accept-completion-by-word) :map copilot-completion-map ("" . 'copilot-accept-completion) ("TAB" . 'copilot-accept-completion))) #+END_SRC