#+TITLE: Doom Emacs Literate Config #+AUTHOR: Emmet * Table of Contents :TOC:QUOTE: #+BEGIN_QUOTE - [[#what-is-doom-emacs][What is Doom Emacs?]] - [[#configuration-for-doom-emacs][Configuration for Doom Emacs]] - [[#my-configel][My config.el]] - [[#preamble--user-configuration][Preamble + User Configuration]] - [[#registers][Registers]] - [[#org-mode-configuration][Org Mode Configuration]] - [[#org-roam-configuration][Org Roam Configuration]] - [[#org-agenda-configuration][Org Agenda Configuration]] - [[#magit-configuration][Magit Configuration]] - [[#ibuffer-configuration][Ibuffer Configuration]] - [[#dired-configuration][Dired Configuration]] - [[#ranger-configuration][Ranger Configuration]] - [[#hledger-mode-configuration][hledger-mode Configuration]] - [[#tab-bar-configuration][Tab Bar Configuration]] - [[#focus-mode-configuration][Focus Mode Configuration]] - [[#helpful-mode-configuration][Helpful Mode Configuration]] - [[#eaf][EAF]] - [[#direnv][Direnv]] - [[#projectile][Projectile]] - [[#lsp][LSP]] - [[#terminal][Terminal]] - [[#my-initel][My init.el]] - [[#my-packagesel][My packages.el]] - [[#nix-integration][Nix Integration]] #+END_QUOTE * What is Doom Emacs? [[https://github.com/doomemacs/doomemacs][Doom Emacs]] is a distribution of the [[https://www.gnu.org/software/emacs/][Emacs Text Editor]] designed for [[https://www.vim.org/][Vim]] users. I like to use Emacs due to its extensibility and extra features it is capable of (besides text editing). Some of these extra features include: - [[https://orgmode.org/][Org Mode]] (Hierarchical text-based document format) - [[https://www.orgroam.com/][Org Roam]] (A second brain / personal wiki) - [[https://orgmode.org/][Org Agenda]] (Calendar and todo list) - [[https://magit.vc/][magit]] (Git Client) I have found Emacs to be incredibly efficient, and transferring my workflow to fit inside of Emacs has allowed me to get much more work done. I primarily use Emacs for writing, note-taking, task/project management and organizing information. * Configuration for Doom Emacs Doom Emacs is configured via 3 main files, written in Elisp, a dialect of the Lisp programming langauge designed for Emacs. These 3 main files are: - [[./config.el][config.el]] - Stores your main configuration and allows to set user variables. - [[./init.el][init.el]] - Allows quick downloads of groups of Emacs packages. These groups of Emacs packages are curated by the Doom Emacs developers. - [[./packages.el][packages.el]] - Allows you to download additional packages from Melpa (Emacs package manager). By storing your configuration in these 3 files, it allows for quick reproducible builds of Doom Emacs. You can also load separate files inside of [[./config.el][config.el]] via the =load!= function, like so: #+BEGIN_SRC emacs-lisp (load! "~/.doom.d/private.el") #+END_SRC I use this functionality to load my private config file with non-public information. Doom Emacs is traditionally installed by cloning the repository ([[https://github.com/doomemacs/doomemacs][https://github.com/doomemacs/doomemacs]]) and running =./bin/doom install=. I instead install Doom Emacs via Nix Doom Emacs ([[https://github.com/nix-community/nix-doom-emacs][https://github.com/nix-community/nix-doom-emacs]]), which packages Doom Emacs as a Nix derivation. The advantage to this is that I get more reproducibility and the ability to rollback updates (if anything breaks), but the downside is that every time the config is changed/updated, the entire derivation must be rebuilt from scratch (this is often time-consuming). I load this as a Nix derivation in my flake using the [[./doom.nix][doom.nix]] module. * My config.el ** Preamble + User Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;; $DOOMDIR/config.el -*- lexical-binding: t; -*- ;;;------ User configuration ------;;; ;; My default user identity as my yt alias (setq user-full-name "Emmet") ;; I prefer visual lines (setq display-line-numbers-type 'visual line-move-visual t) (use-package-hook! evil :pre-init (setq evil-respect-visual-line-mode t) ;; sane j and k behavior t) ;; I also like evil mode visual movement (map! :map evil-normal-state-map :desc "Move to next visual line" "j" 'evil-next-visual-line :desc "Move to previous visual line" "k" 'evil-previous-visual-line) ;; Theme and font (setq custom-theme-directory "~/.emacs.d/themes") (setq doom-theme 'doom-stylix) (setq doom-font (font-spec :family "Inconsolata" :size 20)) ;; +unicode-init-fonts-h often errors out (remove-hook 'doom-init-ui-hook '+unicode-init-fonts-h) ;; Transparent background (set-frame-parameter (selected-frame) 'alpha '(90 . 90)) (add-to-list 'default-frame-alist '(alpha . (90 . 90))) ;; Icons in completion buffers (add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup) (all-the-icons-completion-mode) ;; This makes non-main buffers dimmer, so you can focus on main buffers (solaire-global-mode +1) ;; Grammar tasing should be voluntary (setq writegood-mode nil) ;; Beacon shows where the cursor is, even when fast scrolling (setq beacon-mode t) ;; Quicker window management keybindings (bind-key* "C-j" #'evil-window-down) (bind-key* "C-k" #'evil-window-up) (bind-key* "C-h" #'evil-window-left) (bind-key* "C-l" #'evil-window-right) (bind-key* "C-q" #'evil-window-delete) (bind-key* "M-q" #'kill-current-buffer) (bind-key* "M-w" #'+workspace/close-window-or-workspace) (bind-key* "M-n" #'next-buffer) (bind-key* "M-p" #'previous-buffer) (bind-key* "M-z" #'+vterm/toggle) (bind-key* (kbd "M-") #'+vterm/here) ;; Buffer management (bind-key* "" #'next-buffer) (bind-key* "" #'previous-buffer) ;; Disables custom.el (setq custom-file null-device) ;; Fancy splash image (setq fancy-splash-image "~/.emacs.d/dashboard-logo.png") (setq +doom-dashboard-menu-sections '(("Open org roam overview" :icon (all-the-icons-octicon "globe" :face 'doom-dashboard-menu-title) :face (:inherit (doom-dashboard-menu-title bold)) :action org-roam-default-overview) ("Roam to another db" :icon (all-the-icons-fileicon "org" :face 'doom-dashboard-menu-title) :action org-roam-switch-db) ("Open agenda" :icon (all-the-icons-octicon "calendar" :face 'doom-dashboard-menu-title) :when (fboundp 'org-agenda) :action org-agenda-list :key "SPC o A a") ("Open private configuration" :icon (all-the-icons-octicon "tools" :face 'doom-dashboard-menu-title) :when (file-directory-p doom-user-dir) :action doom/open-private-config) ("Open documentation" :icon (all-the-icons-octicon "book" :face 'doom-dashboard-menu-title) :action doom/help) ("Quit emacs" :icon (all-the-icons-faicon "level-down" :face 'doom-dashboard-menu-title) :action save-buffers-kill-terminal) ) ) ;; Requires for faster loading (require 'org-agenda) (require 'dired) ;; Garbage collection to speed things up (add-hook 'after-init-hook #'(lambda () (setq gc-cons-threshold (* 100 1000 1000)))) (add-hook 'focus-out-hook 'garbage-collect) (run-with-idle-timer 5 t 'garbage-collect) ;; Enable autorevert globally so that buffers update when files change on disk. ;; Very useful when used with file syncing (i.e. syncthing) (setq global-auto-revert-mode nil) (setq auto-revert-use-notify t) #+END_SRC ** Registers #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ Registers ------;;; (map! :leader :desc "Jump to register" "r" 'jump-to-register) (set-register ?f '(file . "/home/emmet/Org/Family.s/Notes/hledger.org")) (set-register ?h '(file . "/home/emmet")) (set-register ?r '(file . "/home/emmet/.dotfiles/README.org")) (set-register ?x '(file . "/home/emmet/.dotfiles/user/wm/xmonad/xmonad.org")) (set-register ?d '(file . "/home/emmet/.dotfiles/user/app/doom-emacs/doom.org")) #+END_SRC ** Org Mode Configuration *** Standard Org Mode Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ Org mode configuration ------;;; ;; Set default org directory (setq org-directory "~/.Org") (remove-hook 'after-save-hook #'+literate|recompile-maybe) (set-company-backend! 'org-mode nil) ;; Automatically show images but manually control their size (setq org-startup-with-inline-images t org-image-actual-width nil) (require 'evil-org) (require 'evil-org-agenda) (add-hook 'org-mode-hook 'evil-org-mode -100) ;; Top-level headings should be bigger! (custom-set-faces! '(org-level-1 :inherit outline-1 :height 1.3) '(org-level-2 :inherit outline-2 :height 1.25) '(org-level-3 :inherit outline-3 :height 1.2) '(org-level-4 :inherit outline-4 :height 1.1) '(org-level-5 :inherit outline-5 :height 1.1) '(org-level-6 :inherit outline-6 :height 1.05) '(org-level-7 :inherit outline-7 :height 1.05) ) (after! org (org-eldoc-load)) (with-eval-after-load 'org (global-org-modern-mode)) ;; Add frame borders and window dividers (modify-all-frames-parameters '((right-divider-width . 10) (internal-border-width . 10))) (dolist (face '(window-divider window-divider-first-pixel window-divider-last-pixel)) (face-spec-reset-face face) (set-face-foreground face (face-attribute 'default :background))) (set-face-background 'fringe (face-attribute 'default :background)) (setq ;; Edit settings org-auto-align-tags nil org-tags-column 0 org-catch-invisible-edits 'show-and-error org-special-ctrl-a/e t org-insert-heading-respect-content t ;; Org styling, hide markup etc. org-hide-emphasis-markers t org-pretty-entities t org-ellipsis "…") (setq-default line-spacing 0.1) ; Automatic table of contents is nice (if (require 'toc-org nil t) (progn (add-hook 'org-mode-hook 'toc-org-mode) (add-hook 'markdown-mode-hook 'toc-org-mode)) (warn "toc-org not found")) ;;---- this block from http://fgiasson.com/blog/index.php/2016/06/21/optimal-emacs-settings-for-org-mode-for-literate-programming/ ----;; ;; Tangle Org files when we save them (defun tangle-on-save-org-mode-file() (when (string= (message "%s" major-mode) "org-mode") (org-babel-tangle))) (add-hook 'after-save-hook 'tangle-on-save-org-mode-file) ;; ---- end block ---- ;; ;; Better org table editing ;; This breaks multiline visual block edits ;;(setq-default evil-insert-state-exit-hook '(org-update-parent-todo-statistics ;; t)) ;;(setq org-table-automatic-realign nil) ;; Better for org source blocks (setq electric-indent-mode nil) (setq org-src-window-setup 'current-window) (delete '("^\\*Org Src" (+popup-buffer) (actions) (side . bottom) (size . 0.42) (window-width . 40) (window-height . 0.42) (slot) (vslot) (window-parameters (ttl) (quit) (select . t) (modeline . t) (autosave . t) (transient . t) (no-other-window . t))) display-buffer-alist) #+END_SRC *** Org Download, Image Capture, and Opening Files in External Programs #+BEGIN_SRC emacs-lisp :tangle config.el (require 'org-download) ;; Drag-and-drop to `dired` (add-hook 'dired-mode-hook 'org-download-enable) (setq org-download-screenshot-method "flameshot gui -p %s") (after! org-download (setq org-download-method 'directory)) (after! org (setq-default org-download-image-dir "img/" org-download-heading-lvl nil)) (defun my-org-screenshot () "Take a screenshot into a time stamped unique-named file in the same directory as the org-buffer and insert a link to this file." (interactive) (setq filename (concat (make-temp-name (concat (buffer-file-name) "_" (format-time-string "%Y%m%d_%H%M%S_")) ) ".png")) (shell-command (concat "emacs-wayshot " filename)) (insert (concat "[[" filename "]]")) (org-display-inline-images)) (defun my-org-paste() "Take an image from the clipboard into a time stamped unique-named file in the same directory as the org-buffer and insert a link to this file." (interactive) (setq filename (concat (make-temp-name (concat (file-name-directory (buffer-file-name)) "img/" (file-name-nondirectory (buffer-file-name)) "_" (format-time-string "%Y%m%d_%H%M%S_")) ) ".png")) (shell-command (concat "wl-paste > " filename)) (insert (concat "[[" filename "]]")) (org-display-inline-images)) (defun my-org-new-file-from-template() "Copy a template from ~/Templates into a time stamped unique-named file in the same directory as the org-buffer and insert a link to this file." (interactive) (setq template-file (completing-read "Template file:" (directory-files "~/Templates"))) (setq filename (concat (make-temp-name (concat (file-name-directory (buffer-file-name)) "files/" (file-name-nondirectory (buffer-file-name)) "_" (format-time-string "%Y%m%d_%H%M%S_")) ) (file-name-extension template-file t))) (copy-file (concat "/home/emmet/Templates/" template-file) filename) (setq prettyname (read-from-minibuffer "Pretty name:")) (insert (concat "[[./files/" (file-name-nondirectory filename) "][" prettyname "]]")) (org-display-inline-images)) (when (require 'openwith nil 'noerror) (setq openwith-associations (list (list (openwith-make-extension-regexp '("mpg" "mpeg" "mp3" "mp4" "avi" "wmv" "wav" "mov" "flv" "ogm" "ogg" "mkv")) "mpv" '(file)) (list (openwith-make-extension-regexp '("doc" "xls" "ppt" "odt" "ods" "odg" "odp")) "libreoffice" '(file)) '("\\.lyx" "lyx" (file)) '("\\.chm" "kchmviewer" (file)) (list (openwith-make-extension-regexp '("pdf" "ps" "ps.gz" "dvi")) "atril" '(file)) (list (openwith-make-extension-regexp '("kdenlive")) "kdenlive" '(file)) (list (openwith-make-extension-regexp '("kra")) "krita" '(file)) (list (openwith-make-extension-regexp '("blend" "blend1")) "blender" '(file)) (list (openwith-make-extension-regexp '("helio")) "helio" '(file)) (list (openwith-make-extension-regexp '("svg")) "inkscape" '(file)) (list (openwith-make-extension-regexp '("flp")) "~/.local/bin/flstudio" '(file)) )) (openwith-mode 1)) (add-to-list 'display-buffer-alist '("^*Async Shell Command*" . (display-buffer-no-window))) (map! :leader :desc "Insert a screenshot" ;; "i s" 'my-org-screenshot) "i s" 'org-download-screenshot) (defun org-download-clipboard-basename () (interactive) (setq org-download-path-last-dir org-download-image-dir) (setq org-download-image-dir (completing-read "directory: " (-filter #'f-directory-p (directory-files-recursively "." "" t)) nil t)) (org-download-clipboard (completing-read "basename: " '() nil nil)) (setq org-download-image-dir org-download-path-last-dir) ) (map! :leader :desc "Insert image from clipboard" "i p" 'org-download-clipboard "i P" 'org-download-clipboard-basename) (map! :leader :desc "Create a new file from a template and insert a link at point" "i t" 'my-org-new-file-from-template) #+END_SRC *** Copy Links/Files into Clipboard #+BEGIN_SRC emacs-lisp :tangle config.el (defun org-copy-link-to-clipboard-at-point () "Copy current link at point into clipboard (useful for images and links)" ;; Remember to press C-g to kill this foreground process if it hangs! (interactive) (if (eq major-mode #'org-mode) (link-hint-copy-link-at-point) ) (if (eq major-mode #'ranger-mode) (ranger-copy-absolute-file-paths) ) (if (eq major-mode #'image-mode) (image-mode-copy-file-name-as-kill) ) (shell-command (concat "~/.emacs.d/scripts/copy-link-or-file/copy-link-or-file-to-clipboard.sh " (gui-get-selection 'CLIPBOARD)) nil nil) ) (map! :leader :desc "Copy link/file at point into system clipbord (C-g to escape if copying a file)" "y y" 'org-copy-link-to-clipboard-at-point) #+END_SRC **** Copy Link/File to Clipboard Helper Script Shamelessly stolen from [[https://unix.stackexchange.com/questions/30093/copy-image-from-command-line-to-clipboard][here]] and modified for my use. #+BEGIN_SRC shell :tangle ./scripts/copy-link-or-file/copy-link-or-file-to-clipboard.sh :tangle-mode (identity #o755) #!/bin/sh if [[ -f "$1" ]]; then TYPE=$(file -b --mime-type "$1") xclip -selection clipboard -t "$TYPE" -i "$1" else echo $1 | xclip -selection clipboard -t text/plain &> /dev/null exit fi exit #+END_SRC *** Org Online Images #+BEGIN_SRC emacs-lisp :tangle config.el ;; Online images inside of org mode is pretty cool ;; This snippit is from Tobias on Stack Exchange ;; https://emacs.stackexchange.com/questions/42281/org-mode-is-it-possible-to-display-online-images (require 'org-yt) (defun org-image-link (protocol link _description) "Interpret LINK as base64-encoded image data." (cl-assert (string-match "\\`img" protocol) nil "Expected protocol type starting with img") (let ((buf (url-retrieve-synchronously (concat (substring protocol 3) ":" link)))) (cl-assert buf nil "Download of image \"%s\" failed." link) (with-current-buffer buf (goto-char (point-min)) (re-search-forward "\r?\n\r?\n") (buffer-substring-no-properties (point) (point-max))))) (org-link-set-parameters "imghttp" :image-data-fun #'org-image-link) (org-link-set-parameters "imghttps" :image-data-fun #'org-image-link) #+END_SRC *** Org Mermaid Diagrams #+BEGIN_SRC emacs-lisp :tangle config.el ;; Mermaid diagrams (setq ob-mermaid-cli-path "~/.nix-profile/bin/mmdc") #+END_SRC *** Org Simple Printing #+BEGIN_SRC emacs-lisp :tangle config.el ;; Print org mode (defun org-simple-print-buffer () "Open an htmlized form of current buffer and open in a web browser to print" (interactive) (htmlize-buffer) (browse-url-of-buffer (concat (buffer-name) ".html")) (sleep-for 1) (kill-buffer (concat (buffer-name) ".html"))) ;; Doesn't work yet, bc htmlize-region takes arguments BEG and END ;(defun org-simple-print-region() ; "Open an htmlized form of current region and open in a web browser to print" ; (interactive) ; (htmlize-region ) ; (browse-url-of-buffer (concat (buffer-name) ".html")) ; (sleep-for 1) ; (kill-buffer (concat (buffer-name) ".html"))) (map! :leader :prefix ("P" . "Print") :desc "Simple print buffer in web browser" "p" 'org-simple-print-buffer) (map! :leader :prefix ("P" . "Print") :desc "Simple print buffer in web browser" "b" 'org-simple-print-buffer) ;(map! :leader ; :prefix ("P" . "Print") ; :desc "Simple print region in web browser" ; "r" 'org-simple-print-region) #+END_SRC ** Org Roam Configuration *** Standard Org Roam Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ Org roam configuration ------;;; (require 'org-roam) (require 'org-roam-dailies) (setq org-roam-directory "~/Org/Personal/Notes" org-roam-db-location "~/Org/Personal/Notes/org-roam.db") (setq org-roam-node-display-template "${title:65}📝${tags:*}") (org-roam-db-autosync-mode) #+END_SRC *** Multi Org Roam Configuration #+BEGIN_SRC emacs-lisp :tangle config.el (setq full-org-roam-db-list nil) (setq full-org-roam-db-list (directory-files "~/Org" t "\\.[p,s]$")) (dolist (item full-org-roam-db-list) (setq full-org-roam-db-list (append (directory-files item t "\\.[p,s]$") full-org-roam-db-list))) (setq org-roam-db-choice "Default") (setq full-org-roam-db-list-pretty (list "Default")) (dolist (item full-org-roam-db-list) (setq full-org-roam-db-list-pretty (append (list (replace-regexp-in-string "\\/home\\/emmet\\/Org\\/" "" item)) full-org-roam-db-list-pretty))) (defun org-roam-open-dashboard () "Open ${org-roam-directory}/dashboard.org (I use this naming convention to create dashboards for each of my org roam maps)" (interactive) (if (file-exists-p (concat org-roam-directory "/dashboard.org")) (org-open-file (concat org-roam-directory "/dashboard.org")) (dired org-roam-directory)) ) (defun org-roam-switch-db (&optional arg silent) "Switch to a different org-roam database, arg" (interactive) (when (not arg) (setq full-org-roam-db-list nil) (setq full-org-roam-db-list (directory-files "~/Org" t "\\.[p,s]$")) (dolist (item full-org-roam-db-list) (setq full-org-roam-db-list (append (directory-files item t "\\.[p,s]$") full-org-roam-db-list))) (setq full-org-roam-db-list-pretty (list "Default")) (dolist (item full-org-roam-db-list) (setq full-org-roam-db-list-pretty (append (list (replace-regexp-in-string "\\/home\\/emmet\\/Org\\/" "" item)) full-org-roam-db-list-pretty))) (setq org-roam-db-choice (completing-read "Select org roam database: " full-org-roam-db-list-pretty nil t))) (when arg (setq org-roam-db-choice arg)) (if (string= org-roam-db-choice "Default") (setq org-roam-directory (file-truename "~/Org/Personal/Notes") org-roam-db-location (file-truename "~/Org/Personal/Notes/org-roam.db") org-directory (file-truename"~/Org/Personal/Notes")) (setq org-roam-directory (file-truename (concat "~/Org/" org-roam-db-choice "/Notes")) org-roam-db-location (file-truename (concat "~/Org/" org-roam-db-choice "/Notes/org-roam.db")) org-directory (file-truename (concat "~/Org/" org-roam-db-choice "/Notes")))) (when (not silent) (org-roam-open-dashboard)) (org-roam-db-sync) (message (concat "Switched to " org-roam-db-choice " org-roam database!"))) (defun org-roam-default-overview () (interactive) (org-roam-switch-db "Default")) (defun org-roam-switch-db-id-open (arg ID &optional switchpersist) "Switch to another org-roam db and visit file with id arg" "If switchpersist is non-nil, stay in the new org-roam db after visiting file" (interactive) (setq prev-org-roam-db-choice org-roam-db-choice) (org-roam-switch-db arg 1) (org-roam-id-open ID) (when (not switchpersist) (org-roam-switch-db prev-org-roam-db-choice 1))) #+END_SRC *** Org Roam "todos" Tagging for Org Agenda #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ Org-roam-agenda configuration ------;;; (defun text-in-buffer-p (TEXT) (save-excursion (goto-char (point-min)) (search-forward TEXT nil t))) (defun apply-old-todos-tag-maybe (&optional FILE) (interactive) (if (stringp FILE) (setq the-daily-node-filename FILE) (setq the-daily-node-filename buffer-file-name)) (if (org-roam-dailies--daily-note-p the-daily-node-filename) (if (<= (nth 2 (org-roam-dailies-calendar--file-to-date the-daily-node-filename)) (nth 2 org-agenda-current-date)) (if (<= (nth 1 (org-roam-dailies-calendar--file-to-date the-daily-node-filename)) (nth 1 org-agenda-current-date)) (if (<= (nth 0 (org-roam-dailies-calendar--file-to-date the-daily-node-filename)) (nth 0 org-agenda-current-date)) (funcall (lambda () (with-current-buffer (get-file-buffer the-daily-node-filename) (org-roam-tag-add '("old-todos"))) (with-current-buffer (get-file-buffer the-daily-node-filename) (org-roam-tag-remove '("todos"))) ) ) ) ) ) ) ) (defun apply-old-todos-tag-maybe-and-save (FILE) (interactive) (find-file-noselect FILE) (apply-old-todos-tag-maybe FILE) (with-current-buffer (get-file-buffer the-daily-node-filename) (save-buffer)) (with-current-buffer (get-file-buffer the-daily-node-filename) (kill-buffer)) ) ; This has a bug where it won't sync a new agenda file ; if I'm editing an org roam node file while set to another ; org roam db (defun add-todos-tag-on-save-org-mode-file() (interactive) (when (string= (message "%s" major-mode) "org-mode") (if (org-roam-node-p (org-roam-node-at-point)) (funcall (lambda() (if (or (text-in-buffer-p "SCHEDULED: <") (text-in-buffer-p "DEADLINE: <")) (org-roam-tag-add '("todos")) (org-roam-tag-remove '("todos")) ) (apply-old-todos-tag-maybe) ) ) ) ) ) (add-hook 'before-save-hook 'add-todos-tag-on-save-org-mode-file) #+END_SRC *** Setup Org Agenda from Org Roam #+BEGIN_SRC emacs-lisp :tangle config.el (defun org-roam-filter-by-tag (tag-name) (lambda (node) (member tag-name (org-roam-node-tags node)))) (defun org-roam-list-notes-by-tag (tag-name) (mapcar #'org-roam-node-file (seq-filter (org-roam-filter-by-tag tag-name) (org-roam-node-list)))) (defun org-roam-dailies-apply-old-todos-tags-to-all () ; (dolist (daily-node org-roam-dailies-files) ; (apply-old-todos-tag-maybe-and-save daily-node) ; ) (setq num 0) (while (< num (list-length (org-roam-list-notes-by-tag "todos"))) (apply-old-todos-tag-maybe-and-save (nth num (org-roam-list-notes-by-tag "todos"))) (setq num (1+ num)) ) ) (defun org-roam-append-notes-to-agenda (tag-name db) (org-roam-switch-db db t) ; (org-roam-dailies-apply-old-todos-tags-to-all) (setq org-agenda-files (append org-agenda-files (org-roam-list-notes-by-tag "todos"))) ) (defun org-roam-refresh-agenda-list () (interactive) (setq prev-org-roam-db-choice org-roam-db-choice) (setq org-agenda-files '()) (dolist (DB full-org-roam-db-list-pretty) (org-roam-append-notes-to-agenda "todos" DB) ) (setq org-agenda-files (-uniq org-agenda-files)) (org-roam-switch-db prev-org-roam-db-choice 1) ) ;; Build agenda for first time during this session (org-roam-refresh-agenda-list) (map! :leader :prefix ("o a") :desc "Refresh org agenda from roam dbs" "r" 'org-roam-refresh-agenda-list) #+END_SRC *** Org Roam Keybindings #+BEGIN_SRC emacs-lisp :tangle config.el (map! :leader :prefix ("N" . "org-roam notes") :desc "Capture new roam node" "c" 'org-roam-capture :desc "Insert roam node link at point" "i" 'org-roam-node-insert :desc "Find roam node" "." 'org-roam-node-find :desc "Switch org-roam database" "s" 'org-roam-switch-db :desc "Update current org-roam database" "u" 'org-roam-db-sync :desc "Re-zoom on current node in org-roam-ui" "z" 'org-roam-ui-node-zoom :desc "Visualize org-roam database with org-roam-ui" "O" 'org-roam-default-overview :desc "Visualize org-roam database with org-roam-ui" "o" 'org-roam-open-dashboard) #+END_SRC *** Org Roam Capture Templates #+BEGIN_SRC emacs-lisp :tangle config.el (after! org-roam (setq org-roam-capture-templates '(("d" "default" plain "%?" :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n") :unnarrowed t)))) #+END_SRC *** Org Roam Olivetti Mode #+BEGIN_SRC emacs-lisp :tangle config.el (defun org-roam-olivetti-mode () (interactive) (if (org-roam-file-p) (olivetti-mode)) (if (org-roam-file-p) (doom-disable-line-numbers-h))) (add-hook 'org-mode-hook 'org-roam-olivetti-mode) #+END_SRC *** Org Roam Dynamic Blocks This needs fixing on NixOS: #+BEGIN_SRC emacs-lisp :tangle config.el (add-load-path! "~/.emacs.d/org-nursery/lisp") (require 'org-roam-dblocks) (use-package org-roam-dblocks :hook (org-mode . org-roam-dblocks-autoupdate-mode)) #+END_SRC *** Org Roam Export Setup #+BEGIN_SRC emacs-lisp :tangle config.el (setq org-id-extra-files 'org-agenda-text-search-extra-files) #+END_SRC *** Org Roam UI Setup I want this to be able to automatically open ORUI in EAF Browser in a split to the right. This kinda works now? On Wayland, EAF doesn't work. #+BEGIN_SRC emacs-lisp :tangle config.el ;(add-to-list 'display-buffer-alist '("^\\ORUI" display-buffer-in-side-window ; '(side . right) ; (window-width . 50) ;)) ;(add-to-list 'display-buffer-alist '("^\\localhost:35901" display-buffer-in-side-window ; '(side . right) ; (window-width . 50) ;)) ;;(setq org-roam-ui-browser-function 'eaf-open-browser) ; xorg (setq org-roam-ui-browser-function 'browse-url) ; wayland (defun open-org-roam-ui () (interactive) (+evil/window-vsplit-and-follow) (org-roam-ui-open) (evil-window-left 1)) (defun kill-org-roam-ui () (interactive) ;; (delete-window (get-buffer-window "ORUI" t)) ; xorg ;; (kill-buffer "ORUI") ; xorg (kill-buffer "*httpd*") ) ; xorg ;;(map! :leader ;; :prefix ("N" . "org-roam notes") ;; :desc "Visualize org-roam database with org-roam-ui" ;; "v" 'open-org-roam-ui) ; wayland (map! :leader :prefix ("N" . "org-roam notes") :desc "Visualize org-roam database with org-roam-ui" "v" 'org-roam-ui-open) (map! :leader :prefix ("N" . "org-roam notes") :desc "Kill all org roam ui buffers" "V" 'kill-org-roam-ui) #+END_SRC ** Org Agenda Configuration *** Standard Org Agenda Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ Org agenda configuration ------;;; ;; Set span for agenda (setq org-agenda-span 1 org-agenda-start-day "+0d") ;; Ricing org agenda (setq org-agenda-current-time-string "") (setq org-agenda-time-grid '((daily) () "" "")) (setq org-agenda-prefix-format '( (agenda . " %?-2i %t ") (todo . " %i %-12:c") (tags . " %i %-12:c") (search . " %i %-12:c"))) (setq org-agenda-hide-tags-regexp ".*") (setq org-agenda-category-icon-alist `(("Teaching" ,(list (all-the-icons-faicon "graduation-cap" :height 0.8)) nil nil :ascent center) ("Family" ,(list (all-the-icons-faicon "home" :v-adjust 0.005)) nil nil :ascent center) ("Producer" ,(list (all-the-icons-faicon "youtube-play" :height 0.9)) nil nil :ascent center) ("Bard" ,(list (all-the-icons-faicon "music" :height 0.9)) nil nil :ascent center) ("Story" ,(list (all-the-icons-faicon "book" :height 0.9)) nil nil :ascent center) ("Author" ,(list (all-the-icons-faicon "pencil" :height 0.9)) nil nil :ascent center) ("Gamedev" ,(list (all-the-icons-faicon "gamepad" :height 0.9)) nil nil :ascent center) ("Tech" ,(list (all-the-icons-faicon "laptop" :height 0.9)) nil nil :ascent center) )) ;; Function to be run when org-agenda is opened (defun org-agenda-open-hook () "Hook to be run when org-agenda is opened" (olivetti-mode)) ;; Adds hook to org agenda mode, making follow mode active in org agenda (add-hook 'org-agenda-mode-hook 'org-agenda-open-hook) #+END_SRC *** Org Agenda Convenience Functions #+BEGIN_SRC emacs-lisp :tangle config.el ;; Function to list all my available org agenda files and switch to them (defun list-and-switch-to-agenda-file () "Lists all available agenda files and switches to desired one" (interactive) (setq full-agenda-file-list nil) (setq choice (completing-read "Select agenda file:" org-agenda-files nil t)) (find-file choice)) (map! :leader :desc "Switch to specific org agenda file" "o a s" 'list-and-switch-to-agenda-file) (map! :leader :desc "Open org calendar" "o c" #'cfw:open-org-calendar) (defun org-agenda-switch-with-roam () "Switches to org roam node file and database from org agenda view" (interactive) (org-agenda-switch-to) (if (f-exists-p (concat (dir!) "/org-roam.db")) (org-roam-switch-db (f-filename (f-parent (dir!))) t)) (org-roam-olivetti-mode) ) (map! :map evil-org-agenda-mode-map :after org-agenda :nvmeg "" #'org-agenda-switch-with-roam :nvmeg "" #'org-agenda-switch-with-roam) (map! :map org-agenda-mode-map :after org-agenda :nvmeg "" #'org-agenda-switch-with-roam :nvmeg "" #'org-agenda-switch-with-roam) #+END_SRC *** Org Super Agenda Configuration #+BEGIN_SRC emacs-lisp :tangle config.el (require 'org-super-agenda) (setq org-super-agenda-groups '(;; Each group has an implicit boolean OR operator between its selectors. (:name "Home Tech" :and(:file-path "emmet/Agenda" :not (:tag "event")) :order 3) (:name "Family" :and(:file-path "Family" :not (:tag "event")) :order 3) (:name "Teaching Prep" :and(:file-path "Teaching.p" :tag "planning" :not (:tag "grading") :not (:tag "event")) :order 3) (:name "Teaching Secretarial" :and(:file-path "Teaching.p" :tag "secretarial" :not (:tag "grading") :not (:tag "event")) :order 3) (:name "Teaching Grading" :and(:file-path "Teaching.p" :tag "grading" :not (:tag "planning") :not (:tag "event")) :order 3) (:name "School Side Projects" :and(:file-path "Teaching.p" :tag "tech" :not (:tag "planning") :not (:tag "event")) :order 3) (:name "Gamedev Current Projects" :and (:file-path "Gamedev" :todo "STRT") :order 5) (:name "Youtube" :tag "youtube" :order 6) (:name "Learning" :tag "learning" :order 7) (:name "Today" ; Optionally specify section name :time-grid t :date today :scheduled today :order 1) )) (org-super-agenda-mode t) (map! :desc "Next line" :map org-super-agenda-header-map "j" 'org-agenda-next-line) (map! :desc "Next line" :map org-super-agenda-header-map "k" 'org-agenda-previous-line) #+END_SRC ** Magit Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ magit configuration ------;;; ;; Need the following two blocks to make magit work with git bare repos (defun ~/magit-process-environment (env) "Add GIT_DIR and GIT_WORK_TREE to ENV when in a special directory. https://github.com/magit/magit/issues/460 (@cpitclaudel)." (let ((default (file-name-as-directory (expand-file-name default-directory))) (home (expand-file-name "~/"))) (when (string= default home) (let ((gitdir (expand-file-name "~/.dotfiles.git/"))) (push (format "GIT_WORK_TREE=%s" home) env) (push (format "GIT_DIR=%s" gitdir) env)))) env) (advice-add 'magit-process-environment :filter-return #'~/magit-process-environment) (evil-set-initial-state 'magit-status-mode 'motion) (evil-set-initial-state 'magit-log-mode 'motion) (evil-set-initial-state 'magit-diff-mode 'motion) (evil-set-initial-state 'magit-refs-mode 'motion) (evil-define-key 'motion magit-status-mode-map "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "c" 'magit-commit "s" 'magit-stage "u" 'magit-unstage "l" 'magit-log "F" 'magit-pull "p" 'magit-push "q" '+magit/quit (kbd "") 'magit-diff-visit-file-worktree) (evil-define-key 'motion magit-log-mode-map "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "q" '+magit/quit (kbd "") 'magit-visit-ref) (evil-define-key 'motion magit-diff-mode-map "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "q" '+magit/quit (kbd "") 'magit-visit-ref) (evil-define-key 'motion magit-refs-mode-map "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "q" '+magit/quit (kbd "") 'magit-visit-ref) #+END_SRC ** Ibuffer Configuration #+BEGIN_SRC emacs-lisp :tangle config.el (evil-set-initial-state 'ibuffer-mode 'motion) (evil-define-key 'motion 'ibuffer-mode "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "d" 'ibuffer-mark-for-delete "q" 'kill-buffer (kbd "") 'ibuffer-visit-buffer) #+END_SRC ** Dired Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ dired configuration ------;;; (add-hook 'dired-mode-hook 'all-the-icons-dired-mode) (map! :desc "Increase font size" "C-=" 'text-scale-increase :desc "Decrease font size" "C--" 'text-scale-decrease) #+END_SRC ** Ranger Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ ranger configuration ------;;; (map! :map ranger-mode-map :desc "Mark current file" "m" 'ranger-mark :desc "Toggle mark on current file" "x" 'ranger-toggle-mark :desc "Open ranger" "o d" 'ranger) #+END_SRC ** hledger-mode Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;-- hledger-mode configuration ;;;-- ;;; Basic configuration (require 'hledger-mode) ;; To open files with .journal extension in hledger-mode (add-to-list 'auto-mode-alist '("\\.journal\\'" . hledger-mode)) ;; The default journal location is too opinionated. (setq hledger-jfile "/home/emmet/Org/Family.s/Notes/hledger.journal") ;;; Auto-completion for account names ;; For company-mode users: (add-to-list 'company-backends 'hledger-company) (evil-define-key* 'normal hledger-view-mode-map "q" 'kill-current-buffer) (evil-define-key* 'normal hledger-view-mode-map "[" 'hledger-prev-report) (evil-define-key* 'normal hledger-view-mode-map "]" 'hledger-next-report) (map! :leader :prefix ("l" . "hledger") :desc "Exec hledger command" "c" 'hledger-run-command :desc "Generate hledger balancesheet" "b" 'hledger-balancesheet* :desc "Exec hledger command" "d" 'hledger-daily-report*) (map! :localleader :map hledger-mode-map :desc "Reschedule transaction at point" "d s" 'hledger-reschedule :desc "Edit amount at point" "t a" 'hledger-edit-amount) #+END_SRC ** Tab Bar Configuration I don't have this active right now since it's kinda weird with pgtk... #+BEGIN_SRC emacs-lisp ;;;-- tab-bar-mode configuration ;;;-- ;; Kbd tab navigation (map! :map evil-normal-state-map "H" #'tab-bar-switch-to-prev-tab "L" #'tab-bar-switch-to-next-tab "C-" #'tab-bar-switch-to-prev-tab "C-" #'tab-bar-switch-to-next-tab) (evil-global-set-key 'normal (kbd "C-w") 'tab-bar-close-tab) (evil-global-set-key 'normal (kbd "C-t") 'tab-bar-new-tab) (setq tab-bar-new-tab-choice "*doom*") (tab-bar-mode t) #+END_SRC ** Focus Mode Configuration #+BEGIN_SRC emacs-lisp :tangle config.el (require 'focus) (map! :leader :prefix ("F" . "Focus mode") :desc "Toggle focus mode" "t" 'focus-mode :desc "Pin focused section" "p" 'focus-pin :desc "Unpin focused section" "u" 'focus-unpin) (add-to-list 'focus-mode-to-thing '(org-mode . org-element)) (add-to-list 'focus-mode-to-thing '(python-mode . paragraph)) (add-to-list 'focus-mode-to-thing '(lisp-mode . paragraph)) ;(add-hook 'org-mode-hook #'focus-mode) #+END_SRC ** Helpful Mode Configuration #+BEGIN_SRC emacs-lisp :tangle config.el ;;;------ helpful configuration ------;;; (evil-set-initial-state 'helpful-mode 'normal) (evil-define-key 'normal helpful-mode-map "j" 'evil-next-visual-line "k" 'evil-previous-visual-line "q" 'helpful-kill-buffers) #+END_SRC ** EAF #+BEGIN_SRC emacs-lisp :tangle config.el ;;;-- Load emacs application framework;;;-- (use-package! eaf :load-path "~/.emacs.d/eaf/" :init :custom (eaf-browser-continue-where-left-off t) (eaf-browser-enable-adblocker t) (browse-url-browser-function 'eaf-open-browser) ;; Make EAF Browser my default browser :config (defalias 'browse-web #'eaf-open-browser) (require 'eaf-browser) (require 'eaf-evil) (define-key key-translation-map (kbd "SPC") (lambda (prompt) (if (derived-mode-p 'eaf-mode) (pcase eaf--buffer-app-name ("browser" (if (string= (eaf-call-sync "eval_function" eaf--buffer-id "is_focus") "True") (kbd "SPC") (kbd eaf-evil-leader-key))) (_ (kbd "SPC"))) (kbd "SPC"))))) (setq browse-url-browser-function 'browse-url-default-browser) (map! :leader :desc "Open web browser" "o w" #'eaf-open-browser-with-history) #+END_SRC ** Direnv #+BEGIN_SRC emacs-lisp :tangle config.el ;;;-- Load emacs direnv;;;-- (require 'direnv) (direnv-mode) #+END_SRC ** Projectile #+BEGIN_SRC emacs-lisp :tangle config.el ;;;-- projectile wrapper commands ;;;-- (defun projectile-goto-project () (interactive) (projectile-switch-project t) ;;(neotree-dir (projectile-project-root)) ) (map! :leader :desc "Open project" "p p" #'projectile-goto-project) (map! :leader :desc "Projectile commander" "p @" #'projectile-commander) (map! :leader :desc "Projectile grep" "/" #'projectile-grep) #+END_SRC ** LSP #+BEGIN_SRC emacs-lisp :tangle config.el ;;;-- LSP stuff ;;;-- (use-package lsp-mode :ensure t) (use-package nix-mode :hook (nix-mode . lsp-deferred) :ensure t) (setq lsp-java-workspace-dir "/home/emmet/.local/share/doom/java-workspace") (require 'gdscript-mode) (use-package gdscript-mode :hook (gdscript-mode . lsp-deferred) :ensure t) #+END_SRC ** Terminal #+BEGIN_SRC emacs-lisp :tangle config.el #+END_SRC * My init.el This section is the [[./init.el][init.el]] section, which controls which Doom modules are loaded. =SPC h d h= (vim) or =C-h d h= (non-vim) can be used to access Doom's documentation (including a "Module Index"). =K= (vim) or =C-c c k= (non-vim) can be used to view a module's documentation (this can help you discover module flags as well). =gd= (vim) or =C-c c d= (non-vim) will let you browse a module's directory (source code). #+BEGIN_SRC emacs-lisp :tangle init.el (doom! :input ;;chinese ;;japanese ;;layout ; auie,ctsrnm is the superior home row :completion company ; the ultimate code completion backend ;;helm ; the *other* search engine for love and life ;;ido ; the other *other* search engine... ;;ivy ; a search engine for love and life vertico ; the search engine of the future :ui ;;deft ; notational velocity for Emacs doom ; what makes DOOM look the way it does doom-dashboard ; a nifty splash screen for Emacs doom-quit ; DOOM quit-message prompts when you quit Emacs (emoji +unicode) ; 🙂 hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW ;;hydra ;;indent-guides ; highlighted indent columns ;;ligatures ; ligatures and symbols to make your code pretty again ;;minimap ; show a map of the code on the side modeline ; snazzy, Atom-inspired modeline, plus API nav-flash ; blink cursor line after big motions neotree ; a project drawer, like NERDTree for vim ophints ; highlight the region an operation acts on (popup +defaults) ; tame sudden yet inevitable temporary windows ;;tabs ; a tab bar for Emacs treemacs ; a project drawer, like neotree but cooler unicode ; extended unicode support for various languages vc-gutter ; vcs diff in the fringe vi-tilde-fringe ; fringe tildes to mark beyond EOB window-select ; visually switch windows workspaces ; tab emulation, persistence & separate workspaces ;;zen ; distraction-free coding or writing :editor (evil +everywhere); come to the dark side, we have cookies file-templates ; auto-snippets for empty files fold ; (nigh) universal code folding (format +onsave) ; automated prettiness ;;god ; run Emacs commands without modifier keys ;;lispy ; vim for lisp, for people who don't like vim ;;multiple-cursors ; editing in many places at once ;;objed ; text object editing for the innocent ;;parinfer ; turn lisp into python, sort of ;;rotate-text ; cycle region at point between text candidates snippets ; my elves. They type so I don't have to word-wrap ; soft wrapping with language-aware indent :emacs (dired +ranger) ; making dired pretty [functional] electric ; smarter, keyword-based electric-indent ibuffer ; interactive buffer management undo ; persistent, smarter undo for your inevitable mistakes vc ; version-control and Emacs, sitting in a tree :term eshell ; the elisp shell that works everywhere ;;shell ; simple shell REPL for Emacs ;;term ; basic terminal emulator for Emacs vterm ; the best terminal emulation in Emacs :checkers syntax ; tasing you for every semicolon you forget (spell +flyspell) ; tasing you for misspelling mispelling ;;grammar ; tasing grammar mistake every you make :tools ;;ansible ;;biblio ; Writes a PhD for you (citation needed) ;;debugger ; FIXME stepping through code, to help you add bugs ;;direnv docker ;;editorconfig ; let someone else argue about tabs vs spaces ;;ein ; tame Jupyter notebooks with emacs (eval +overlay) ; run code, run (also, repls) ;;gist ; interacting with github gists lookup ; navigate your code and its documentation (lsp) ; M-x vscode magit ; a git porcelain for Emacs ;;make ; run make tasks from Emacs ;;pass ; password manager for nerds ;;pdf ; pdf enhancements ;;prodigy ; FIXME managing external services & code builders rgb ; creating color strings ;;taskrunner ; taskrunner for all your projects ;;terraform ; infrastructure as code ;;tmux ; an API for interacting with tmux ;;upload ; map local to remote projects via ssh/ftp :os ;;(:if IS-MAC macos) ; improve compatibility with macOS tty ; improve the terminal Emacs experience :lang ;;agda ; types of types of types of types... ;;beancount ; mind the GAAP ;;cc ; C > C++ == 1 ;;clojure ; java with a lisp common-lisp ; if you've seen one lisp, you've seen them all ;;coq ; proofs-as-programs ;;crystal ; ruby at the speed of c ;;csharp ; unity, .NET, and mono shenanigans data ; config/data formats ;;(dart +flutter) ; paint ui and not much else ;;dhall ;;elixir ; erlang done right ;;elm ; care for a cup of TEA? emacs-lisp ; drown in parentheses ;;erlang ; an elegant language for a more civilized age ;;ess ; emacs speaks statistics ;;factor ;;faust ; dsp, but you get to keep your soul ;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER) ;;fsharp ; ML stands for Microsoft's Language ;;fstar ; (dependent) types and (monadic) effects and Z3 (gdscript +lsp) ; the language you waited for ;;(go +lsp) ; the hipster dialect (haskell +lsp) ; a language that's lazier than I am ;;hy ; readability of scheme w/ speed of python ;;idris ; a language you can depend on json ; At least it ain't XML (java +lsp) ; the poster child for carpal tunnel syndrome javascript ; all(hope(abandon(ye(who(enter(here)))))) ;;julia ; a better, faster MATLAB ;;kotlin ; a better, slicker Java(Script) latex ; writing papers in Emacs has never been so fun ;;lean ; for folks with too much to prove ;;ledger ; be audit you can be lua ; one-based indices? one-based indices markdown ; writing docs for people to ignore ;;nim ; python + lisp at the speed of c (nix +lsp) ; I hereby declare "nix geht mehr!" ;;ocaml ; an objective camel (org +roam2) ; organize your plain life in plain text ;;php ; perl's insecure younger brother ;;plantuml ; diagrams for confusing people more ;;purescript ; javascript, but functional python ; beautiful is better than ugly ;;qt ; the 'cutest' gui framework ever ;;racket ; a DSL for DSLs ;;raku ; the artist formerly known as perl6 ;;rest ; Emacs as a REST client ;;rst ; ReST in peace ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} ;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap() ;;scala ; java, but good ;;(scheme +guile) ; a fully conniving family of lisps sh ; she sells {ba,z,fi}sh shells on the C xor ;;sml ;;solidity ; do you need a blockchain? No. ;;swift ; who asked for emoji variables? ;;terra ; Earth and Moon in alignment for performance. web ; the tubes yaml ; JSON, but readable ;;zig ; C, but simpler :email ;;(mu4e +org) ;;notmuch ;;(wanderlust +gmail) :app calendar ;;emms ;;everywhere ; *leave* Emacs!? You must be joking ;;irc ; how neckbeards socialize ;;(rss +org) ; emacs as an RSS reader ;;twitter ; twitter client https://twitter.com/vnought :config ;;literate (default +bindings +smartparens)) #+END_SRC * My packages.el The [[./packages.el][packages.el]] file allows extra packages to be configured outside of the typical Doom modules from [[./init.el][init.el]]. Packages are declared via =(package! some-package)= where =some-package= is from MELPA, ELPA, or emacsmirror. There are other ways to install packages outside of Emacs package archives, including directly from git. Installing a package directly from git requires a =:recipe=. Here is [[https://github.com/raxod502/straight.el#the-recipe-format][a full documentation of the recipe format]]. Doom's built-in packages can also be modified here: - =(package! builtin-package :disable t)= to disable - =(package! builtin-package-2 :recipe (:repo "myfork/package"))= to override the recipe - Side-note: the full recipe for built-in packages does not need specification, as the override will inherit the unspecified properties directly from Doom Any git package can be configured for a particular commit or branch: - =(package! builtin-package :recipe (:branch "develop")= for a particular branch - =(package! builtin-package :pin "1a2b3c4d5e")= for a particular commit - =(unpin! pinned-package another-pinned-package)= to get bleeding edge instead of Doom's stability #+BEGIN_SRC emacs-lisp :tangle packages.el (package! direnv) (package! org-modern) (package! org-super-agenda) (package! emacsql :pin "c1a4407") (package! org-roam-ui) ;;(package! org-roam-nursery :recipe (:repo "https://github.com/chrisbarrett/nursery")) (package! lister) (package! org-download) (package! org-yt) (package! toc-org) (package! all-the-icons-dired) (package! all-the-icons-completion) (package! ox-reveal) (package! hledger-mode) (package! rainbow-mode) (package! crdt) (package! ess) (package! openwith) (package! ob-mermaid) (package! focus) (package! olivetti) #+END_SRC * Nix Integration In order to have Nix load my Doom Emacs configuration [[./doom.nix][doom.nix]], which I source in the =imports= block of my [[../../home.nix][home.nix]]. #+BEGIN_SRC nix :tangle doom.nix { config, lib, pkgs, eaf, eaf-browser, org-nursery, theme, ... }: let themePolarity = lib.removeSuffix "\n" (builtins.readFile (./. + "../../../../themes"+("/"+theme)+"/polarity.txt")); dashboardLogo = ./. + "/nix-" + themePolarity + ".png"; in { services.emacs.enable = true; programs.doom-emacs = { enable = true; emacsPackage = pkgs.emacs29-pgtk; doomPrivateDir = ./.; # This block from https://github.com/znewman01/dotfiles/blob/be9f3a24c517a4ff345f213bf1cf7633713c9278/emacs/default.nix#L12-L34 # Only init/packages so we only rebuild when those change. doomPackageDir = let filteredPath = builtins.path { path = ./.; name = "doom-private-dir-filtered"; filter = path: type: builtins.elem (baseNameOf path) [ "init.el" "packages.el" ]; }; in pkgs.linkFarm "doom-packages-dir" [ { name = "init.el"; path = "${filteredPath}/init.el"; } { name = "packages.el"; path = "${filteredPath}/packages.el"; } { name = "config.el"; path = pkgs.emptyFile; } ]; # End block }; home.file.".emacs.d/themes/doom-stylix-theme.el".source = config.lib.stylix.colors { template = builtins.readFile ./themes/doom-stylix-theme.el.mustache; extension = ".el"; }; home.packages = with pkgs; [ nil nixfmt git file nodejs wmctrl jshon aria hledger hunspell hunspellDicts.en_US-large pandoc nodePackages.mermaid-cli (python3.withPackages (p: with p; [ pandas requests pyqt6 sip qtpy qt6.qtwebengine epc lxml pyqt6-webengine pysocks pymupdf markdown ]))]; home.sessionVariables = { EDITOR = "emacsclient"; }; home.file.".emacs.d/eaf" = { source = "${eaf}"; recursive = true; }; home.file.".emacs.d/eaf/app/browser" = { source = "${eaf-browser}"; recursive = true; onChange = " pushd ~/.emacs.d/eaf/app/browser; rm package*.json; npm install darkreader @mozilla/readability && rm package*.json; popd; "; }; home.file.".emacs.d/org-nursery" = { source = "${org-nursery}"; }; home.file.".emacs.d/dashboard-logo.png".source = dashboardLogo; home.file.".emacs.d/scripts/copy-link-or-file/copy-link-or-file-to-clipboard.sh" = { source = ./scripts/copy-link-or-file/copy-link-or-file-to-clipboard.sh; executable = true; }; } #+END_SRC