| 1 | ;;; $DOOMDIR/config.el -*- lexical-binding: t; -*- |
| 2 | |
| 3 | ;; Place your private configuration here! Remember, you do not need to run 'doom |
| 4 | ;; sync' after modifying this file! |
| 5 | |
| 6 | ;; Some functionality uses this to identify you, e.g. GPG configuration, email |
| 7 | ;; clients, file templates and snippets. It is optional. |
| 8 | ;; (setq user-full-name "John Doe" |
| 9 | ;; user-mail-address "john@doe.com") |
| 10 | |
| 11 | (setq doom-theme 'doom-darkmatter) |
| 12 | (setq display-line-numbers-type "relative") |
| 13 | (setq org-directory "~/org/") |
| 14 | |
| 15 | (after! org |
| 16 | (add-to-list 'org-capture-templates |
| 17 | '("b" "Bookmark" entry (file "bookmarks.org") |
| 18 | "* [[%^{URL}][%^{Title}]] %^g\n:PROPERTIES:\n:ADDED: %U\n:END:\n%?" |
| 19 | :empty-lines 1))) |
| 20 | |
| 21 | ;; ZNC password: read from `pass' (gpg-encrypted), cached in memory per session |
| 22 | (require 'auth-source-pass) |
| 23 | |
| 24 | (defvar my/znc-pass-entry "irc/znc" |
| 25 | "Entry in the password store holding the ZNC password.") |
| 26 | |
| 27 | (defvar my/znc--password nil) |
| 28 | |
| 29 | (defun my/znc-password (&rest _) |
| 30 | (or my/znc--password |
| 31 | (setq my/znc--password |
| 32 | (or (auth-source-pass-get 'secret my/znc-pass-entry) |
| 33 | (user-error "No ZNC password in pass entry %s" my/znc-pass-entry))))) |
| 34 | |
| 35 | (defun my/znc-pass (client) |
| 36 | "Build ZNC server password for CLIENT." |
| 37 | (concat "stevedylandev_@" client "/libera:" (my/znc-password))) |
| 38 | |
| 39 | ;; Prompt before connecting, not mid-handshake |
| 40 | (defadvice! my/irc-ask-password-a (&rest _) |
| 41 | :before #'+irc/connect |
| 42 | (my/znc-password)) |
| 43 | |
| 44 | (set-irc-server! "znc" |
| 45 | `(:host "138.197.115.89" |
| 46 | :port 6697 |
| 47 | :tls t |
| 48 | :nick "stevedylandev_" |
| 49 | :pass ,(lambda (&rest _) (my/znc-pass "emacs")))) |
| 50 | |
| 51 | ;; ERC: same ZNC bouncer, separate client id so sessions don't collide with circe |
| 52 | (after! erc |
| 53 | (setq erc-server "138.197.115.89" |
| 54 | erc-port 6697 |
| 55 | erc-nick "stevedylandev_" |
| 56 | erc-user-full-name "Steve Simkins" |
| 57 | erc-prompt-for-password nil |
| 58 | erc-track-shorten-start 8 |
| 59 | erc-kill-buffer-on-part t |
| 60 | erc-kill-queries-on-quit t |
| 61 | erc-hide-list '("JOIN" "PART" "QUIT"))) |
| 62 | |
| 63 | (defun my/erc-znc () |
| 64 | "Connect ERC to ZNC over TLS." |
| 65 | (interactive) |
| 66 | (erc-tls :server "138.197.115.89" |
| 67 | :port 6697 |
| 68 | :nick "stevedylandev_" |
| 69 | :password (my/znc-pass "erc"))) |
| 70 | |
| 71 | (after! elfeed-org |
| 72 | (setq rmh-elfeed-org-files (list "~/org/elfeed.org"))) |
| 73 | |
| 74 | (defvar my/dashboard-banner-file (expand-file-name "banner.txt" doom-user-dir) |
| 75 | "Text file holding the ASCII banner for the Doom dashboard.") |
| 76 | |
| 77 | (defun my/file-ascii-banner () |
| 78 | (if (file-readable-p my/dashboard-banner-file) |
| 79 | (propertize |
| 80 | (with-temp-buffer |
| 81 | (insert-file-contents my/dashboard-banner-file) |
| 82 | (string-trim-right (buffer-string))) |
| 83 | 'face '+dashboard-banner) |
| 84 | (+dashboard-draw-ascii-banner-fn))) |
| 85 | |
| 86 | (setq +dashboard-ascii-banner-fn #'my/file-ascii-banner) |
| 87 | |
| 88 | (custom-set-faces! |
| 89 | `(+dashboard-banner :foreground ,(doom-color 'white))) |
| 90 | |
| 91 | (setq +dashboard-functions |
| 92 | '(+dashboard-widget-banner |
| 93 | +dashboard-widget-loaded)) |
| 94 | |
| 95 | (add-to-list 'load-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e") |
| 96 | (load! "scripts/posts") |
| 97 | |
| 98 | ;; Make GUI Emacs see Homebrew binaries (mbsync, msmtp, pass, gpg) |
| 99 | (when (memq window-system '(mac ns)) |
| 100 | (exec-path-from-shell-initialize)) ; needs the exec-path-from-shell package |
| 101 | |
| 102 | (require 'mu4e) |
| 103 | |
| 104 | (setq user-mail-address "contact@stevedylan.dev" |
| 105 | user-full-name "Steve Simkins" |
| 106 | |
| 107 | ;; Fetching |
| 108 | mu4e-get-mail-command "mbsync -a" |
| 109 | mu4e-update-interval 300 |
| 110 | mu4e-change-filenames-when-moving t ; required with mbsync |
| 111 | |
| 112 | ;; Folders (adjust to match `mbsync -l local`) |
| 113 | mu4e-sent-folder "/local/Sent" |
| 114 | mu4e-drafts-folder "/local/Drafts" |
| 115 | mu4e-trash-folder "/local/Trash" |
| 116 | mu4e-refile-folder "/local/Archive" |
| 117 | |
| 118 | ;; Sending via msmtp |
| 119 | sendmail-program (executable-find "msmtp") |
| 120 | send-mail-function #'sendmail-send-it |
| 121 | message-send-mail-function #'message-send-mail-with-sendmail |
| 122 | message-sendmail-envelope-from 'header |
| 123 | message-kill-buffer-on-exit t |
| 124 | mu4e-maildir-shortcuts |
| 125 | '((:maildir "/local/Inbox" :key ?i) |
| 126 | (:maildir "/local/Sent" :key ?s) |
| 127 | (:maildir "/local/Drafts" :key ?d) |
| 128 | (:maildir "/local/Archive" :key ?a) |
| 129 | (:maildir "/local/Trash" :key ?t))) |
| 130 | |
| 131 | (after! gptel |
| 132 | (setq gptel-model 'claude-sonnet-5-5 |
| 133 | gptel-backend |
| 134 | (gptel-make-anthropic "Claude" |
| 135 | :stream t |
| 136 | :key #'gptel-api-key |
| 137 | :models '(claude-sonnet-5-5 claude-opus-5-5 claude-haiku-4-5-20251001)))) |
| 138 | |
| 139 | (after! jabber |
| 140 | (setq jabber-account-list |
| 141 | `(("stevedylandev@xmpp.is" |
| 142 | (:password . ,(auth-source-pass-get 'secret "xmpp/stevedylandev@xmpp.is"))))) |
| 143 | (jabber-modeline-mode 1) |
| 144 | (map! :leader "o j" #'jabber-roster)) ; optional binding |