/ .emacs.d / readme.org
readme.org
   1  :PROPERTIES:
   2  :ID:       b9359672-0126-4fcd-a3bf-8b0c0dcd4d73
   3  :END:
   4  #+PROPERTY: header-args:emacs-lisp :tangle yes
   5  #+TITLE: Emacs Configuration
   6  * Extra Functionality
   7  :PROPERTIES:
   8  :ID:       2dc993e7-cb89-4ba8-a418-b51464807b6e
   9  :END:
  10  
  11  ** op commandline integration
  12  :PROPERTIES:
  13  :ID:       77e5b779-e31e-4b1c-a864-76f2c4c1a8d0
  14  :END:
  15  
  16  #+begin_src emacs-lisp
  17  (require 'auth-source)
  18  
  19  (defgroup auth-source-op nil
  20    "op (1password command line tool) auth source."
  21    :group 'auth-source
  22    :tag "auth-source-op"
  23    :prefix "op-")
  24  
  25  (defcustom auth-source-op-executable "op"
  26    "op executable to use."
  27    :type 'string
  28    :group 'auth-source-op)
  29  
  30  (cl-defun auth-source-op-search (&rest spec
  31                                         &key _backend _type host _user _port
  32                                         &allow-other-keys)
  33    "query 1password using the op command"
  34    (if (executable-find auth-source-op-executable)
  35        ;; TODO: handle errors :P
  36        (let* ((op-result (string-trim
  37  			 (shell-command-to-string
  38  			  (format "%s item get %s --fields label=username,label=password --reveal --format json"
  39  				  auth-source-op-executable
  40  				  host))))
  41  	     (result (json-parse-string op-result :object-type 'alist :array-type 'list))
  42  	     (user (cdr (assoc 'value (nth 0 result))))
  43  	     (secret (cdr (assoc 'value (nth 1 result)))))
  44  	(list (list :user user
  45  		    :secret secret)))
  46      (warn "`auth-source-op': Couldn't find 'op' executable")))
  47  
  48  (defun auth-source-op-enable ()
  49    "Enable the op auth source."
  50    (add-to-list 'auth-sources 'op)
  51    (auth-source-forget-all-cached))
  52  
  53  (defvar auth-source-op-backend
  54    (auth-source-backend
  55     :source "."
  56     :type 'password-store
  57     :search-function #'auth-source-op-search))
  58  
  59  (defun auth-source-op-backend-parse (entry)
  60    (when (eq entry 'op)
  61      (auth-source-backend-parse-parameters entry auth-source-op-backend)))
  62  
  63  (if (boundp 'auth-source-backend-parser-functions)
  64      (add-hook 'auth-source-backend-parser-functions #'auth-source-op-backend-parse)
  65    (advice-add 'auth-source-backend-parse :before-until #'auth-source-op-backend-parse))
  66  
  67  (provide 'auth-source-op)
  68  #+end_src
  69  
  70  * Literate emacs configuration
  71  :PROPERTIES:
  72  :ID:       63e8f578-4726-47ea-84ee-31146bad6fd2
  73  :END:
  74  
  75  I can never rembember what various configs do. Jumping on this literate emacs
  76  config to see if it helps!
  77  
  78  ** Instance Specific
  79  :PROPERTIES:
  80  :ID:       2b0c380e-411a-4c7a-b4a9-892b0f5f3742
  81  :END:
  82  
  83  Sometimes I need to execute some other things on different machines. This lets
  84  me include an extra file to extend things a bit.
  85  
  86  #+begin_src emacs-lisp
  87    (if (file-exists-p "~/.emacs.d/xin-custom.el")
  88        (progn
  89          (load "~/.emacs.d/xin-custom.el")))
  90  #+end_src
  91  
  92  ** Start the emacs server
  93  :PROPERTIES:
  94  :ID:       fd3e2824-e62c-4812-9919-6b7ed9af0942
  95  :END:
  96  
  97  Starting as a server lets me connect externally to do things like change
  98  themes, save buffers via cron and other such dumbary!
  99  
 100  #+begin_src emacs-lisp
 101  (require 'bind-key)
 102  (load "server")
 103  (unless (server-running-p) (server-start))
 104  #+end_src
 105  
 106  ** Interface and Behavior
 107  :PROPERTIES:
 108  :ID:       c3ba44d8-5c91-454f-98bf-803290f5e2a1
 109  :END:
 110  *** Interface
 111  :PROPERTIES:
 112  :ID:       7ba540d9-275f-4267-9d86-46db134d2c01
 113  :END:
 114  
 115  Global font
 116  #+begin_src emacs-lisp
 117    (set-frame-font "Go Mono 11")
 118  #+end_src
 119  
 120  Use 80 columns, this helps keep things readable when windows are split
 121  #+begin_src emacs-lisp
 122  (setq whitespace-style '(trailing lines space-before-tab)
 123        whitespace-line-column 80)
 124  (setq-default fill-column 80)
 125  #+end_src
 126  
 127  I know I am in emacs, don't need to see the startup screen.
 128  #+begin_src emacs-lisp
 129  (setq inhibit-startup-screen t)
 130  #+end_src
 131  
 132  **** Use UTF8 where ever possible
 133  :PROPERTIES:
 134  :ID:       84a57366-d670-4656-a65b-bb65d0aafd4c
 135  :END:
 136  #+begin_src emacs-lisp
 137  (prefer-coding-system 'utf-8)
 138  (set-default-coding-systems 'utf-8)
 139  (set-terminal-coding-system 'utf-8)
 140  (set-keyboard-coding-system 'utf-8)
 141  #+end_src
 142  
 143  **** Change various UI bits
 144  :PROPERTIES:
 145  :ID:       87e81f85-c239-4381-ba8f-36fbeba9f32f
 146  :END:
 147  #+begin_src emacs-lisp
 148  (tool-bar-mode -1)
 149  (menu-bar-mode -1)
 150  (scroll-bar-mode -1)
 151  (column-number-mode +1)
 152  (global-font-lock-mode 1)
 153  #+end_src
 154  
 155  **** direnv
 156  :PROPERTIES:
 157  :ID:       dfde4ab6-2bfd-4fa1-8e2f-f943dce10c0e
 158  :END:
 159  
 160  #+begin_src emacs-lisp
 161    (use-package direnv
 162      :config
 163      (direnv-mode))
 164  #+end_src
 165  
 166  **** project.el
 167  :PROPERTIES:
 168  :ID:       194d6c86-cb31-4563-820c-efbf72853313
 169  :END:
 170  
 171  #+begin_src emacs-lisp
 172    (setq project-list-file (expand-file-name "~/.emacs.d/projects"))
 173  #+end_src
 174  
 175  **** transient
 176  :PROPERTIES:
 177  :ID:       fff55527-096f-41bd-8aa2-535c089aa06d
 178  :END:
 179  
 180  #+begin_src emacs-lisp
 181    (setq transient-history-file (expand-file-name "~/.emacs.d/transient"))
 182  #+end_src
 183  
 184  **** eww
 185  :PROPERTIES:
 186  :ID:       7a31ea70-4a38-444f-9fbc-e72330d293a9
 187  :END:
 188  
 189  [2025-04-02 Wed] Since switching to rcirc and elfeed.. it's nice to be able to
 190  view links directly in emacs. This sets the default to be eww.. I can use ~&~ to
 191  open in the external browser.
 192  
 193  #+begin_src emacs-lisp
 194    (setq browse-url-browser-function 'eww-browse-url)
 195  #+end_src
 196  
 197  **** scrolly scroll scroll
 198  :PROPERTIES:
 199  :ID:       2daea08b-1cba-4bc8-96ec-0c590f2cf690
 200  :END:
 201  
 202  #+begin_src emacs-lisp
 203    (pixel-scroll-precision-mode)
 204  #+end_src
 205  
 206  
 207  **** wayland copy / paste issues
 208  :PROPERTIES:
 209  :ID:       a17c42f7-e91c-4fb8-9491-88c97d55a0e1
 210  :END:
 211  
 212  [2025-04-18 Fri] it seems I have recently started having issues with wayland and
 213  copy / paste. It works initially - but after some time the buffers diverge.
 214  
 215  The [[https://www.emacswiki.org/emacs/CopyAndPaste#h5o-4][wiki]] has some info on using ~wl-clipboard~ to fix things.
 216  
 217  [2025-08-12 Tue] Update to the what the latest wiki has.. if this doesn't work I
 218  will try setting ~save-interprogram-paste-before-kill~.
 219  
 220  #+begin_src emacs-lisp
 221    (setopt select-active-regions nil)
 222    (setopt select-enable-clipboard 't)
 223    (setopt select-enable-primary nil)
 224    (setopt interprogram-cut-function #'gui-select-text)
 225  #+end_src
 226  
 227  *** Common functionality
 228  :PROPERTIES:
 229  :ID:       837a6def-b743-40f0-8753-9b16bd8416d5
 230  :END:
 231  
 232  #+begin_src emacs-lisp
 233    (defun xin/no-check ()
 234      (interactive)
 235      (setenv "SKIP_CHECK" "1"))
 236  #+end_src
 237  
 238  *** Behavior
 239  :PROPERTIES:
 240  :ID:       9100298b-44d4-4ddc-9d32-b4ce3a04a134
 241  :END:
 242  
 243  Switch various defaults to be more comfortable for myself.
 244  
 245  #+begin_src emacs-lisp
 246    (fset 'yes-or-no-p 'y-or-n-p)
 247    (show-paren-mode t)
 248  
 249    (setq desktop-dirname             "~/.emacs.d/"
 250          desktop-base-file-name      "emacs.desktop"
 251          desktop-base-lock-name      "lock"
 252          desktop-path                (list desktop-dirname)
 253          desktop-save                t
 254          desktop-files-not-to-save   "^$" ;reload tramp paths
 255          desktop-load-locked-desktop nil
 256          desktop-auto-save-timeout   30)
 257    (desktop-save-mode 1)
 258  
 259    (setq backup-directory-alist '(("." . "~/.emacs-saves")))
 260    (setq auto-mode-alist
 261          (append
 262           (list
 263            '("\\.gpg$" . sensitive-minor-mode)
 264            )
 265           auto-mode-alist))
 266    (setq auth-sources
 267          '("/run/secrets/netrc"))
 268  #+end_src
 269  
 270  Use spelling and auto-fill when we are in text mode.
 271  
 272  #+begin_src emacs-lisp
 273  (add-hook 'text-mode-hook (lambda ()
 274  			    (auto-fill-mode 1)
 275  			    (turn-on-flyspell)))
 276  #+end_src
 277  
 278  #+begin_src emacs-lisp
 279    (setq eshell-history-file-name (expand-file-name "~/.emacs.d/eshell/history"))
 280    (use-package eat
 281      :config
 282      (setq eat-kill-buffer-on-exit t)
 283      (add-hook 'eshell-load-hook #'eat-eshell-mode))
 284  #+end_src
 285  ** Unset custom-file
 286  :PROPERTIES:
 287  :ID:       9f381acd-3889-4808-b1c3-96b502c5cfb5
 288  :END:
 289  
 290  The customization file mostly just causes churn in the SCM so we disable it
 291  here.
 292  #+begin_src emacs-lisp
 293  (setq custom-file (make-temp-file ""))
 294  #+end_src
 295  
 296  * Packages
 297  :PROPERTIES:
 298  :ID:       ab08313d-8258-478b-ba7c-f131dc7f56a7
 299  :END:
 300  
 301  ** package-lint
 302  :PROPERTIES:
 303  :ID:       774dca4a-5cb3-4264-806b-8e3fb3ac8671
 304  :END:
 305  
 306  #+begin_src emacs-lisp
 307    (use-package package-lint)
 308  #+end_src
 309  
 310  ** ob-mermaid
 311  :PROPERTIES:
 312  :ID:       867fa1c6-ce4d-4f1e-a60d-4e99c885cd91
 313  :END:
 314  
 315  #+begin_src emacs-lisp
 316    (use-package ob-mermaid)
 317    (use-package mermaid-mode)
 318  #+end_src
 319  
 320  ** yaml
 321  :PROPERTIES:
 322  :ID:       0ea42ef6-f505-4ec5-af59-db8556920f48
 323  :END:
 324  
 325  #+begin_src emacs-lisp
 326    (use-package yaml-mode)
 327  #+end_src
 328  
 329  ** rust-mode
 330  :PROPERTIES:
 331  :ID:       002b3f67-4bbb-40c3-9bc3-1ca9c809b094
 332  :END:
 333  #+begin_src emacs-lisp
 334    (use-package rust-mode)
 335  #+end_src
 336  
 337  ** uxntal
 338  :PROPERTIES:
 339  :ID:       05ac40fb-f95d-45d0-82b0-a94367653bd9
 340  :END:
 341  
 342  #+begin_src emacs-lisp
 343    (use-package uxntal-mode)
 344  #+end_src
 345  
 346  ** breadcrumb
 347  :PROPERTIES:
 348  :ID:       a271e79c-010a-4418-a12d-e7d65c14e085
 349  :END:
 350  
 351  Handy breadcrumbs for seeing where things are in the LSP.
 352  
 353  #+begin_src emacs-lisp
 354    (use-package breadcrumb)
 355  #+end_src
 356  
 357  ** web-mode
 358  :PROPERTIES:
 359  :ID:       96f95d47-78fb-4fa2-88e1-c9e998b163c1
 360  :END:
 361  
 362  #+begin_src emacs-lisp
 363    (use-package web-mode
 364      :config
 365      (setq web-mode-markup-indent-offset 2)
 366      (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
 367      (add-to-list 'auto-mode-alist '("\\.php?\\'" . web-mode))
 368      (add-to-list 'auto-mode-alist '("\\.ts?\\'" . web-mode))
 369      (add-to-list 'auto-mode-alist '("\\.js?\\'" . web-mode)))
 370  #+end_src
 371  
 372  ** scpaste
 373  :PROPERTIES:
 374  :ID:       cb5d91f6-352e-48cf-8304-3cc47c857977
 375  :END:
 376  
 377  Post pastes to https://paste.suah.dev
 378  
 379  #+begin_src emacs-lisp
 380    (use-package scpaste
 381      :config (setq scpaste-scp-destination "suah.dev:/var/www/paste"
 382    		scpaste-http-destination "https://paste.suah.dev"))
 383  #+end_src
 384  
 385  ** htmlize
 386  :PROPERTIES:
 387  :ID:       0975c7dc-bdd1-4358-8a35-65ce1354b3f7
 388  :END:
 389  
 390  This is needed for publishing org stuff
 391  
 392  #+begin_src emacs-lisp
 393    (use-package htmlize)
 394  #+end_src
 395  
 396  ** parchment-theme
 397  :PROPERTIES:
 398  :ID:       75dc99d8-4790-47e2-8a91-7e497406de6c
 399  :END:
 400  This is a nice theme that resembles acme in plan9. Minimal.
 401  
 402  #+begin_src emacs-lisp
 403  (use-package parchment-theme
 404    :config (load-theme 'parchment t))
 405  #+end_src
 406  
 407  ** ivy
 408  :PROPERTIES:
 409  :ID:       587ef327-b68d-423b-842c-3a14a12f07bf
 410  :END:
 411  
 412  ~ivy~ is fantastic. It gives me nice visual search for buffers,
 413  code.. etc. Combined with ~smex~ for sorting (shows last used things first) and
 414  ~counsel~ (extends ivy into various areas like the help stuff).
 415  
 416  #+begin_src emacs-lisp
 417    (use-package counsel)
 418    (setq smex-save-file (expand-file-name "~/.emacs.d/smex.save"))
 419    (use-package smex)
 420    (use-package ivy
 421      :hook (after-init . ivy-mode)
 422      :bind
 423      ("C-s"     . swiper-isearch)
 424      ("M-x"     . counsel-M-x)
 425      ("C-x C-f" . counsel-find-file)
 426      ("C-x b"   . ivy-switch-buffer))
 427  #+end_src
 428  
 429  ** magit
 430  :PROPERTIES:
 431  :ID:       87a444d1-b786-4e2d-8a9d-8e5e43c63206
 432  :END:
 433  
 434  Magit is a awesome. Not sure what else to say about it. :P
 435  
 436  #+begin_src emacs-lisp
 437    (use-package magit
 438      :bind ("C-c m" . magit-status)
 439      :init
 440      (setq magit-completing-read-function 'ivy-completing-read))
 441  
 442    (use-package forge
 443      :after magit)
 444  #+end_src
 445  
 446  ** lsp
 447  :PROPERTIES:
 448  :ID:       7619e01c-121b-497e-8b43-5f548626cfc6
 449  :END:
 450  
 451  Use ~eglot~ for lsp stuff. It's built in and shows a bit more information for
 452  auto-completion stuff.
 453  
 454  #+begin_src emacs-lisp
 455    (use-package paredit
 456      :hook ((scheme-mode
 457    	  elisp-mode
 458              geiser-repl-mode
 459          . paredit-mode)))
 460    (use-package eglot
 461      :config
 462      (add-hook 'elm-mode-hook 'eglot-ensure)
 463      (add-hook 'go-mode-hook 'eglot-ensure)
 464      (add-hook 'haskell-mode-hook 'eglot-ensure)
 465      (add-hook 'lua-mode 'eglot-ensure)
 466      (add-hook 'nix-mode-hook 'eglot-ensure)
 467      (add-hook 'perl-mode-hook 'eglot-ensure)
 468      (add-hook 'ruby-mode-hook 'eglot-ensure)
 469      (add-hook 'rust-mode-hook 'eglot-ensure)
 470      (add-hook 'typescript-mode-hook 'eglot-ensure)
 471  
 472      (add-to-list 'eglot-server-programs '(c-mode    . ("clangd")))
 473      (add-to-list 'eglot-server-programs '(c++-mode  . ("clangd")))
 474      (add-to-list 'eglot-server-programs '(rust-mode . ("rust-analyzer")))
 475  
 476      (define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)
 477      (define-key eglot-mode-map (kbd "C-c f") 'eglot-format)
 478  
 479      :hook
 480      (eglot-managed-mode . (lambda()
 481    			  (add-hook 'before-save-hook 'eglot-format-buffer nil 'local)
 482    			  (flyspell-prog-mode))))
 483  #+end_src
 484  
 485  ** company and friends
 486  :PROPERTIES:
 487  :ID:       7327dc57-0f1d-4cff-80c3-fac203aa2626
 488  :END:
 489  
 490  ~company~ allows for auto-completion of various things. It can interface with ~lsp-mode~ to complete
 491  things like Go.
 492  
 493  #+begin_src emacs-lisp
 494  (use-package company
 495    :config
 496    (setq company-tooltip-limit 20
 497  	company-minimum-prefix-length 1
 498  	company-idle-delay .3
 499  	company-echo-delay 0)
 500    :hook (prog-mode . company-mode))
 501  #+end_src
 502  
 503  ** gitgutter
 504  :PROPERTIES:
 505  :ID:       bd3213fa-acb4-49ef-8f8a-a7710ce4984a
 506  :END:
 507  This gives me a nice in-ui way to see modifications and what not.
 508  
 509  #+begin_src emacs-lisp
 510    (use-package git-gutter
 511      :hook
 512      (after-init . global-git-gutter-mode)
 513      :config
 514      (global-set-key (kbd "C-x g r") 'git-gutter:revert-hunk)
 515      (global-set-key (kbd "C-x g p") 'git-gutter:previous-hunk)
 516      (global-set-key (kbd "C-x g n") 'git-gutter:next-hunk))
 517  #+end_src
 518  
 519  ** shell
 520  :PROPERTIES:
 521  :ID:       45907b9c-125c-4c73-ac4c-2bb2c199a76a
 522  :END:
 523  
 524  I don't often use the shell from emacs, but when I do these bits make it
 525  easier for me to treat it like a regular shell.
 526  
 527  #+begin_src emacs-lisp
 528    ;; Kill terminal buffers on exit so I din't have to kill the buffer after I exit.
 529    (defadvice term-handle-exit
 530        (after term-kill-buffer-on-exit activate)
 531      (kill-buffer))
 532  #+end_src
 533  
 534  
 535  vterm is handy for running things that spit out a lot of escape codes (nom.. etc)
 536  #+begin_src emacs-lisp
 537    (use-package vterm)
 538  #+end_src
 539  
 540  * Language Configurations
 541  :PROPERTIES:
 542  :ID:       4d31b983-3fd6-408f-9488-b2215c005c63
 543  :END:
 544  
 545  ** zig
 546  :PROPERTIES:
 547  :ID:       3185af97-f0b5-4d8f-80b2-85ba2dff8af2
 548  :END:
 549  
 550  #+begin_src emacs-lisp
 551    (use-package zig-mode)
 552  #+end_src
 553  
 554  ** Forth
 555  :PROPERTIES:
 556  :ID:       75ab5012-b901-43ca-aaac-421ff542763c
 557  :END:
 558  
 559  #+begin_src emacs-lisp
 560    (use-package forth-mode)
 561  #+end_src
 562  
 563  ** Ada
 564  :PROPERTIES:
 565  :ID:       0847485a-c6a3-4098-b096-f2dab861a65b
 566  :END:
 567  
 568  #+begin_src emacs-lisp
 569    ;; (use-package ada-mode)
 570  #+end_src
 571  
 572  ** Lua
 573  :PROPERTIES:
 574  :ID:       5bbf0216-a279-419d-a420-9131ed0d56f0
 575  :END:
 576  
 577  #+begin_src emacs-lisp
 578    (use-package lua-mode)
 579  #+end_src
 580  
 581  ** scheme
 582  :PROPERTIES:
 583  :ID:       92990292-8fce-4c3f-92f8-e48b43979cda
 584  :END:
 585  
 586  #+begin_src emacs-lisp
 587    (use-package geiser)
 588    (use-package geiser-guile)
 589    (use-package geiser-racket)
 590  #+end_src
 591  
 592  ** OCaml
 593  :PROPERTIES:
 594  :ID:       d4bee8fb-db63-4ac9-91b7-ab8b3be5e57b
 595  :END:
 596  
 597  #+begin_src emacs-lisp
 598    (use-package ocamlformat
 599      :custom (ocamlformat-enable 'enable-outside-detected-project)
 600      :hook (before-save . ocamlformat-before-save))
 601  
 602    (use-package tuareg
 603       :mode ("\\.ml$" . tuareg-mode))
 604  
 605    (use-package merlin
 606      :config
 607      (add-hook 'tuareg-mode-hook #'merlin-mode))
 608  #+end_src
 609  
 610  ** firewall stuff
 611  :PROPERTIES:
 612  :ID:       b9af3ace-8fef-4239-adc4-24dce2ea04b1
 613  :END:
 614  
 615  *** nftables
 616  :PROPERTIES:
 617  :ID:       7fce62a2-f105-46a6-a001-800e665abf4f
 618  :END:
 619  
 620  #+begin_src emacs-lisp
 621    (use-package nftables-mode)
 622  #+end_src
 623  
 624  ** Shell
 625  :PROPERTIES:
 626  :ID:       a12d920c-d93a-4bee-a643-9e32d796134e
 627  :END:
 628  
 629  #+begin_src emacs-lisp
 630    (use-package shfmt)
 631    (add-hook 'sh-mode-hook 'shfmt-on-save-mode)
 632  #+end_src
 633  
 634  ** Typescript
 635  :PROPERTIES:
 636  :ID:       bf197863-f739-4f67-80a3-e1e583ebb93d
 637  :END:
 638  
 639  #+begin_src emacs-lisp
 640    (use-package typescript-mode)
 641  #+end_src
 642  
 643  ** Nix
 644  :PROPERTIES:
 645  :ID:       b2222546-8d4d-4e6b-8905-0988028e77c2
 646  :END:
 647  
 648  #+begin_src emacs-lisp
 649    (use-package nix-mode
 650      :mode "\\.nix\\'")
 651  #+end_src
 652  
 653  ** Elm
 654  :PROPERTIES:
 655  :ID:       405c6f22-53fc-40c6-8513-334df1c16a39
 656  :END:
 657  
 658  #+begin_src emacs-lisp
 659    (use-package elm-mode)
 660  #+end_src
 661  
 662  ** Haskell
 663  :PROPERTIES:
 664  :ID:       8e14edd0-7e70-42a2-b69c-ffe19a69930e
 665  :END:
 666  
 667  #+begin_src emacs-lisp
 668    (use-package haskell-mode)
 669  #+end_src
 670  
 671  ** Go
 672  :PROPERTIES:
 673  :ID:       ff95f843-b8cd-4e07-985a-c2a4ee3896bb
 674  :END:
 675  
 676  *** go-add-tags
 677  :PROPERTIES:
 678  :ID:       3e152be1-4c73-4d67-a4ea-386ae537d3c4
 679  :END:
 680  
 681  This lets one select a ~struct~ or similar and auto add the ~`json:"NAME"`~ bits.
 682  
 683  #+begin_src emacs-lisp
 684    (use-package go-add-tags)
 685  #+end_src
 686  
 687  *** go-mode
 688  :PROPERTIES:
 689  :ID:       72c1f87f-1c69-470f-b7a9-5a3642eaa4a2
 690  :END:
 691  
 692  This allows for things like ~gofmt~ and auto adding / removing of imports.
 693  
 694  #+begin_src emacs-lisp
 695    (use-package go-mode
 696      :bind
 697      ("C-c t" . go-add-tags))
 698    (defun xin/eglot-organize-imports () (interactive)
 699           (eglot-code-actions nil nil "source.organizeImports" t))
 700    (defun xin/lsp-go-install-save-hooks ()
 701      (add-hook 'before-save-hook 'xin/eglot-organize-imports nil t))
 702    (add-hook 'go-mode-hook #'xin/lsp-go-install-save-hooks)
 703  #+end_src
 704  
 705  *** go-eldoc
 706  :PROPERTIES:
 707  :ID:       88db5063-f22c-4b0d-b6e1-e1fb3c64bced
 708  :END:
 709  
 710  This extends eldoc to be able to speak Go - quite handy for quickly looking
 711  up what things do.
 712  
 713  #+begin_src emacs-lisp
 714  (use-package go-eldoc
 715    :hook
 716    (go-mode . go-eldoc-setup))
 717  #+end_src
 718  
 719  * org-mode
 720  :PROPERTIES:
 721  :ID:       9609380e-e2d0-48f6-a240-f67acca87d15
 722  :END:
 723  
 724  Oh ~org-mode~. It's the reason I started using emacs.. and it's the reason I
 725  can't quit!
 726  
 727  ** Config
 728  :PROPERTIES:
 729  :ID:       b8cfd8d3-1422-4cf8-b284-aea6ae701bdd
 730  :END:
 731  #+begin_src emacs-lisp
 732    (require 'org-crypt)
 733    (require 'org-id)
 734    (org-crypt-use-before-save-magic)
 735    (setq org-tags-exclude-from-inheritance '("crypt"))
 736    (setq org-crypt-key "35863350BFEAC101DB1A4AF01F81112D62A9ADCE")
 737  
 738    (defun xin/org-add-ids ()
 739      "Add ID properties to org files"
 740      (interactive)
 741      (org-map-entries 'org-id-get-create))
 742  
 743    (org-babel-do-load-languages
 744     'org-babel-load-languages
 745     '((plantuml . t)
 746       (dot      . t)
 747       (shell    . t)
 748       (latex    . t)))
 749  #+end_src
 750  ** Publish bits
 751  :PROPERTIES:
 752  :ID:       792ab95b-b796-4c25-a675-4845ffae1462
 753  :END:
 754  
 755  I publish some of my notes [[https://suah.dev/p][on suah.dev/p]]. Also some recipes.
 756  
 757  #+begin_src emacs-lisp
 758    (setq org-export-with-broken-links t)
 759  
 760    (defun xin/exo-touch-and-publish (plist filename dir)
 761      (progn
 762        (set-file-times "~/org-roam/index.org")
 763        (org-html-publish-to-html plist filename dir)))
 764  
 765    (setq my-org-publish-alist
 766          '(("exo" :components ("org-roam" "org-roam-static" "org-roam-org"))
 767    	("bolddaemon" :components ("bolddaemon-web" "bolddaemon-static"))
 768    	("notes" :components ("org-notes" "notes-static" "notes-rss"))
 769    	("deftly" :components ("deftly-blog" "deftly-static"))
 770    	("ohmyksh" :components ("ohmy-web" "ohmy-static"))
 771    	("org-roam"
 772    	 :publishing-directory "/ssh:suah.dev:/var/www/exo.suah.dev/"
 773    	 :recursive t
 774    	 :html-link-home "http://exo.suah.dev/"
 775    	 :html-link-up "../"
 776    	 :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />"
 777    	 :publishing-function xin/exo-touch-and-publish
 778    	 :base-directory "~/org-roam")
 779    	("org-roam-org"
 780    	 :publishing-directory "/ssh:suah.dev:/var/www/exo.suah.dev/"
 781    	 :publishing-function org-org-publish-to-org
 782    	 :recursive t
 783    	 :base-directory "~/org-roam")
 784    	("org-roam-static"
 785    	 :base-directory "~/org-roam"
 786    	 :recursive t
 787    	 :publishing-directory "/rsync:suah.dev:/var/www/exo.suah.dev/"
 788    	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|svg"
 789    	 :publishing-function org-publish-attachment)
 790    	("org-roam-rss"
 791    	 :publishing-directory "/ssh:suah.dev:/var/www/exo.suah.dev/"
 792    	 :publishing-function org-rss-publish-to-rss
 793    	 :rss-extension "xml"
 794    	 :base-directory "~/org-roam")
 795    	("org-notes"
 796    	 :auto-preamble t
 797    	 :auto-sitemap t
 798    	 :headline-levels 4
 799    	 :publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
 800    	 :publishing-function org-html-publish-to-html
 801    	 :recursive t
 802    	 :section-numbers nil
 803    	 :html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
 804    	 :html-link-home "http://suah.dev/p/"
 805    	 :html-link-up "../"
 806    	 :style-include-default nil
 807    	 :sitemap-filename "index.org"
 808    	 :sitemap-title "Notes"
 809    	 :with-title t
 810    	 :author-info nil
 811    	 :creator-info nil
 812    	 :base-directory "~/org/notes")
 813    	("deftly-blog"
 814    	 :auto-preamble t
 815    	 :auto-sitemap t
 816    	 :headline-levels 1
 817    	 :publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
 818    	 :publishing-function org-html-publish-to-html
 819    	 :recursive t
 820    	 :section-numbers nil
 821    	 :html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/new/css/stylesheet.css\" type=\"text/css\" />"
 822    	 :html-link-home "http://deftly.net/new"
 823    	 :html-link-up "../"
 824    	 :style-include-default nil
 825    	 :sitemap-title "Deftly.net"
 826    	 :with-title t
 827    	 :author-info t
 828    	 :creator-info nil
 829    	 :base-directory "~/org/deftly")
 830    	("ohmy-web"
 831    	 :auto-preamble t
 832    	 :auto-sitemap nil
 833    	 :headline-levels 2
 834    	 :publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
 835    	 :publishing-function org-html-publish-to-html
 836    	 :recursive t
 837    	 :section-numbers nil
 838    	 :html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/ohmyksh/css/stylesheet.css\" type=\"text/css\" />"
 839    	 :html-link-home "http://deftly.net/ohmyksh"
 840    	 :html-link-up "../"
 841    	 :style-include-default nil
 842    	 :with-title t
 843    	 :author-info t
 844    	 :creator-info nil
 845    	 :base-directory "~/src/ohmyksh")
 846    	("notes-static"
 847    	 :base-directory "~/org/notes"
 848    	 :publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
 849    	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|svg"
 850    	 :recursive t
 851    	 :publishing-function org-publish-attachment)
 852    	("deftly-static"
 853    	 :base-directory "~/org/deftly"
 854    	 :publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
 855    	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
 856    	 :recursive t
 857    	 :publishing-function org-publish-attachment)
 858    	("ohmy-static"
 859    	 :base-directory "~/src/ohmyksh"
 860    	 :publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
 861    	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
 862    	 :recursive t
 863    	 :publishing-function org-publish-attachment)
 864    	("notes-rss"
 865    	 :publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
 866    	 :publishing-function org-rss-publish-to-rss
 867    	 :recursive t
 868    	 :rss-extension "xml"
 869    	 :section-numbers nil
 870    	 :exclude ".*"
 871    	 :include ("index.org")
 872    	 :table-of-contents nil
 873    	 :base-directory "~/org/notes")
 874    	("recipes"
 875    	 :auto-preamble t
 876    	 :auto-sitemap t
 877    	 :headline-levels 4
 878    	 :publishing-directory "/ssh:suah.dev:/var/www/suah.dev/recipes/"
 879    	 :publishing-function org-html-publish-to-html
 880    	 :recursive t
 881    	 :section-numbers nil
 882    	 :html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
 883    	 :html-link-home "http://suah.dev/recipes/"
 884    	 :html-link-up "../"
 885    	 :style-include-default nil
 886    	 :sitemap-filename "index.org"
 887    	 :sitemap-title "Recipes"
 888    	 :with-title t
 889    	 :author-info nil
 890    	 :creator-info nil
 891    	 :base-directory "~/org/recipes")
 892    	("bolddaemon-web"
 893    	 :auto-preamble t
 894    	 :auto-sitemap t
 895    	 :headline-levels 4
 896    	 :publishing-directory "/ssh:suah.dev:/var/www/bolddaemon.com/"
 897    	 :publishing-function org-html-publish-to-html
 898    	 :recursive t
 899    	 :section-numbers nil
 900    	 :html-link-home "http://bolddaemon.com"
 901    	 :html-link-up "../"
 902    	 :html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\" />"
 903    	 :style-include-default nil
 904    	 :with-title t
 905    	 :author-info nil
 906    	 :creator-info nil
 907    	 :base-directory "~/org/bold.daemon")
 908    	("bolddaemon-static"
 909    	 :base-directory "~/org/bold.daemon"
 910    	 :publishing-directory "/ssh:suah.dev:/var/www/bolddaemon.com/"
 911    	 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
 912    	 :recursive t
 913    	 :publishing-function org-publish-attachment)
 914    	))
 915  #+end_src
 916  
 917  ** Capture templates
 918  :PROPERTIES:
 919  :ID:       da112c38-c9c6-4579-ba42-8ea6dc4ce0b7
 920  :END:
 921  
 922  #+begin_src emacs-lisp
 923    (setq my-org-capture-templates
 924          `(("t" "TODO"
 925    	 entry (file+headline "~/org/todo.org" "TODOs")
 926    	 ,(concat
 927    	   "* TODO %?\n"
 928    	   ":PROPERTIES:\n"
 929    	   ":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
 930    	   ":END:\n") :prepend t)
 931    	("f" "TODO with File"
 932    	 entry (file+headline "~/org/todo.org" "TODOs")
 933    	 ,(concat
 934    	   "* TODO %?\n"
 935    	   ":PROPERTIES:\n"
 936    	   ":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
 937    	   ":END:\n"
 938    	   "%i\n  %a") :prepend t)
 939    	("b" "Bug"
 940    	 entry (file+olp+datetree "~/org/bugs.org" "Bugs")
 941    	 "* BUG %?\nEntered on %U\n  :PROPERTIES:\n  :FILE: %a\n  :END:\n" :prepend t)
 942    	("p" "Protocol"
 943    	 entry (file+headline "~/org/links.org" "Links")
 944    	 "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")
 945    	("L" "Protocol Link" entry (file+headline "~/org/links.org" "Links")
 946    	 "* %? %:link\n%:description\n")
 947    	("j" "Journal"
 948    	 entry (file+olp+datetree "~/org/journal.org")
 949    	 "* %?\nEntered on %U\n  %i\n")
 950    	("P" "Process Soon" entry (file+headline "~/org/todo.org" "TODOs")
 951    	 "* TODO %:fromname: %a %?\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))")))
 952  #+end_src
 953  
 954  ** org
 955  :PROPERTIES:
 956  :ID:       8ca36457-ab66-4ffc-bd18-903efcc63f1a
 957  :END:
 958  
 959  #+begin_src emacs-lisp
 960    (use-package org
 961      :hook
 962      (org-mode . (lambda ()
 963                    (turn-on-flyspell)
 964                    (auto-revert-mode)
 965                    (auto-fill-mode 1)))
 966      :bind
 967      ("C-c c" . org-capture)
 968      ("C-c p" . org-publish)
 969      ("C-c l" . org-store-link)
 970      ("C-c a" . org-agenda)
 971      ("C-c b" . org-iswitchb)
 972      :config
 973      (load-library "find-lisp")
 974      (setq org-directory "~/org"
 975            org-agenda-files (find-lisp-find-files "~/org" "\.org$")
 976            org-startup-indented t
 977            org-log-done 'time
 978            org-export-with-sub-superscripts nil
 979            org-html-inline-images t
 980            org-log-into-drawer t
 981            org-src-tab-acts-natively t
 982            org-agenda-skip-scheduled-if-deadline-is-shown t
 983            org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)")
 984                                (sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")
 985                                (sequence "|" "CANCELED(c)")))
 986      (setq org-publish-project-alist my-org-publish-alist)
 987      (setq org-capture-templates my-org-capture-templates)
 988      (add-hook 'org-mode-hook (lambda ()
 989    			     (add-hook 'before-save-hook 'xin/org-add-ids nil 'local))))
 990    (use-package org-contrib)
 991    (use-package ox-rss)
 992  #+end_src
 993  
 994  *** Extra bits
 995  :PROPERTIES:
 996  :ID:       98e84516-59ad-4441-b541-baa174ffdf24
 997  :END:
 998  #+begin_src emacs-lisp
 999  (use-package org-journal
1000    :defer t
1001    :config
1002    (setq org-journal-dir "~/org/journal/"
1003  	org-journal-file-format "%Y/%m-%d"
1004  	org-journal-date-format "%A, %d %B %Y"))
1005  #+end_src
1006  
1007  Add in some org-mode helpers:
1008  
1009  - ~org-habit~ lets me keep track of TODOs and other things.
1010  - ~org-checklist~ lets me reset checklists for reoccurring tasks.
1011    - This requires one to ~pkg_add a2ps~.
1012    - ~RESET_CHECK_BOXES~ property to be set to ~t~ on a task
1013      headline. properties can be set via ~C-c C-x d~
1014  #+begin_src emacs-lisp
1015    (require 'org-habit)
1016    (require 'org-checklist)
1017  #+end_src
1018  
1019  Custom agenda commands for various things.
1020  
1021  - ~Daily habits~ shows how well I am keeping track of daily things.
1022  #+begin_src emacs-lisp
1023  (setq org-agenda-custom-commands
1024        '(("h" "Daily habits"
1025  	 ((agenda ""))
1026  	 ((org-agenda-show-log t)
1027  	  (org-agenda-ndays 7)
1028  	  (org-agenda-log-mode-items '(state))))))
1029  #+end_src
1030  
1031  **** org-roam
1032  :PROPERTIES:
1033  :ID:       6af98b92-9562-46ac-8f14-0a5792ebb620
1034  :END:
1035  
1036  It took me a few tries to get used to using org-roam. I think I was over
1037  complicating using it.
1038  
1039  #+begin_src emacs-lisp
1040    (use-package org-roam
1041      :after org
1042      :custom
1043      (org-roam-directory (file-truename "~/org-roam/"))
1044      (org-roam-capture-templates
1045       '(("d" "default" plain
1046          "%?"
1047          :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n")
1048          :unnarrowed t)
1049         ("b" "book" plain
1050          "- Author: /%^{Author}/\n- Year: /%^{Year}/\n\n* Highlights / Notes\n"
1051          :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+filetags: :Book:\n")
1052          :unnarrowed t)
1053         ))
1054      :bind (("C-c n l" . org-roam-buffer-toggle)
1055    	 ("C-c n f" . org-roam-node-find)
1056    	 ("C-c n g" . org-roam-graph)
1057    	 ("C-c n r" . org-roam-ref-add)
1058    	 ("C-c n s" . org-roam-db-sync)
1059    	 ("C-c n t" . org-roam-tag-add)
1060    	 ("C-c n i" . org-roam-node-insert)
1061    	 ("C-c n c" . org-roam-capture)
1062    	 ("C-c n j" . org-roam-dailies-capture-today))
1063      :config
1064      (org-roam-db-autosync-enable)
1065      (setq org-roam-completion-everywhere t)
1066      (setq org-roam-node-display-template
1067    	(concat "${title:40} "
1068    		(propertize "${tags:40}" 'face 'org-tag)
1069    		"${file}"))
1070      (require 'org-roam-protocol))
1071  #+end_src
1072  
1073  Extending org with the ability to transclude makes for a powerhouse!
1074  #+begin_src emacs-lisp
1075    (use-package org-transclusion
1076      :after org
1077      :config
1078      (setq org-transclusion-exclude-elements '(keyword property-drawer)))
1079  #+end_src
1080  
1081  
1082  #+begin_src emacs-lisp
1083    (use-package request)
1084    ;; (use-package org-social)
1085  #+end_src
1086  
1087  **** Presentations in plain old org-mode \o/
1088  :PROPERTIES:
1089  :ID:       d90bf8e9-da87-4794-826a-f0d291f3955c
1090  :END:
1091  
1092  #+begin_src emacs-lisp
1093    (use-package epresent)
1094    #+end_src
1095  * RSS
1096  :PROPERTIES:
1097  :ID:       842027db-4e8a-4d9b-80c9-b8fb7825a078
1098  :END:
1099  
1100  #+begin_src emacs-lisp
1101    (use-package elfeed)
1102    (use-package elfeed-protocol
1103      :after elfeed
1104      :config
1105      (setq elfeed-protocol-feeds '(("fever+https://qbit@rss.bolddaemon.com"
1106    				 :password (auth-info-password
1107    					    (nth 0 (auth-source-search :max 1 :host "rss.bolddaemon.com" :require '(:secret))))
1108    				 :api-url "https://rss.bolddaemon.com/fever/")))
1109      (setq elfeed-protocol-enabled-protocols '(fever))
1110      (elfeed-protocol-enable)
1111      (defun xin/elfeed-update-feeds ()
1112        (interactive)
1113        (elfeed-protocol-fever-reinit "https://qbit@rss.bolddaemon.com")
1114        (elfeed-update))
1115      (define-key elfeed-search-mode-map (kbd "U") 'xin/elfeed-update-feeds))
1116  #+end_src
1117  
1118  * Mail
1119  :PROPERTIES:
1120  :ID:       428ef069-6c97-4fb9-83c2-f5f2bcea69c5
1121  :END:
1122  
1123  ** gnus
1124  :PROPERTIES:
1125  :ID:       01bfd3e1-9b66-43e0-806a-850cf14e791d
1126  :END:
1127  
1128  [2024-08-22 Thu] Might need to switch go gnus. mu4e has been not showing new
1129  mail for some things and having to sync state between two sources is a pita.
1130  
1131  #+begin_src emacs-lisp
1132    (setq gnus-use-cache t
1133          gnus-use-full-window nil
1134          gnus-suppress-duplicates t
1135          gnus-inhibit-startup-message t
1136          gnus-asynchronous t
1137          gnus-sum-thread-tree-false-root ""
1138          gnus-sum-thread-tree-indent " "
1139          gnus-sum-thread-tree-leaf-with-other "├► "
1140          gnus-sum-thread-tree-root ""
1141          gnus-sum-thread-tree-single-leaf "╰► "
1142          gnus-sum-thread-tree-vertical "│"
1143          gnus-summary-line-format "%U%R%z %(%&user-date>;  %-15,15f  %B%s%)\n"
1144          gnus-summary-thread-gathering-function 'gnus-gather-threads-by-references
1145          gnus-thread-sort-functions '(gnus-thread-sort-by-date)
1146          gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M"))
1147          gnus-select-method '(nntp "news.gmane.io"))
1148  #+end_src
1149  
1150  * mu4e
1151  :PROPERTIES:
1152  :ID:       eb029614-075a-4f8d-8f64-583667bbaccc
1153  :END:
1154  ~mu~ has been the best mail client for me on emacs.
1155  ** Initializing mu
1156  :PROPERTIES:
1157  :ID:       1d7e1d28-0577-47c2-b066-486ec34c1051
1158  :END:
1159  The defaults ~mu~ uses make no sense. ~~/.cache~ is for .. caching data, not
1160  persistent databases.. So we init things with sane defaults:
1161  #+begin_src shell
1162  mu init --muhome=/home/qbit/.mu -m /home/qbit/Maildir/fastmail/ --my-address="aaron@bolddaemon.com"
1163  #+end_src
1164  
1165  ** OpenBSD specific bits
1166  :PROPERTIES:
1167  :ID:       f9677956-15c6-42e9-aa62-524ea043a90e
1168  :END:
1169  
1170  #+begin_src emacs-lisp
1171    (if (file-exists-p "/usr/local/share/emacs/site-lisp/mu4e/mu4e.el")
1172        (load "/usr/local/share/emacs/site-lisp/mu4e/mu4e.el"))
1173    (if (file-exists-p "/usr/share/emacs/site-lisp/elpa-src/mu4e-1.12.14/mu4e.el")
1174        (load "/usr/share/emacs/site-lisp/elpa-src/mu4e-1.12.14/mu4e.el"))
1175  #+end_src
1176  
1177  ** mu4e specific configs
1178  :PROPERTIES:
1179  :ID:       92d0499c-592e-4992-b67a-d1c8646e2b6b
1180  :END:
1181  #+begin_src emacs-lisp
1182    (use-package mu4e
1183      :init
1184      (setq mail-user-agent 'mu4e-user-agent
1185            read-mail-command 'mu4e
1186    	mu4e-maildir "~/Maildir"
1187            mu4e-get-mail-command "mbsync -a"
1188    	mu4e-change-filenames-when-moving t
1189            mu4e-update-interval 420
1190            mu4e-compose-context-policy nil
1191            mu4e-context-policy 'pick-first
1192            mu4e-drafts-folder "/Drafts"
1193            mu4e-sent-folder   "/Sent Items"
1194            mu4e-trash-folder  "/Trash"
1195            mu4e-maildir-shortcuts
1196            '( ("/fastmail/Inbox"        . ?i)
1197               ("/fastmail/Archive"      . ?a)
1198               ("/segfault/Inbox"        . ?s))
1199            org-mu4e-link-query-in-headers-mode nil
1200            mu4e-attachment-dir
1201            (lambda (fname mtype)
1202              (cond
1203               ((and fname (string-match "\\.diff$" fname))  "~/patches")
1204               ((and fname (string-match "\\.patch$" fname))  "~/patches")
1205               ((and fname (string-match "\\.diff.gz$" fname))  "~/patches")
1206               (t "~/Downloads")))
1207    	mu4e-contexts (list
1208    		       (make-mu4e-context
1209    			:name "Fastmail"
1210    			:match-func
1211    			(lambda (msg)
1212    			  (when msg
1213    			    (string-prefix-p "/fastmail" (mu4e-message-field msg :maildir))))
1214    			:vars '((user-mail-address   . "aaron@bolddaemon.com")
1215    				(mu4e-drafts-folder . "/fastmail/Drafts")
1216    				(mu4e-sent-folder   . "/fastmail/Sent Items")
1217    				(mu4e-refile-foldir . "/fastmail/Archive")))
1218    		       (make-mu4e-context
1219    			:name "Segfault"
1220    			:match-func
1221    			(lambda (msg)
1222    			  (when msg
1223    			    (string-prefix-p "/segfault" (mu4e-message-field msg :maildir))))
1224    			:vars '((user-mail-address   . "qbit@segfault.rodeo")
1225    				(mu4e-drafts-folder . "/segfault/Drafts")
1226    				(mu4e-sent-folder   . "/segfault/Sent")
1227    				(mu4e-refile-folder . "/segfault/Archive"))))
1228  
1229            mu4e-bookmarks `(( :name "Fastmail Inbox"
1230    			   :query "maildir:/fastmail/Inbox AND NOT flag:trashed"
1231    			   :key ?f)
1232    			 ( :name "Segfault Inbox"
1233    			   :query "maildir:/segfault/Inbox AND NOT flag:trashed"
1234    			   :key ?s)
1235    			 ( :name "TODO"
1236    			   :query "maildir:/fastmail/TODO AND NOT flag:trashed"
1237    			   :key ?T)
1238    			 ( :name  "Unread messages"
1239    			   :query "flag:unread AND NOT flag:trashed AND NOT list:ports-changes.openbsd.org AND NOT list:source-changes.openbsd.org"
1240    			   :key ?u)
1241    			 ( :name  "Today's messages"
1242    			   :query "date:today..now"
1243    			   :key ?d)
1244    			 ( :name  "Last 7 days"
1245    			   :query "date:6d..now AND NOT flag:trashed AND NOT list:ports-changes.openbsd.org AND NOT list:source-changes.openbsd.org"
1246    			   :key ?w)
1247    			 ( :name  "Hackers"
1248    			   :query "list:hackers.openbsd.org AND NOT flag:trashed"
1249    			   :key ?h)
1250    			 ( :name   "Bugs"
1251    			   :query  "list:bugs.openbsd.org AND NOT flag:trashed"
1252    			   :key ?b)
1253    			 ( :name  "Tech"
1254    			   :query "list:tech.openbsd.org AND NOT flag:trashed"
1255    			   :key ?t)
1256    			 ( :name  "Ports"
1257    			   :query "list:ports.openbsd.org AND NOT flag:trashed"
1258    			   :key ?p)
1259    			 ( :name "Misc"
1260    			   :query "list:misc.openbsd.org AND NOT flag:trashed"
1261    			   :key ?m)
1262    			 ( :name "9front"
1263    			   :query "list:9front.9front.org AND NOT flag:trashed"
1264    			   :key ?9)
1265    			 ( :name "GOT"
1266    			   :query "list:gameoftrees.openbsd.org AND NOT flag:trashed"
1267    			   :key ?g))))
1268    (add-to-list 'display-buffer-alist
1269                 `(,(regexp-quote mu4e-main-buffer-name)
1270                   display-buffer-same-window))
1271    (define-key mu4e-headers-mode-map (kbd "C-c c") 'mu4e-org-store-and-capture)
1272    (define-key mu4e-view-mode-map    (kbd "C-c c") 'mu4e-org-store-and-capture)
1273  #+end_src
1274  
1275  ** SMTP
1276  :PROPERTIES:
1277  :ID:       5b48d1b9-2fcd-475c-a9c8-51e4fcc5f454
1278  :END:
1279  
1280  #+begin_src emacs-lisp
1281    (require 'smtpmail)
1282    (setq user-mail-address              "aaron@bolddaemon.com"
1283          user-full-name                 "Aaron Bieber"
1284          message-send-mail-function     'smtpmail-send-it
1285          message-kill-buffer-on-exit    t
1286          smtpmail-smtp-user             "qbit@fastmail.com"
1287          smtpmail-smtp-server           "smtp.fastmail.com"
1288          smtpmail-smtp-service          465
1289          smtpmail-default-smtp-server   "smtp.fastmail.com"
1290          smtpmail-stream-type           'ssl)
1291  #+end_src
1292  
1293  * Chat
1294  :PROPERTIES:
1295  :ID:       056f6b1e-0174-49c7-97ae-3e691a077a4c
1296  :END:
1297  
1298  ** IRC
1299  :PROPERTIES:
1300  :ID:       088a5a76-c22e-419b-a6b5-f514f6e2ddc5
1301  :END:
1302  
1303  #+begin_src emacs-lisp
1304    (setq
1305     rcirc-fill-column 'frame-width
1306     rcirc-default-nick "qbit"
1307     rcirc-default-port 6697
1308     rcirc-default-full-name "Qbit"
1309     rcirc-reconnect-delay 10
1310     rcirc-reconnect-attempts 5
1311     rcirc-server-alist
1312     '(("bounce.bold.daemon"
1313        :server-alias "bTyrfingr"
1314        :encryption tls
1315        :user-name "qbit@rcirc.europa/Tyrfingr")
1316       ("bounce.bold.daemon"
1317        :server-alias "bLibera"
1318        :encryption tls
1319        :user-name "qbit@rcirc.europa/Libera")
1320       ("bounce.bold.daemon"
1321        :server-alias "bOFTC"
1322        :encryption tls
1323        :channels ("#cat-v")
1324        :user-name "qbit@rcirc.europa/OFTC")
1325       ("bounce.bold.daemon"
1326        :server-alias "bHackers"
1327        :nick "abieber"
1328        :encryption tls
1329        :user-name "qbit@rcirc.europa/hackers")
1330       ("bounce.bold.daemon"
1331        :server-alias "bPorters"
1332        :nick "abieber"
1333        :encryption tls
1334        :user-name "qbit@rcirc.europa/porters")))
1335    (add-hook 'rcirc-mode-hook #'rcirc-track-minor-mode)
1336    (add-hook 'rcirc-mode-hook #'flyspell-mode)
1337    (setopt
1338     rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY")
1339     rcirc-bridge-bot-alist
1340     '(("tapebot" . "<\\(.+?\\)>[[:space:]]+")
1341       ("ijchain" . "<\\(.+?\\)>[[:space:]]+")
1342       ("matrix_bridge" . "<\\(.+?\\)>[[:space:]]+")
1343       ("ischain" . "<\\(.+?\\)>[[:space:]]+")))
1344    (add-to-list 'display-buffer-alist
1345    	     '((major-mode . rcirc-mode) display-buffer-same-window))
1346  #+end_src
1347  
1348  * Experiments
1349  :PROPERTIES:
1350  :ID:       99dc81c2-b0bc-4aa0-99c3-4ea32cb2e6fe
1351  :END:
1352  
1353  #+begin_src emacs-lisp
1354    (use-package guix)
1355  #+end_src