#+title: Doom Literate Config #+author: Preston Pan #+date: <2023-06-09 Fri> #+description: My doom emacs configuration #+html_head: * config.el Configuration This is a doom emacs configuration. If you are not using doom emacs, do not use this document. ** Basic Information My name, and the org mode directory on my computer, as well as basic editor configuration options. Below is the old documentation. #+begin_src emacs-lisp :tangle yes (setq user-full-name "Preston Pan" user-mail-address "preston@nullring.xyz") (setq display-line-numbers-type t) (setq x-select-enable-clipboard t) (setq save-interprogram-paste-before-kill t) (setq yank-pop-change-selection t) (setq org-directory "~/org/") (setq warning-minimum-level :emergency) #+end_src - `load!' for loading external *.el files relative to this one - `add-load-path!' for adding directories to the `load-path', relative to this file. Emacs searches the `load-path' when you load packages with `require' or `use-package'. ** Modeline In order to display the time in the modeline: #+begin_src emacs-lisp :tangle yes (display-time-mode 1) #+end_src To display the battery percentage: #+begin_src emacs-lisp :tangle yes (display-battery-mode 1) #+end_src ** Transparency Let's make emacs transparent. #+begin_src emacs-lisp :tangle yes (set-frame-parameter nil 'alpha-background 90) (add-to-list 'default-frame-alist '(alpha-background . 90)) #+end_src ** EXWM First we load our packages: #+begin_src emacs-lisp :tangle yes ;; (use-package! exwm) ;; (use-package! exwm-config) ;; (exwm-config-example) #+end_src Now, we set our keybindings: #+begin_src emacs-lisp :tangle yes ;; (setq exwm-input-global-keys ;; `( ;; ([?\s-r] . exwm-reset) ;; ([?\s-w] . exwm-workspace-switch) ;; ,@(mapcar (lambda (i) ;; `(,(kbd (format "s-%d" i)) . ;; (lambda () ;; (interactive) ;; (exwm-workspace-switch-create ,i)))) ;; (number-sequence 0 9)) ;; ([?\s-&] . (lambda (command) ;; (interactive (list (read-shell-command "$ "))) ;; (start-process-shell-command command nil command))) ;; ([?\s-d] . (lambda () ;; (interactive) ;; (dired default-directory))) ;; ([?\s-f] . (lambda () ;; (interactive) ;; (exwm-layout-toggle-mode-line) ;; (exwm-workspace-toggle-minibuffer))) ;; ([?\s-b] . exwm-workspace-switch-to-buffer) ;; ([?\s-w] . (lambda () ;; (interactive) ;; (start-process "" nil "qutebrowser"))) ;; ([?\s-n] . (lambda () ;; (interactive) ;; (start-process "" nil "nyxt"))) ;; ([?\s-k] . (lambda () ;; (interactive) ;; (start-process "" nil "krita"))) ;; ([?\s-g] . (lambda () ;; (interactive) ;; (start-process "" nil "gimp"))) ;; ([?\s-b] . (lambda () ;; (interactive) ;; (start-process "" nil "blender"))) ;; ([?\s-c] . (lambda () ;; (interactive) ;; (start-process "" nil "chromium"))) ;; ([s-f2] . (lambda () ;; (interactive) ;; (start-process "" nil "/usr/bin/slock"))))) #+end_src And we also need to set up our media keys: #+begin_src emacs-lisp :tangle yes ;; (exwm-input-set-key (kbd "") 'emms-next) ;; (exwm-input-set-key (kbd "") 'emms-previous) ;; (exwm-input-set-key (kbd "") 'emms-pause) ;; (exwm-input-set-key ;; (kbd "") ;; (lambda () ;; (interactive) (start-process-shell-command ;; "pactl" nil "pactl set-sink-volume 0 +5% && pactl set-sink-volume 1 +5%"))) ;; (exwm-input-set-key ;; (kbd "") ;; (lambda () ;; (interactive) (start-process-shell-command ;; "pactl" nil "pactl set-sink-volume 0 -5% && pactl set-sink-volume 1 -5%"))) ;; (exwm-input-set-key ;; (kbd "") ;; (lambda () ;; (interactive) (start-process-shell-command ;; "pactl" nil "pactl set-sink-mute 0 tog ;; gle && pactl set-sink-mute 1 toggle"))) ;; Things to implement in exwm: ;;Key([], 'XF86MonBrightnessUp', lazy.spawn("light -A 10")), ;;Key([], 'XF86MonBrightnessDown', lazy.spawn("light -U 10")), ;;Key([], "Print", lazy.spawn("scrot '%Y-%m-%d-%s_screenshot_$wx$h.jpg' -e 'mv $f ~/img/scrot")), #+end_src ** Font Now we configure fonts: #+begin_src emacs-lisp :tangle yes (setq doom-font (font-spec :family "Hack" :size 16 :weight 'semi-light) doom-variable-pitch-font (font-spec :family "Fira Sans" :size 16) doom-unicode-font (font-spec :family "Symbola" :size 16) doom-serif-font (font-spec :family "Fira Sans" :size 16) doom-big-font (font-spec :family "Hack" :size 28)) #+end_src ** Color Scheme I'm experimenting with many themes right now. One of these themes is the city-lights theme, another one of them is the catppuccin theme. #+begin_src emacs-lisp :tangle yes ;; (setq doom-theme 'doom-ayu-light) (setq doom-theme 'doom-gruvbox) ;; (setq catppuccin-flavor 'mocha) ;; (load-theme 'catppuccin) #+end_src ** Doom Module and Programs Configuration *** Agenda Now we add these two files to our agenda search path: #+begin_src emacs-lisp :tangle yes (require 'org-habit) (setq org-agenda-files (list "~/org/agenda.org" "~/org/contacts.org" "~/org/notes.org")) (setq org-default-notes-file (concat org-directory "/notes.org")) #+end_src And we also want to set up org-habit to start graphing our habits as soon as possible: #+begin_src emacs-lisp :tangle yes (setq org-habit-preceding-days 1) #+end_src *** IRC Set up circe to connect to my bouncer: #+begin_src emacs-lisp :tangle yes ;; (after! circe ;; (set-irc-server! "nullring.xyz" ;; `(:tls t ;; :port 4095 ;; :nick "LiCoO2/AndreiNet" ;; :user "LiCoO2/AndreiNet" ;; :pass ,(+pass-get-secret "ZNC")))) #+end_src And another to connect to libera: #+begin_src emacs-lisp :tangle yes (after! circe (set-irc-server! "irc.libera.chat" `(:tls t :port 6697 :nick "ret2pop" :sasl-username "ret2pop" :sasl-password (lambda (&rest _) (+pass-get-secret "libera.chat")) :channels ("#emacs" "#rwx")))) #+end_src #+begin_src emacs-lisp :tangle yes (after! circe (set-irc-server! "nullring.xyz" `(:tls t :port 6697 :nick "LiCoO2"))) #+end_src *** Email In order to use this configuration, you must install and configure mu and mbsync. #+begin_src emacs-lisp :tangle yes ;; (setq send-mail-function 'smtpmail-send-it) ;; (setq smtpmail-default-smtp-server "mail.nullring.xyz") ;; (setq smtpmail-smtp-server "mail.nullring.xyz") ;; (setq smtpmail-smtp-service 465) ;; (setq smtpmail-stream-type 'starttls) (require 'smtpmail) (setq send-mail-function 'smtpmail-send-it) (setq smtpmail-smtp-server "mail.nullring.xyz") (setq smtpmail-default-smtp-server "mail.nullring.xyz") (setq smtpmail-smtp-service 465) (setq smtpmail-smtp-user "preston@nullring.xyz") (setq smtpmail-stream-type 'ssl) (setq smtpmail-debug-info t) (setq smtpmail-auth-credentials '(("mail.nullring.xyz" 465 "preston@nullring.xyz" "lO7Y`\"-si\n#+html_head: \n#+html_head: \n#+options: broken-links:t") (`weekly "#+TITLE: Weekly Journal\n#+STARTUP: folded") (`monthly "#+TITLE: Monthly Journal\n#+STARTUP: folded") (`yearly "#+TITLE: Yearly Journal\n#+STARTUP: folded")))) (setq org-journal-file-header 'org-journal-file-header-func) (setq org-journal-file-format "%Y%m%d.org") #+end_src To add everything to the agenda search path, we toggle: #+begin_src emacs-lisp :tangle yes (setq org-journal-enable-agenda-integration t) #+end_src *** Brain I don't use this anymore, but it's good to have. #+begin_src emacs-lisp :tangle yes (setq org-brain-path "~/org/website/brain/") #+end_src *** Roam This is the configuration for my mindmap. #+begin_src emacs-lisp :tangle yes (setq org-roam-graph-viewer "qutebrowser") (setq org-roam-directory (file-truename "~/org/website/mindmap")) (setq org-roam-capture-templates '(("d" "default" plain "%?" :target (file+head "${title}.org" "#+title: ${title}\n#+author: Preston Pan\n#+html_head: \n#+html_head: \n#+html_head: \n#+options: broken-links:t") :unnarrowed t))) #+end_src *** Publishing In order to publish my website, we need to configure emacs to publish it somewhere and with diferrent parameters: #+begin_src emacs-lisp :tangle yes (require 'ox-publish) (setq org-publish-project-alist '(("website-org" :base-directory "~/org/website" :base-extension "org" :publishing-directory "~/website_html" :recursive t :publishing-function org-html-publish-to-html :headline-levels 4 :html-preamble t :html-preamble-format (("en" "

home | section main page


"))) ("website-static" :base-directory "~/org/website" :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|ico" :publishing-directory "~/website_html/" :recursive t :publishing-function org-publish-attachment) ("website" :auto-sitemap t :components ("website-org" "website-static")))) ;; (setq org-export-html-postamble-format '(("en" "

previous page | home

"))) (setq org-html-postamble "Copyright © 2024 Preston Pan") #+end_src *** Contacts Now we configure org-contacts, which allows me to store contacts in an org mode file: #+begin_src emacs-lisp :tangle yes (setq org-contacts-files '("~/org/contacts.org")) #+end_src And then we need to add some templates with org-capture in order to add entries to the contacts easier: #+begin_src emacs-lisp :tangle yes (defvar my/org-contacts-template "* %^{name} :PROPERTIES: :ADDRESS: %^{289 Cleveland St. Brooklyn, 11206 NY, USA} :BIRTHDAY: %^{yyyy-mm-dd} :EMAIL: %^{Email} :NOTE: %^{NOTE} :END:" "Template for org-contacts.") (setq org-capture-templates `(("c" "Contact" entry (file+headline "~/org/contacts.org" "Friends"), my/org-contacts-template :empty-lines 1))) #+end_src *** Org Timer Sometimes I want a timer to help me keep track of the time. #+begin_src emacs-lisp :tangle yes (setq org-clock-sound "~/audio/ding.wav") #+end_src ** External Packages we want to include some packages that don't come with doom emacs. *** KBD-Mode kbd-mode allows us to edit kmonad kbd files with syntax highlighting: #+begin_src emacs-lisp :tangle yes (use-package! kbd-mode) #+end_src *** Pinentry We now set up pinentry for the pass program. We need to set the mode to loopback in order to enable emacs to start itself as a pinentry program, and we need to allow loopbacks in gpg-agent.conf. #+begin_src emacs-lisp :tangle yes (use-package! pinentry :init (setq epa-pinentry-mode `loopback) (pinentry-start)) #+end_src *** Rainbow Mode This is not used currently but might in the future. #+begin_src emacs-lisp :tangle yes (define-globalized-minor-mode global-rainbow-mode rainbow-mode (lambda () (when (not (memq major-mode (list 'org-agenda-mode))) (rainbow-mode 1)))) #+end_src *** Automatically tangle Tangling manually every single time is kind of painful. Instead, we allow ourselves to set a flag in org that allows org to know we should tangle on save: #+begin_src emacs-lisp :tangle yes (use-package! org-auto-tangle :hook (org-mode . org-auto-tangle-mode)) #+end_src *** Notifications We use ednc to manage notifications. #+begin_src emacs-lisp :tangle yes (ednc-mode 1) (defun show-notification-in-buffer (old new) (let ((name (format "Notification %d" (ednc-notification-id (or old new))))) (with-current-buffer (get-buffer-create name) (if new (let ((inhibit-read-only t)) (if old (erase-buffer) (ednc-view-mode)) (insert (ednc-format-notification new t)) (pop-to-buffer (current-buffer))) (kill-buffer))))) (add-hook 'ednc-notification-presentation-functions #'show-notification-in-buffer) (evil-define-key 'normal ednc-view-mode-map (kbd "d") 'ednc-dismiss-notification (kbd "RET") 'ednc-invoke-action (kbd "e") 'ednc-toggle-expanded-view) #+end_src *** Playing Video #+begin_src emacs-lisp :tangle yes (setq empv-invidious-instance "https://yewtu.be/api/v1") #+end_src *** Mastodon #+begin_src emacs-lisp :tangle yes (setq mastodon-instance-url "https://types.pl") (setq mastodon-active-user "ret2pop") #+end_src *** Ement #+begin_src emacs-lisp :tangle yes ;; (ement-connect :uri-prefix "http://localhost:8009") #+end_src *** Stem I wrote a [[https://github.com/ret2pop/stem-mode][major mode]] for my programming language [[https://github.com/ret2pop/stem][stem]]. #+begin_src emacs-lisp :tangle yes (use-package stem-mode) (add-to-list 'auto-mode-alist '("\\.stem\\'" . stem-mode)) #+end_src *** Tufte Our website uses the tufte css styling and we must therefore tell emacs to generate html that is compliant with this html: #+begin_src emacs-lisp (use-package! ox-tufte) (use-package! plan9-theme) #+end_src *** This is supposed to work but it doesn't #+begin_src emacs-lisp (setq org-export-with-section-numbers nil) #+end_src * packages.el Configuration These are some external packages that I use that are not provided by doom modules. #+begin_src emacs-lisp :tangle packages.el (unpin! evil-collection) (package! evil-collection :recipe (:repo "kepi/evil-collection" :branch "mu4e-development")) (package! pinentry) (package! kbd-mode :recipe (:host github :repo "kmonad/kbd-mode")) (package! nasm-mode) (package! org-contrib) (package! exwm) (package! org-auto-tangle) (package! rainbow-mode) (package! ednc) (package! mentor) (package! request) ;; dependency for lemmy client (package! plz) ;; dependency for lemmy client; either request or plz is idk what to use (package! curl-to-elisp) (package! empv) (package! elpher) (package! ement) (package! mastodon) (package! go-translate) (package! ts) (package! chess) (package! ox-tufte) (package! plan9-theme) #+end_src * init.el Configuration This installs all the doom modules that we are going to be configuring: #+begin_src emacs-lisp :tangle init.el (doom! :input ;;bidi ; (tfel ot) thgir etirw uoy gnipleh chinese japanese ;;layout ; auie,ctsrnm is the superior home row :completion company ;;helm ; the *other* search engine for love and life ;;ido ; the other *other* search engine... (ivy +icons +fuzzy) ;; vertico :ui ;;deft ; notational velocity for Emacs doom doom-dashboard doom-quit (emoji +unicode) hl-todo hydra indent-guides (ligatures +extra +fira) minimap modeline ;;nav-flash ; blink cursor line after big motions ;;neotree ; a project drawer, like NERDTree for vim ophints (popup +defaults) ;; tabs treemacs unicode (vc-gutter +pretty) vi-tilde-fringe window-select workspaces zen :editor (evil +everywhere) file-templates fold (format +onsave) ;;god ; run Emacs commands without modifier keys lispy ;;multiple-cursors ; editing in many places at once ;;objed ; text object editing for the innocent parinfer ;;rotate-text ; cycle region at point between text candidates snippets word-wrap :emacs dired electric (ibuffer +icons) undo vc :term eshell ; the elisp shell that works everywhere ;;shell ; simple shell REPL for Emacs ;; term ; basic terminal emulator for Emacs vterm :checkers syntax (spell +flyspell) grammar :tools ;;ansible ;;biblio ; Writes a PhD for you (citation needed) (debugger +lsp) ;;direnv ;;docker editorconfig ein (eval +overlay) gist (lookup +dictionary +offline) lsp magit make pass pdf ;;prodigy ; FIXME managing external services & code builders rgb ;;taskrunner ; taskrunner for all your projects ;;terraform ; infrastructure as code tmux tree-sitter ;;upload ; map local to remote projects via ssh/ftp :os (:if IS-MAC macos) tty :lang ;;agda ; types of types of types of types... ;;beancount ; mind the GAAP (cc +lsp) ;;clojure ; java with a lisp common-lisp ;;coq ; proofs-as-programs ;;crystal ; ruby at the speed of c ;;csharp ; unity, .NET, and mono shenanigans data ;;(dart +flutter) ; paint ui and not much else ;;dhall ;;elixir ; erlang done right ;;elm ; care for a cup of TEA? emacs-lisp ;;erlang ; an elegant language for a more civilized age ess ;;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 ; the language you waited for (go +lsp) ;;(graphql +lsp) ; Give queries a REST (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 +lsp) ;;(java +lsp) ; the poster child for carpal tunnel syndrome (javascript +lsp) ;;julia ; a better, faster MATLAB ;;kotlin ; a better, slicker Java(Script) (latex +lsp +fold +cdlatex) ;;lean ; for folks with too much to prove ;;ledger ; be audit you can be ;;lua ; one-based indices? one-based indices (markdown +grip) ;;nim ; python + lisp at the speed of c nix ;;ocaml ; an objective camel (org +journal +jupyter +gnuplot +brain +pretty +roam2) ;;php ; perl's insecure younger brother ;;plantuml ; diagrams for confusing people more ;;purescript ; javascript, but functional (python +lsp +tree-sitter) ;;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 +lsp) ;;scala ; java, but good (scheme +guile) (sh +fish +lsp) ;;sml solidity ; do you need a blockchain? No. ;;swift ; who asked for emoji variables? ;;terra ; Earth and Moon in alignment for performance. (web +lsp) (yaml +lsp) ;;zig ; C, but simpler :email (mu4e +org) ;;notmuch ;;(wanderlust +gmail) :app calendar emms everywhere irc (rss +org) ;;twitter ; twitter client https://twitter.com/vnought :config literate (default +bindings +smartparens)) #+end_src