From 6adad6f4775489bc6bfcc2de4318b8e0c408cd33 Mon Sep 17 00:00:00 2001
From: Thomas Voss <mail@thomasvoss.com>
Date: Sun, 8 Sep 2024 00:03:41 +0200
Subject: emacs: Move configuration to emacs-old/

---
 .config/emacs-old/.gitignore     |    8 +
 .config/emacs-old/config.org     | 1396 ++++++++++++++++++++++++++++++++++++++
 .config/emacs-old/mango-theme.el |  158 +++++
 3 files changed, 1562 insertions(+)
 create mode 100644 .config/emacs-old/.gitignore
 create mode 100644 .config/emacs-old/config.org
 create mode 100644 .config/emacs-old/mango-theme.el

(limited to '.config/emacs-old')

diff --git a/.config/emacs-old/.gitignore b/.config/emacs-old/.gitignore
new file mode 100644
index 0000000..42a924b
--- /dev/null
+++ b/.config/emacs-old/.gitignore
@@ -0,0 +1,8 @@
+# Org-Tangle generated files
+early-init.el
+init.el
+
+# Emacs auto-generated files
+*~
+\#*
+.#*
diff --git a/.config/emacs-old/config.org b/.config/emacs-old/config.org
new file mode 100644
index 0000000..82412f4
--- /dev/null
+++ b/.config/emacs-old/config.org
@@ -0,0 +1,1396 @@
+#+TITLE: Emacs Configuration
+#+AUTHOR: Thomas Voss
+#+DATE: <2023-08-09 Wed>
+#+DESCRIPTION: My Emacs configuration — before I ran ‘rm -rf ~/.config’ that is
+#+STARTUP: overview
+
+* Headers
+
+The first thing we need in any configuration is a header setting
+~lexical-binding~ to ~t~.  This will allow us to have non-autistic behavior when
+scoping variables.
+
+#+BEGIN_SRC elisp :tangle early-init.el
+  ;;; early-init.el --- Emacs early configuration file  -*- lexical-binding: t -*-
+#+END_SRC
+
+#+BEGIN_SRC elisp :tangle init.el
+  ;;; init.el --- Emacs configuration file  -*- lexical-binding: t -*-
+#+END_SRC
+
+* Early Init File
+:PROPERTIES:
+:header-args: :tangle early-init.el
+:END:
+
+** Numerical Constants
+
+These are not really important, but nice to have to make the following
+configuration more readable.  The reason they’re defined in the ~early-init.el~
+is simply because I need to use them here.
+
+#+BEGIN_SRC elisp
+
+  (defconst 1-KiB 1024
+    "The number of bytes in 1 kibibyte.")
+
+  (defconst 1-MiB (* 1-KiB 1024)
+    "The number of bytes in 1 mebibyte.")
+
+  (defconst 1-GiB (* 1-MiB 1024)
+    "The number of bytes in 1 gibibyte.")
+
+#+END_SRC
+
+** XDG Directories
+
+We want to define variables for the main XDG directories for Emacs to use.
+These are nice for keeping things organized and out of the way.
+
+#+BEGIN_SRC elisp
+
+  (defconst mango-cache-directory
+    (expand-file-name
+     "emacs"
+     (or (getenv "XDG_CACHE_HOME")
+         (expand-file-name ".cache" (getenv "HOME"))))
+    "The XDG-conformant cache directory that Emacs should use.")
+
+  (defconst mango-config-directory
+    (expand-file-name
+     "emacs"
+     (or (getenv "XDG_CONFIG_HOME")
+         (expand-file-name ".config" (getenv "HOME"))))
+    "The XDG-conformant config directory that Emacs should use.")
+
+  (defconst mango-data-directory
+    (expand-file-name
+     "emacs"
+     (or (getenv "XDG_DATA_HOME")
+         (expand-file-name ".local/share" (getenv "HOME"))))
+    "The XDG-conformant data directory that Emacs should use.")
+
+#+END_SRC
+
+We also need to ensure our directories actually exist.
+
+#+BEGIN_SRC elisp
+
+  (mapc (lambda (x) (make-directory x t))
+        (list mango-cache-directory
+              mango-config-directory
+              mango-data-directory))
+
+#+END_SRC
+
+We don’t want to have all sorts of random garbage populating the configuartion
+directory; let’s throw it all in the cache directory instead.
+
+#+BEGIN_SRC elisp
+
+  (setq user-emacs-directory mango-cache-directory
+        auto-save-list-file-prefix (expand-file-name
+                                    "auto-save-list/"
+                                    mango-cache-directory)
+        backup-directory-alist `(("." . ,(expand-file-name
+                                          "backups"
+                                          mango-cache-directory))))
+
+#+END_SRC
+
+** Default Limits
+
+These are just some limits Emacs abides by as far as garbage-collection and
+process communication go.  They’re pretty low by default though; any modern
+system is capable of much higher.  To improve startup performance the garbage
+collection theshold is set to the max until Emacs is initialized.  Additionally
+the documentation for ~read-process-output-max~ gives us a hint at how large we
+can set it:
+
+#+BEGIN_QUOTE
+
+  On GNU/Linux systems, the value should not exceed
+  =/proc/sys/fs/pipe-max-size=.  See pipe(7) manpage for details.
+
+#+END_QUOTE
+
+#+BEGIN_SRC elisp
+
+  (setq gc-cons-threshold most-positive-fixnum)
+  (add-hook 'after-init-hook
+            (lambda () (setq gc-cons-threshold (* 512 1-MiB))))
+
+  (with-temp-buffer
+    (insert-file-contents "/proc/sys/fs/pipe-max-size")
+    (setq read-process-output-max (number-at-point)))
+
+#+END_SRC
+
+** Package Management
+
+Finally, we want to completely disable ~package.el~ since we’re going to be
+using ~straight.el~ in the main configuration.
+
+#+BEGIN_SRC elisp
+
+  (setq package-enable-at-startup nil)
+
+#+END_SRC
+
+* Init File
+:PROPERTIES:
+:header-args: :tangle init.el
+:END:
+
+** Helper Functions and -Macros
+
+*** Shorter Lambdas
+
+It’s annoying to have to write out ~(lambda () BODY)~ every time I want to write
+a lambda that takes no args — a very common operation.  The solution is to just
+use an actual lambda.  If I ever forget how to enter a lambda, it’s =C-x 8 RET=.
+
+#+BEGIN_SRC elisp
+
+  (defmacro λ (&rest body)
+    "Convenience macro to create lambda functions that take no arguments with much
+  short and concise syntax.  Calling ‘λ’ with BODY is equivalent to calling
+  ‘lambda’ with an empty argument list and BODY."
+    (declare (pure t) (side-effect-free t))
+    `(lambda () ,@body))
+
+#+END_SRC
+
+*** Hooks from Modes
+
+It is very often that I have a mode symbol and I want to extract the
+corresponding hook from it.  Luckily there’s a pretty standard naming convention
+here.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-mode-to-hook (mode)
+    "Get the hook corresponding to MODE."
+    (declare (pure t) (side-effect-free t))
+    (intern (concat (symbol-name mode) "-hook")))
+
+#+END_SRC
+
+*** Tree-Sitter Modes
+
+As I was writing this configuration, Emacs 29 released on the Arch repositories
+with native support for ~tree-sitter~.  As a result many major-modes now have two
+versions — a regular version and a ~tree-sitter~ version.  I should have pretty
+equal configurations for both versions of a mode so it’s useful to be able to
+grab one from the other.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-mode-to-ts-mode (mode)
+    "Get the tree-sitter mode corresponding to MODE."
+    (declare (pure t) (side-effect-free t))
+    (intern (concat
+             (string-remove-suffix "-mode" (symbol-name mode))
+             "-ts-mode")))
+
+#+END_SRC
+
+** Package Management
+
+For package management I like to use ~straight.el~.  Before setting that up
+though it’s probably best to disable native-compilation warnings; we’ll get a
+whole lot of those when ~straight.el~ is installing packages.
+
+#+BEGIN_SRC elisp
+
+  (setq comp-async-report-warnings-errors nil
+        native-comp-async-report-warnings-errors nil)
+
+#+END_SRC
+
+After doing that, we can bootstrap ~straight.el~.  The two options enabled at
+the end are just configuring ~use-package~ to always use ~straight.el~ by
+default, and to always ensure packages unless stated otherwise.
+
+#+BEGIN_SRC elisp
+
+  (defvar bootstrap-version)
+  (let ((bootstrap-file
+         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+        (bootstrap-version 6))
+    (unless (file-exists-p bootstrap-file)
+      (with-current-buffer
+          (url-retrieve-synchronously
+           "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
+           'silent 'inhibit-cookies)
+        (goto-char (point-max))
+        (eval-print-last-sexp)))
+    (load bootstrap-file nil 'nomessage))
+
+  (setq straight-use-package-by-default t
+        use-package-always-ensure t)
+
+#+END_SRC
+
+** Documentation
+
+Documentation is absolutely essential.  The ~helpful~ package gives us much
+better documentation for things, so let’s use it.  I’m mostly just overriding
+the bindings for the standard ~describe-*~ functions.
+
+#+BEGIN_SRC elisp
+
+  (use-package helpful
+    :bind (("C-h f"   . #'helpful-callable)
+           ("C-h v"   . #'helpful-variable)
+           ("C-h k"   . #'helpful-key)
+           ("C-h o"   . #'helpful-symbol)
+           ("C-c C-d" . #'helpful-at-point)))
+
+#+END_SRC
+
+** Key Bindings
+
+*** Editing This Config
+
+This configuration is one of the files I visit the most.  Not just for making
+large customizations, but also for simply editing the tab-width for a mode I
+happen to be using.  For that reason there should probably be a binding to get
+here.
+
+#+BEGIN_SRC elisp
+
+  (keymap-global-set
+   "C-c e"
+   (λ (interactive)
+      (find-file
+       (expand-file-name "config.org" mango-config-directory))))
+
+#+END_SRC
+
+*** Evil Mode
+
+The default Emacs keybindings are horrible and dangerous.  Feel free to use them
+if you want to develop genuine problems with your hands.  For this reason,
+~evil-mode~ bindings are the way to go.  Also as I was writing this, Bram
+Moolenaar, the creator of Vim died.  RIP.
+
+Here we setup bindings in the ~:bind~ section; the functions bound to that don’t
+exist yet will be created shortly.  You also need to set all these variables
+/before/ ~evil-mode~ is loaded — it’s just how ~evil~ works I suppose.  Finally
+I like to have ~visual-line-mode~ enabled as I find it far more intuitive.
+
+#+BEGIN_SRC elisp
+
+  (use-package evil
+    :bind (:map evil-normal-state-map
+           ("€"         . #'evil-end-of-visual-line)
+           ("<leader>h" . #'evil-window-left)
+           ("<leader>j" . #'evil-window-down)
+           ("<leader>k" . #'evil-window-up)
+           ("<leader>l" . #'evil-window-right)
+           ("<leader>a" . #'mango--evil-align-regexp)
+           ("<leader>s" . #'mango--evil-sort-lines)
+           ("<leader>;" . #'mango--evil-comment-or-uncomment-region))
+    :init
+    ;; We need to set these variables before loading ‘evil-mode’
+    (setq evil-want-Y-yank-to-eol t
+          evil-v$-excludes-newline t
+          evil-respect-visual-line-mode t
+          evil-split-window-below t
+          evil-vsplit-window-right t
+          evil-want-fine-undo t
+          evil-undo-system 'undo-redo
+          evil-flash-delay 1
+          evil-want-keybinding nil)
+    (evil-mode)
+    (global-visual-line-mode)
+    :config
+    (evil-set-leader nil (kbd "SPC")))
+
+#+END_SRC
+
+*** Evil Surround
+
+This is probably one of the more useful Vim/Emacs extensions out there.  It
+let’s you easy add-, remove-, and change surrounding pairs such as quotation
+marks and parenthesis from a /text object/.  I like to use unicode single- and
+double quotation marks — so we also want to add support for those.
+
+#+BEGIN_SRC elisp
+
+  (use-package evil-surround
+    :after evil
+    :config
+    (global-evil-surround-mode))
+
+#+END_SRC
+
+Supporting custom pairs is a bit tricky since we need to define an evil /text
+object/ to make them work properly.  Also we add some custom Jinja pairs!
+
+#+BEGIN_SRC elisp
+
+  (defmacro mango--evil-define-and-bind-quoted-text-object (name key start-regex end-regex)
+    (let ((inner-name (make-symbol (concat "evil-inner-" name)))
+          (outer-name (make-symbol (concat "evil-a-"     name))))
+      `(progn
+         (evil-define-text-object ,inner-name (count &optional beg end type)
+           (evil-select-paren ,start-regex ,end-regex beg end type count nil))
+         (evil-define-text-object ,outer-name (count &optional beg end type)
+           (evil-select-paren ,start-regex ,end-regex beg end type count t))
+         (define-key evil-inner-text-objects-map ,key #',inner-name)
+         (define-key evil-outer-text-objects-map ,key #',outer-name))))
+
+  (mango--evil-define-and-bind-quoted-text-object "single-quote-open"  "‘" "‘" "’")
+  (mango--evil-define-and-bind-quoted-text-object "single-quote-close" "’" "‘" "’")
+  (mango--evil-define-and-bind-quoted-text-object "double-quote-open"  "“" "“" "”")
+  (mango--evil-define-and-bind-quoted-text-object "double-quote-close" "”" "“" "”")
+
+  (setq-default
+   evil-surround-pairs-alist
+   (append
+    '((?‘ . ("‘ " . " ’"))
+      (?’ . ("‘"  .  "’"))
+      (?“ . ("“ " . " ”"))
+      (?“ . ("“"  .  "”")))
+    evil-surround-pairs-alist))
+
+  (add-hook
+   'html-mode-hook
+   (λ (setq-local
+       evil-surround-pairs-alist
+       (append
+        '((?% . ("{% " . " %}"))
+          (?# . ("{# " . " #}"))
+          (?{ . ("{{ " . " }}")))
+        evil-surround-pairs-alist))
+      (mango--evil-define-and-bind-quoted-text-object "jinja-action"  "%" "{%" "%}")
+      (mango--evil-define-and-bind-quoted-text-object "jinja-comment" "#" "{#" "#}")
+      (mango--evil-define-and-bind-quoted-text-object "jinja-code"    "{" "{{" "}}")))
+
+#+END_SRC
+
+*** Evil Collection
+
+This is a super-simple to setup package that adds ~evil~ bindings to many other
+custom packages like ~magit~ and ~mu4e~.
+
+#+BEGIN_SRC elisp
+
+  (use-package evil-collection
+    :after evil
+    :config
+    (evil-collection-init))
+
+#+END_SRC
+
+*** Aligning Text
+
+I absolutely love aligning text with ~align-regexp~.  It is in my opinion one of
+the most underrated Emacs functions.  Unfortunately, it aligns with tabs or
+-spaces based on the setting of ~indent-tabs-mode~.  Personally I am almost
+always indenting with tabs, but I prefer to align with spaces.  Luckily we can
+use some advice to force the usage of spaces.
+
+#+BEGIN_SRC elisp
+
+  (defun mango--align-regexp-with-spaces (old-function &rest args)
+    "Advice to force ‘align-regexp’ to always align with spaces, regardless of the
+  value of ‘indent-tabs-mode’."
+    (let (indent-tabs-mode)
+      (apply old-function args)))
+
+  (advice-add 'align-regexp :around #'mango--align-regexp-with-spaces)
+
+#+END_SRC
+
+Now that it’s behaving properly, it should also be turned into an ~evil~
+operator so it can be used with Vim motions.
+
+#+BEGIN_SRC elisp
+
+  (evil-define-operator mango--evil-align-regexp (beg end regexp repeat)
+    "Wrapper around ‘align-regexp’ to allow for use as an ‘evil-mode’ operator."
+    (interactive (let ((range (evil-operator-range)))
+                   (list (car range)
+                         (cadr range)
+                         (concat "\\(\\s-*\\)"
+                                 (read-string "Align regexp: "))
+                         (y-or-n-p "Repeat? "))))
+    (align-regexp beg end regexp 1 1 repeat))
+
+#+END_SRC
+
+*** Sorting Text
+
+Another very common operation is sorting text.  So why not make an operator for
+that too?
+
+#+BEGIN_SRC elisp
+
+  (evil-define-operator mango--evil-sort-lines (beg end)
+    "Wrapper around ‘sort-lines’ to allow for use as an ‘evil-mode’ operator."
+    (sort-lines nil beg end))
+
+#+END_SRC
+
+*** Commenting Code
+
+Commenting code is a super common task — so make it an operator!
+
+#+BEGIN_SRC elisp
+
+  (evil-define-operator mango--evil-comment-or-uncomment-region (beg end)
+    "Wrapper around ‘comment-or-uncomment-region’ to allow for use as
+  an ‘evil-mode’ operator."
+    (comment-or-uncomment-region beg end))
+
+#+END_SRC
+
+*** Tetris
+
+Tetris is epic, but the bindings are not so epic.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-tetris-rotate-mirror ()
+    (interactive)
+    (tetris-rotate-next)
+    (tetris-rotate-next))
+
+  (use-package tetris
+    :hook (tetris-mode . (lambda () (evil-local-mode -1)))
+    :bind (:map tetris-mode-map
+           ("a"   . #'tetris-move-left)
+           ("d"   . #'tetris-move-right)
+           ("k"   . #'tetris-rotate-next)
+           (";"   . #'tetris-rotate-prev)
+           ("l"   . #'tetris-move-down)
+           ("o"   . #'mango-tetris-rotate-mirror)
+           ("SPC" . #'tetris-move-bottom)))
+
+#+END_SRC
+
+** Completions
+
+*** Savehist-Mode
+
+This mode is super handy.  It let’s you preserve your history in minibuffer
+prompts.
+
+#+BEGIN_SRC elisp
+
+  (savehist-mode)
+
+#+END_SRC
+
+*** Vertico & Marginalia
+
+Vertico is a great package for enhanced completions in the minibuffer.  It’s
+minimal and works great.  We also want to configure the highlighting of the
+current line to match up with what is used for ~hl-line-mode~.  Vertico also
+doesn’t offer a builtin function to go up a directory when typing out a path, so
+that’s what the ~mango-minibuffer-backward-kill~ is for.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-minibuffer-backward-kill (arg)
+    "When minibuffer is completing a file name delete up to parent folder,
+  otherwise delete a word."
+    (interactive "p")
+    (if minibuffer-completing-file-name
+        (if (string-match-p "/." (minibuffer-contents))
+            (zap-up-to-char (- arg) ?/)
+          (delete-minibuffer-contents))
+      (backward-kill-word arg)))
+
+  (use-package vertico
+    :bind (:map vertico-map
+           ("C-j" . vertico-next)
+           ("C-k" . vertico-previous)
+           ("C-l" . vertico-insert)
+           :map minibuffer-local-map
+           ("C-h" . mango-minibuffer-backward-kill))
+    :custom
+    (vertico-cycle t)
+    :init
+    (vertico-mode))
+
+#+END_SRC
+
+Marginalia is kind of a suppliment I like to use with Vertico.  It adds, well…
+/marginalia/ to the completions in the minibuffer.  This includes things like
+file sizes and permissions when looking at files, function docstrings when
+looking at those, etc.
+
+#+BEGIN_SRC elisp
+
+  (use-package marginalia
+    :after vertico
+    :init
+    (marginalia-mode))
+
+#+END_SRC
+
+*** Orderless
+
+Orderless is another pretty neat package.  It allows for better completion
+candidate filtering.  I personally prefer to use the ~orderless-prefixes~
+completion style where entering the string “foo bar baz” will match the options
+that have components beginning with /foo/, /bar/, and /baz/ in that order.
+
+#+BEGIN_SRC elisp
+
+  (use-package orderless
+    :custom
+    (completion-styles '(orderless basic))
+    (orderless-matching-styles '(orderless-prefixes))
+    (completion-category-overrides '((file (styles basic partial-completion)))))
+
+#+END_SRC
+
+*** Company
+
+Company is a package to give me actual completion popups; it’s super useful for
+autocompleting code but has other uses too I guess.
+
+#+BEGIN_SRC elisp
+
+  (defun mango--company-require-prefix (candidates)
+    "Transformer for ‘company-mode’ that requires that all candidates begin with
+  ‘company-prefix’."
+    (seq-filter (lambda (s) (string-prefix-p company-prefix s)) candidates))
+
+  (defun mango--company-select-candidate (pred)
+    "Select either the next or previous candidate in the candidate list based on
+  the comparison of the ‘company-pseudo-tooltip-overlay’ height and 0 using PRED."
+    (let ((ov company-pseudo-tooltip-overlay))
+      (if (and ov (apply pred (list (overlay-get ov 'company-height) 0)))
+          (company-select-previous)
+        (company-select-next))))
+
+  (defun mango-company-next-candidate ()
+    "Select the next available candidate, taking into account if the candidate
+  list is flipped or not."
+    (interactive)
+    (mango--company-select-candidate #'<))
+
+  (defun mango-company-previous-candidate ()
+    "Select the previous available candidate, taking into account if the candidate
+  list is flipped or not."
+    (interactive)
+    (mango--company-select-candidate #'>))
+
+  (use-package company
+    :bind (:map company-active-map
+           ("C-j" . #'mango-company-next-candidate)
+           ("C-k" . #'mango-company-previous-candidate))
+    :hook ((conf-mode prog-mode) . company-mode)
+    :custom
+    (company-minimum-prefix-length 1)
+    (company-idle-delay (lambda () (unless (company-in-string-or-comment) 0)))
+    (company-selection-wrap-around t)
+    (company-tooltip-align-annotations t)
+    (company-tooltip-flip-when-above t)
+    (company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
+                         company-preview-frontend
+                         company-echo-metadata-frontend))
+    (company-transformers '(mango--company-require-prefix
+                            company-sort-by-backend-importance)))
+
+#+END_SRC
+
+** Math and Numbers
+
+*** Calc
+
+The built-in emacs calculator ~calc~ is genuinely the best calculator program I
+have ever used.  Annoyingly though, it has a ‘trail’ that is always around.  I
+don’t like it.
+
+#+BEGIN_SRC elisp
+
+  (setq calc-display-trail nil)
+
+#+END_SRC
+
+*** Increment- and Decrement Number at Point
+
+This is a pretty standard Vim feature that I dearly miss having.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-increment-number-at-point (&optional arg)
+    "Increment the number at point by ARG or 1 if ARG is nil.  If called
+  interactively, the universal argument can be used to specify ARG.  If the number
+  at point has leading zeros then the width of the number is preserved."
+    (interactive "p*")
+    (save-excursion
+      (save-match-data
+        (skip-chars-backward "0123456789")
+        (when (eq (char-before (point)) ?-)
+          (goto-char (1- (point))))
+        (when (re-search-forward "-?\\([0-9]+\\)" nil t)
+          (let ((answer (+ (string-to-number (match-string 0) 10)
+                           (or arg 1)))
+                (width (length (match-string 1))))
+            (replace-match
+             (format
+              (concat "%0" (int-to-string (if (< answer 0) (1+ width) width)) "d")
+              answer)))))))
+
+  (defun mango-decrement-number-at-point (&optional arg)
+    "The same as ‘mango-increment-number-at-point’, but ARG is negated."
+    (interactive "p*")
+    (mango-increment-number-at-point (- (or arg 1))))
+
+  (keymap-global-set "C-c a" #'mango-increment-number-at-point)
+  (keymap-global-set "C-c x" #'mango-decrement-number-at-point)
+
+#+END_SRC
+
+** Programming
+
+*** Indentation
+
+Indentation in Emacs is a royal pain in the ass.   Not only is there a
+~tab-width~ variable and the ~indent-tabs-mode~ mode, but lots of modes just
+have an extra ~tab-width~-esque variable for some reason?  I try to fix this all
+with a custom function that reads a list of mode-specific indentation settings.
+
+#+BEGIN_SRC elisp
+
+  (setq-default tab-width 8
+                evil-shift-width 8
+                indent-tabs-mode t)
+
+  (defvar mango-indentation-settings
+    '((bash-ts-mode :width 4)
+      (c-mode :width 4 :extra-vars (c-basic-offset))
+      (css-mode :extra-vars (css-indent-offset))
+      (emacs-lisp-mode :spaces t)
+      (graphviz-dot-mode :extra-vars (graphviz-dot-indent-width))
+      (lisp-mode :spaces t)
+      (org-mode :spaces t)
+      (python-mode :width 4 :extra-vars (python-indent-offset))
+      (rust-mode :width 4)
+      (sgml-mode :width 2 :extra-vars (sgml-basic-offset))
+      (sh-mode :width 4 :extra-vars (sh-basic-offset))
+      (xml-mode :width 4))
+    "A list of per-mode indentation settings.  Each list contains a major-mode and
+  the 3 optional keyword arguments of :spaces, :width, and :extra-vars.  When
+  setting the settings for a given major-mode, the settings will also be applied
+  for that modes tree-sitter variant.
+
+  If :spaces is non-nil, then indentation will be performed with spaces instead of
+  tabs characters.
+
+  If :width is non-nil, then it will override the modes given tab-width.
+
+  If :extra-vars is non-nill, then it shall be a list of additional mode-specific
+  variables that need to be assigned the desired indentation-width.")
+
+  (defun mango-set-indentation-settings ()
+    "Apply the indentation settings specified by ‘mango-indentation-settings’."
+    (interactive)
+    (dolist (plist mango-indentation-settings)
+      (let* ((mode (car plist))
+             (args (cdr plist))
+             (width (or (plist-get args :width) (default-value 'tab-width)))
+             (spaces (or (plist-get args :spaces) (not (default-value 'indent-tabs-mode))))
+             (extra (plist-get args :extra-vars))
+             (callback
+              (λ (indent-tabs-mode (when spaces -1))
+                 (setq-local tab-width width
+                             evil-shift-width width)
+                 (dolist (var extra) (set var width)))))
+        (add-hook (mango-mode-to-hook mode) callback 95)
+        (add-hook (mango-mode-to-hook (mango-mode-to-ts-mode mode)) callback 95))))
+
+  (mango-set-indentation-settings)
+
+#+END_SRC
+
+*** Git Integration
+
+I like to use Magit for my ~git~ integration.  I do believe it is the best ~git~
+client ever made for any editor ever.  Anyone who disagrees has simply never
+used Emacs before.  The only command that really needs binding is
+~magit-status~.  All other commands I will end up executing from there with the
+transient commands.  I also install ~magit-todos~.  It’s a super minimal package
+that simply finds all the TODOs in a repository and displays them in the
+~magit-status~ buffer so that I don’t forget them.
+
+#+BEGIN_SRC elisp
+
+  (use-package magit
+    :bind ("C-c g" . magit-status)
+    :custom
+    (magit-display-buffer-function
+     #'magit-display-buffer-same-window-except-diff-v1))
+
+  (use-package magit-todos
+    :after magit
+    :init (magit-todos-mode))
+
+  (defun mango--magit-status ()
+    (interactive)
+    (thread-last
+      (project-current t)
+      (project-root)
+      (magit-status)))
+
+  (require 'project)
+  (add-to-list 'project-switch-commands '(mango--magit-status "Git Status" ?g))
+
+#+END_SRC
+
+*** Tree-Sitter
+
+Emacs 29 brings native support for Tree-Sitter!  This doesn’t just mean better-
+and faster syntax highlighting, but also things such as structured editing.  In
+order to make use of Tree-Sitter the language parsers /do/ need to be installed,
+so let’s do that.  Tree-Sitter doesn’t check to see if the language grammars are
+already installed unfortunately, but it’s easy enough to do manually.
+
+#+BEGIN_SRC elisp
+
+  (setq treesit-language-source-alist
+        '((bash     "https://github.com/tree-sitter/tree-sitter-bash")
+          (c        "https://github.com/tree-sitter/tree-sitter-c")
+          (cpp      "https://github.com/tree-sitter/tree-sitter-cpp")
+          (css      "https://github.com/tree-sitter/tree-sitter-css")
+          (elisp    "https://github.com/Wilfred/tree-sitter-elisp")
+          (go       "https://github.com/tree-sitter/tree-sitter-go")
+          (gomod    "https://github.com/camdencheek/tree-sitter-go-mod.git")
+          (html     "https://github.com/tree-sitter/tree-sitter-html")
+          (json     "https://github.com/tree-sitter/tree-sitter-json")
+          (make     "https://github.com/alemuller/tree-sitter-make")
+          (markdown "https://github.com/ikatyang/tree-sitter-markdown")
+          (python   "https://github.com/tree-sitter/tree-sitter-python")
+          (toml     "https://github.com/tree-sitter/tree-sitter-toml")
+          (yaml     "https://github.com/ikatyang/tree-sitter-yaml")))
+
+  (defun mango-treesit-install ()
+    "Install all the tree-sitter grammars in ‘treesit-language-source-alist’.
+  This function does not assert whether or not the grammar is already installed,
+  making it useful for updating existing grammars."
+    (interactive)
+    (dolist (spec treesit-language-source-alist)
+      (treesit-install-language-grammar (car spec))))
+
+  ;; Automatically install missing grammars
+  (thread-last
+    (mapcar #'car treesit-language-source-alist)
+    (seq-remove #'treesit-language-available-p)
+    (mapc #'treesit-install-language-grammar))
+
+#+END_SRC
+
+I also prefer to have as many things syntax highlighted as possible when using
+tree-sitter, with the ability to fully customize faces (or turn off faces I
+don’t want highlighted).
+
+#+BEGIN_SRC elisp
+
+  (setq treesit-font-lock-level 4)
+
+#+END_SRC
+
+*** Language Server Protocol
+
+LSP is an absolute necessity when programming.  Luckily ~lsp-mode~ has us
+covered.  There is Eglot which is now built in to Emacs 29, but it was giving me
+some really weird issues so I won’t be using that for now.  ~lsp-bridge~ also
+looked promising but I didn’t like it too much.  Also ~yasnippet~ is dead, so
+why they won’t just move on from it I have no idea.  I’ll just disable snippets.
+
+#+BEGIN_SRC elisp
+
+  (use-package lsp-mode
+    :commands (lsp lsp-deferred)
+    :custom
+    (lsp-enable-snippet nil)
+    :init
+    (setq lsp-keymap-prefix "C-c l"))
+
+#+END_SRC
+
+I use ~pyright~ as my Python LSP only because I know no better option.  It does
+need some this custom package though.
+
+#+BEGIN_SRC elisp
+
+  (use-package lsp-pyright
+    :hook (python-ts-mode . (lambda () (require 'lsp-pyright) (lsp))))
+
+#+END_SRC
+
+*** Emmet-Mode
+
+This mode is super useful for writing HTML.  It lets me expand something like
+‘figure>(figcaption>code)+pre’ into an actual HTML structure.
+
+#+BEGIN_SRC elisp
+
+  (use-package emmet-mode
+    :hook (html-mode . emmet-mode))
+
+#+END_SRC
+
+*** Compilation Buffer
+
+Emacs allows you to compile your project with =C-x p c= which is cool and all,
+but it annoyingly creates a compilation buffer that I need to manually close
+every time.  I would like to have this buffer, but only when things go wrong.
+
+#+BEGIN_SRC elisp
+
+  (defun mango--compilation-make-window ()
+    "Make a new vertical split for the compilation buffer if such a buffer doesn’t
+  already exist."
+    (unless (get-buffer "*compilation*")
+      (split-window-vertically)))
+
+  (defun mango--compilation-exit-autoclose (status code msg)
+    "Automatically bury the compilation buffer and delete the compilation window
+  if compilation was successful."
+    (when (and (eq status 'exit)
+               (zerop code))
+      (bury-buffer)
+      (delete-window (get-buffer-window "*compilation*")))
+    (cons msg code))
+
+  (add-hook 'compilation-mode-hook #'mango--compilation-make-window)
+  (setq compilation-exit-message-function #'mango--compilation-exit-autoclose)
+
+#+END_SRC
+
+*** Projects
+
+I want to have all my projects automatically added to the project list.
+
+#+BEGIN_SRC elisp
+
+  (project-remember-projects-under
+   (or (getenv "REPODIR")
+       (expand-file-name "code/repo" (getenv "HOME")))
+   'recursive)
+
+#+END_SRC
+
+** User Interface
+
+The default Emacs UI is fucking atrocious — we need to make it better.
+
+*** Cursor Blink
+
+I personally don’t like cursors blinking, so let’s disable that.
+
+#+BEGIN_SRC elisp
+
+  (blink-cursor-mode -1)
+
+#+END_SRC
+
+*** Shorter Prompts
+
+For some reason emacs has both the ~y-or-n-p~ and ~yes-or-no-p~ functions.  I do
+not like having to spell out full words — /y/ or /n/ is good enough for me — so
+let’s just redefine ~yes-or-no-p~.
+
+#+BEGIN_SRC elisp
+
+  (fset #'yes-or-no-p #'y-or-n-p)
+
+#+END_SRC
+
+*** Disable Basic UI Modes
+
+Emacs has a lot of UI modes that are enabled by default to make life easier for
+the novice user.  I am not the novice user and would rather these modes never
+turned on ever again.
+
+#+BEGIN_SRC elisp
+
+  (menu-bar-mode -1)
+  (scroll-bar-mode -1)
+  (tool-bar-mode -1)
+  (tooltip-mode -1)
+
+#+END_SRC
+
+*** Warnings
+
+I am typically not a fan around being warned about things unless something is
+actually breaking or going wrong.
+
+In order, these options disable the following warnings:
+
+1. Opening large files
+2. Following symbolic links
+3. Adding advice to functions
+
+#+BEGIN_SRC elisp
+
+  (setq large-file-warning-threshold nil
+        vc-follow-symlinks t
+        ad-redefinition-action 'accept)
+
+#+END_SRC
+
+*** Visible Bell
+
+Why not?  I might disable this later.
+
+#+BEGIN_SRC elisp
+
+  (setq visible-bell t)
+
+#+END_SRC
+
+*** Scrolling
+
+By default, scrolling is really bad.  Luckily we can improve it a lot; there’s
+even a pixel-precision scrolling mode!
+
+#+BEGIN_SRC elisp
+
+  (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))
+        mouse-wheel-progressive-speed nil
+        mouse-wheel-follow-mouse t
+        scroll-step 1)
+  ;; (pixel-scroll-precision-mode)
+
+#+END_SRC
+
+*** Auto Reverting Buffers
+
+This is just good to have all of the time; you should never be looking at a file
+whose state was changed by an external process, and not see those changes *instantly*.
+
+#+BEGIN_SRC elisp
+
+  (setq global-auto-revert-non-file-buffers t)
+  (global-auto-revert-mode)
+
+#+END_SRC
+
+*** Highlight Matching Parenthesis
+
+This is generally a good thing — especially when writing lisp code — but I don’t
+want this /everywhere/.
+
+#+BEGIN_SRC elisp
+
+  (defvar mango-highlight-matching-parenthesis-modes
+    '(prog-mode conf-mode)
+    "A list of modes for which the parenthesis that pairs up with the parenthesis
+  at point should be highlighted.")
+
+  (show-paren-mode -1)
+
+  (dolist (mode mango-highlight-matching-parenthesis-modes)
+    (add-hook (mango-mode-to-hook mode) #'show-paren-local-mode))
+
+#+END_SRC
+
+*** Line- and Column Numbers
+
+I like to have line- and column numbers in my modeline.  I find them to be very
+useful to have.  I used to also like to have the current line number on the left
+of the screen, but I don’t really need that information.
+
+#+BEGIN_SRC elisp
+
+  (line-number-mode)
+  (column-number-mode)
+
+#+END_SRC
+
+*** Fonts
+
+My favorite monospace font has got to be /Iosevka/.  It’s good looking, it’s far
+more compact than the usual american-sized monospace fonts, and you can
+customize just about every character from loads of variants.  I have my own
+custom compiled variant called /Iosevka Smooth/.
+
+On the proportional side of things, I am not really sure what font to use.
+/Vollkorn/ tends to be my go-to serif-font on the web, but I dunno how well it
+translates to Emacs.  I am also a bit fan of Ysabeau for sans-serif.  I need to
+play around with this.
+
+#+BEGIN_SRC elisp
+
+  (defvar mango-monospace-font '("Iosevka Smooth" :weight regular :height 162)
+    "The default monospace font to use.  This is a list containing a font name,
+  font weight, and font height in that order.")
+
+  (defvar mango-proportional-font '("Ysabeau" :weight light :height 180)
+    "The default proportional font to use.  This is a list containing a font name,
+  font weight, and font height in that order.")
+
+#+END_SRC
+
+Actually /setting/ the fonts is a bit tricky.  I don’t really fully understand
+why it works like this, but something with the whole server/client model of
+Emacs is really fucking with this, so we need to add a hook to set the font for
+every frame.  We also can’t forget the frame that’s actually running this code.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-set-fonts ()
+    "Set the fonts specified by ‘mango-monospace-font’ and ‘mango-proportional-font’."
+    (interactive)
+    (let* ((mono-family (car mango-monospace-font))
+           (mono-props  (cdr mango-monospace-font))
+           (prop-family (car mango-proportional-font))
+           (prop-props  (cdr mango-proportional-font))
+           (mono-weight (plist-get mono-props :weight))
+           (mono-height (plist-get mono-props :height))
+           (prop-weight (plist-get prop-props :weight))
+           (prop-height (plist-get prop-props :height)))
+      (set-face-attribute 'default nil
+                          :font mono-family
+                          :weight mono-weight
+                          :height mono-height)
+      (set-face-attribute 'fixed-pitch nil
+                          :font mono-family
+                          :weight mono-weight
+                          :height mono-height)
+      (set-face-attribute 'variable-pitch nil
+                          :font prop-family
+                          :weight prop-weight
+                          :height prop-height)))
+
+  (add-hook 'after-make-frame-functions (lambda (_) (mango-set-fonts)))
+  (mango-set-fonts)
+
+#+END_SRC
+
+*** Emacs Theme
+
+I previously ran the ~sanityinc-tomorrow-eighties~ theme, but I now run my own
+custom theme.  I do like to keep the older theme around though as a reference.
+
+#+BEGIN_SRC elisp
+
+  (use-package color-theme-sanityinc-tomorrow)
+  (load-theme 'mango t)
+
+#+END_SRC
+
+*** Fringes
+
+It’s also nice to have fringes!
+
+#+BEGIN_SRC elisp
+
+  (set-fringe-style (cons 32 32))
+
+#+END_SRC
+
+*** Line Highlighting
+
+This is just something I personally like having.  It makes it very easy for me
+to figure out where my point is at all times.
+
+#+BEGIN_SRC elisp
+
+  (global-hl-line-mode)
+
+#+END_SRC
+
+*** Frame Management
+
+Prot has made a fantastic package known as ~beframe~.  It allows you to have
+each frame have its own buffer list.  This is insanely useful for keeping my
+buffers nice and organized.  It’s also useful for having a way to (for example)
+kill all buffers you were using in a frame before closing it.
+
+#+BEGIN_SRC elisp
+
+  (defun mango-beframe-delete-frame ()
+    "Kill all the buffers within the current beframe buffer list and then destroy
+  the frame."
+    (interactive)
+    (cl-loop with buffers = (cl-loop for frame in (frame-list)
+                                     unless (eq frame (selected-frame))
+                                     append (beframe-buffer-list frame))
+             for buffer in (beframe-buffer-list)
+             unless (member buffer buffers)
+             do (kill-buffer buffer))
+    (delete-frame))
+
+  (use-package beframe
+    :bind ([remap delete-frame] . mango-beframe-delete-frame)
+    :init
+    (beframe-mode))
+
+#+END_SRC
+
+*** Transparency
+
+Transparency is totally useless, but it looks cool.  Luckily transparent
+background support was added in Emacs 29!
+
+#+BEGIN_SRC elisp
+
+  (defvar mango-alpha-background 90
+    "The opacity of a graphical Emacs frame, ranging from 0–100.  A value of 0 is
+  fully transparent while a value of 100 is fully opaque.")
+
+  (defun mango-set-alpha-background (value)
+    "Set the current frames background opacity to VALUE."
+    (interactive "NOpacity: ")
+    (set-frame-parameter nil 'alpha-background value))
+
+  (add-to-list 'default-frame-alist (cons 'alpha-background mango-alpha-background))
+
+#+END_SRC
+
+** Extra Modes
+
+Some modes aren’t installed by default with Emacs, so let’s fetch them
+
+#+BEGIN_SRC elisp
+
+  (use-package git-modes)
+  (use-package graphviz-dot-mode)
+  (use-package markdown-mode)
+
+#+END_SRC
+
+** Auto-Start Modes
+
+Some modes need to be manually configured to automatically start when opening a
+file with a certain file extension.
+
+#+BEGIN_SRC elisp
+
+  (require 'go-ts-mode)
+  (require 'rust-ts-mode)
+  (require 'yaml-ts-mode)
+
+  (dolist (pair '(("\\.go\\'"    . go-ts-mode)
+                  ("\\.py\\'"    . python-ts-mode)
+                  ("\\.rs\\'"    . rust-ts-mode)
+                  ("\\.ya?ml\\'" . yaml-ts-mode)))
+    (add-to-list 'auto-mode-alist pair))
+
+#+END_SRC
+
+** Customization Settings
+
+Emacs has a /customization variable/ that contains various configuration-related
+settings that are set by different commands, as well as the customization UI.  I
+would rather have these saved in a temporary file since any customizations I
+make that I would like to have be persistent will be explicitly written into
+this file.
+
+#+BEGIN_SRC elisp
+
+  (setq custom-file
+        (expand-file-name
+         (format "emacs-custom-%s.el" (user-uid))
+         temporary-file-directory))
+  (load custom-file t)
+
+#+END_SRC
+
+** Backup Files
+
+It’s always good to have backups.  I would know — I’ve wiped both =~= and
+=~/.config= before!  Despite the name, ~version-control~ actually just adds
+version numbers to the backup names — it doesn’t start using a VCS.
+
+#+BEGIN_SRC elisp
+
+  (setq delete-old-versions t
+        version-control t
+        kept-new-versions 2
+        kept-old-versions 6)
+
+#+END_SRC
+
+** Mode Specific Settings
+
+*** Org-Mode
+
+**** Fontify Blockquotes
+
+I want to be able to customize the faces of blockquotes, so we need to enable
+that setting with ~org-mode~
+
+#+BEGIN_SRC elisp
+
+  (setopt org-fontify-quote-and-verse-blocks t)
+
+#+END_SRC
+
+**** Visual Intentation
+
+I really enjoy using ~org-indent-mode~.  It indents the contents of the
+org-buffer to keep everything looking nice and structured.
+
+#+BEGIN_SRC elisp
+
+  (add-hook 'org-mode-hook #'org-indent-mode)
+
+#+END_SRC
+
+*** Auto-Fill-Mode
+
+I do like to use this mode, especially when writing.  I also want it when coding
+/sometimes/, but not always.  Overall it’s a pretty useful mode — but I am super
+mixed on when I do and -don’t want it.  I always want it in ~org-mode~ though.
+
+#+BEGIN_SRC elisp
+
+  (setq-default fill-column 80)
+  (add-hook 'org-mode-hook #'auto-fill-mode)
+
+#+END_SRC
+
+** Auto-Directories
+
+When creating new files, the parent directories often don’t exist and I need to
+make them manually with =M-x make-directory RET RET=.  I would prefer that these
+directories just get created automatically.
+
+#+BEGIN_SRC elisp
+
+  (defun mango--auto-create-directories (original-function filename &rest args)
+    "Automatically create and delete parent directories of files.  This is an
+  ‘:override’ advice for ‘find-file’ and friends.  It automatically creates the
+  parent directory (or directories) of the file being visited, if necessary.  It
+  also sets a buffer-local variable so that the user will be prompted to delete
+  the newly created directories if they kill the buffer without saving it."
+    (let (dirs-to-delete)
+      (let* ((dir-to-create (file-name-directory filename))
+             (current-dir dir-to-create))
+        ;; We want to go up each directory component and add them to
+        ;; ‘dirs-to-delete’ individually.
+        (while (not (file-exists-p current-dir))
+          (push current-dir dirs-to-delete)
+          (setq current-dir (file-name-directory
+                             (directory-file-name current-dir))))
+
+        (unless (file-exists-p dir-to-create)
+          (make-directory dir-to-create t)))
+
+      ;; Use ‘prog1’ so that we maintain the original return value
+      (prog1 (apply original-function filename args)
+        (when dirs-to-delete
+          (setq-local mango--dirs-to-delete (reverse dirs-to-delete))
+
+          ;; When we kill the buffer we want to ask if we should delete parent
+          ;; directories *unless* the buffer was saved, in which case we don’t
+          ;; want to do anything.
+          (add-hook 'kill-buffer-hook #'mango--delete-directories-if-appropriate
+                    t t)
+          (add-hook 'after-save-hook #'mango--remove-auto-directory-hooks t t)))))
+
+  (dolist (command #'(find-file
+                      find-alternate-file
+                      write-file))
+    (advice-add command :around #'mango--auto-create-directories))
+
+  (defun mango--delete-directories-if-appropriate ()
+    "Delete parent directories if appropriate.  This is a function for
+  ‘kill-buffer-hook’.  If ‘mango--auto-create-directories’ created the directory
+  containing the file for the current buffer automatically, then offer to delete
+  it.  Otherwise, do nothing.  Also clean up related hooks."
+    (unless (file-exists-p buffer-file-name)
+      (dolist (dir-to-delete mango--dirs-to-delete)
+        (when (and (stringp dir-to-delete)
+                   (file-exists-p dir-to-delete)
+                   (y-or-n-p (format "Also delete directory ‘%s’?"
+                                     (directory-file-name dir-to-delete))))
+          (delete-directory dir-to-delete)))))
+
+  (defun mango--remove-auto-directory-hooks ()
+    "Clean up directory-deletion hooks, if necessary."
+    (remove-hook 'kill-buffer-hook #'mango--delete-directories-if-appropriate t)
+    (remove-hook 'after-save-hook #'mango--remove-auto-directory-hooks t))
+
+#+END_SRC
+
+** Email
+
+#+BEGIN_SRC elisp
+
+  (use-package mu4e
+    :ensure nil
+    :custom
+    (user-full-name "Thomas Voss")
+    (mu4e-change-filenames-when-moving t)
+    (mu4e-get-mail-command "mbsync -a -c /home/thomas/.config/isync/mbsyncrc")
+    (mu4e-maildir "~/mail")
+    (sendmail-program "/usr/bin/msmtp")
+    (send-mail-function 'smtpmail-send-it)
+    (message-sendmail-f-is-evil t)
+    (message-sendmail-extra-arguments '("--read-envelope-from"))
+    (message-send-mail-function 'message-send-mail-with-sendmail)
+    :config
+    (setq mango--mu4e-personal-context
+          (make-mu4e-context
+           :name "Personal"
+           :match-func
+           (lambda (msg)
+             (when msg
+               (string-prefix-p "/mail@thomasvoss.com" (mu4e-message-field msg :maildir))))
+           :vars '((user-mail-address  . "mail@thomasvoss.com")
+                   (mu4e-drafts-folder . "/mail@thomasvoss.com/Drafts")
+                   (mu4e-sent-folder   . "/mail@thomasvoss.com/Sent")
+                   (mu4e-refile-folder . "/mail@thomasvoss.com/Archive")
+                   (mu4e-trash-folder  . "/mail@thomasvoss.com/Junk")
+                   (mu4e-maildir-shortcuts . '((:name "Inbox"   :maildir "/mail@thomasvoss.com/Inbox"   :key ?i)
+                                               (:name "Archive" :maildir "/mail@thomasvoss.com/Archive" :key ?a)
+                                               (:name "Drafts"  :maildir "/mail@thomasvoss.com/Drafts"  :key ?d)
+                                               (:name "Sent"    :maildir "/mail@thomasvoss.com/Sent"    :key ?s)
+                                               (:name "Junk"    :maildir "/mail@thomasvoss.com/Junk"    :key ?j))))))
+    (setq mango--mu4e-legacy-context
+          (make-mu4e-context
+           :name "Legacy"
+           :match-func
+           (lambda (msg)
+             (when msg
+               (string-prefix-p "/thomasvoss@live.com" (mu4e-message-field msg :maildir))))
+           :vars '((user-mail-address  . "thomasvoss@live.com")
+                   (user-full-name     . "Thomas Voss")
+                   (mu4e-drafts-folder . "/thomasvoss@live.com/Drafts")
+                   (mu4e-sent-folder   . "/thomasvoss@live.com/Sent")
+                   (mu4e-refile-folder . "/thomasvoss@live.com/Archive")
+                   (mu4e-trash-folder  . "/thomasvoss@live.com/Junk")
+                   (mu4e-maildir-shortcuts . '((:name "Inbox"   :maildir "/thomasvoss@live.com/Inbox"   :key ?i)
+                                               (:name "POP"     :maildir "/thomasvoss@live.com/POP"     :key ?p)
+                                               (:name "Archive" :maildir "/thomasvoss@live.com/Archive" :key ?a)
+                                               (:name "Drafts"  :maildir "/thomasvoss@live.com/Drafts"  :key ?d)
+                                               (:name "Sent"    :maildir "/thomasvoss@live.com/Sent"    :key ?s)
+                                               (:name "Junk"    :maildir "/thomasvoss@live.com/Junk"    :key ?j))))))
+    (setq mango--mu4e-humanwave-context
+          (make-mu4e-context
+           :name "Humanwave"
+           :match-func
+           (lambda (msg)
+             (when msg
+               (string-prefix-p "/thomas.voss@humanwave.nl" (mu4e-message-field msg :maildir))))
+           :vars '((user-mail-address  . "thomas.voss@humanwave.nl")
+                   (user-full-name     . "Thomas Voss")
+                   (mu4e-drafts-folder . "/thomas.voss@humanwave.nl/[Gmail]/Drafts")
+                   (mu4e-sent-folder   . "/thomas.voss@humanwave.nl/[Gmail]/Sent Mail")
+                   (mu4e-refile-folder . "/thomas.voss@humanwave.nl/[Gmail]/All Mail")
+                   (mu4e-trash-folder  . "/thomas.voss@humanwave.nl/[Gmail]/Trash")
+                   (mu4e-maildir-shortcuts . '((:name "Inbox"   :maildir "/thomas.voss@humanwave.nl/Inbox"             :key ?i)
+                                               (:name "Archive" :maildir "/thomas.voss@humanwave.nl/[Gmail]/All Mail"  :key ?a)
+                                               (:name "Drafts"  :maildir "/thomas.voss@humanwave.nl/[Gmail]/Drafts"    :key ?d)
+                                               (:name "Sent"    :maildir "/thomas.voss@humanwave.nl/[Gmail]/Sent Mail" :key ?s)
+                                               (:name "Junk"    :maildir "/thomas.voss@humanwave.nl/[Gmail]/Junk"      :key ?j))))))
+
+    (setq mu4e-contexts (list mango--mu4e-personal-context
+                              mango--mu4e-legacy-context
+                              mango--mu4e-humanwave-context)))
+
+#+END_SRC
diff --git a/.config/emacs-old/mango-theme.el b/.config/emacs-old/mango-theme.el
new file mode 100644
index 0000000..af44903
--- /dev/null
+++ b/.config/emacs-old/mango-theme.el
@@ -0,0 +1,158 @@
+;;; mango-theme.el --- Just your average dark theme  -*- lexical-binding: t -*-
+
+;; Copyright © 2023 Thomas Voss
+
+;; Author: Thomas Voss <mail@thomasvoss.com>
+;; Maintainer: Thomas Voss <mail@thomasvoss.com>
+;; URL: https://git.sr.ht/~mango/mango-theme
+;; Mailing-List: https://lists.sr.ht/~mango/public-inbox
+
+;;; License:
+
+;; Permission to use, copy, modify, and/or distribute this software for any
+;; purpose with or without fee is hereby granted.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+;; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+;; AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+;; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+;; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+;; OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+;; PERFORMANCE OF THIS SOFTWARE.
+
+;;; Commentary:
+
+;; TODO
+
+;;; Code:
+
+(deftheme mango
+  "Just another dark theme because none of the other options out there were just
+as I would like them.  Why try to fix someone elses themes when I make my own?")
+
+(defun mango-theme--get-color (name)
+  "Get the RGB value of the color NAME from ‘mango-theme-palette’"
+  (cadr (assq name mango-theme-palette)))
+
+(defmacro mango-theme--generate-set-faces (&rest body)
+  "A macro to provide a much simpler syntax than what is expected by
+‘custom-theme-set-faces’.  This is possible because I only run Emacs
+graphically, so I shouldn’t need to have multiple specs per face.
+
+\(fn SPEC...)"
+  (declare (indent 0))
+  (let ((ret '('mango custom-theme-set-faces)))
+    (dolist (spec body)
+      (add-to-list 'ret `(backquote ,(list (car spec) `((((type graphic)) ,(cdr spec)))))))
+    (reverse ret)))
+
+(defconst mango-theme-palette
+  '((foreground       "#C5C8C6")
+    (background       "#2B303B")
+    (background-cool  "#363C4A")
+    (background-faint "#414859")
+    (middleground     "#4F5561")
+    (disabled         "#999999")
+    (pale-azure       "#9CDCFE")
+    (celestial-blue   "#569CD6")
+    (violet           "#E57AE5")
+    (khaki            "#F0E68C")
+    (lime             "#B8F182")
+    (orange           "#F1B282")
+    (pink             "#ED97F5")
+    (spanish-red      "#E60026"))
+  "The color palette used throughout the ‘mango’ theme.")
+
+(mango-theme--generate-set-faces
+  ;; Standard Stuff
+  (default
+   :foreground ,(mango-theme--get-color 'foreground)
+   :background ,(mango-theme--get-color 'background))
+  (fringe
+   :inherit default)
+
+  ;; Lines
+  (hl-line
+   :background ,(mango-theme--get-color 'background-faint))
+  (region
+   :background ,(mango-theme--get-color 'middleground))
+  (header-line
+   :background ,(mango-theme--get-color 'middleground))
+  (mode-line
+   :inherit header-line)
+  (mode-line-inactive
+   :background ,(mango-theme--get-color 'background-cool)
+   :weight light)
+
+  ;; Line Numbers
+  (line-number
+   :background ,(mango-theme--get-color 'background-cool))
+  (line-number-current-line
+   :background ,(mango-theme--get-color 'background-cool)
+   :weight bold)
+
+  ;; Documentation
+  (font-lock-comment-face
+   :foreground ,(mango-theme--get-color 'disabled))
+  (font-lock-doc-face
+   :inherit font-lock-comment-face)
+
+  ;; Core Language
+  (font-lock-keyword-face
+   :foreground ,(mango-theme--get-color 'violet))
+  (font-lock-type-face
+   :foreground ,(mango-theme--get-color 'celestial-blue))
+  (font-lock-builtin-face
+   :inherit font-lock-preprocessor-face)
+
+  ;; Function-likes
+  (font-lock-function-name-face
+   :foreground ,(mango-theme--get-color 'khaki))
+  (font-lock-preprocessor-face
+   :foreground ,(mango-theme--get-color 'pink)
+   :weight bold)
+
+  ;; Variables
+  (font-lock-variable-name-face
+   :foreground ,(mango-theme--get-color 'pale-azure))
+  (font-lock-constant-face
+   :inherit font-lock-variable-name-face
+   :weight bold)
+
+  ;; Org Mode
+  (org-code
+   :foreground ,(mango-theme--get-color 'orange))
+  (org-verbatim
+   :foreground ,(mango-theme--get-color 'lime))
+  (org-block
+   :background ,(mango-theme--get-color 'background-cool))
+  (org-hide
+   :foreground ,(mango-theme--get-color 'background))
+  (org-quote
+   :inherit org-block
+   :slant italic)
+
+  ;; Info Page
+  (Info-quoted
+   :inherit default)
+
+  ;; Magit
+  (magit-diff-hunk-heading
+   :background ,(mango-theme--get-color 'background-cool))
+  (magit-diff-hunk-heading-highlight
+   :background ,(mango-theme--get-color 'middleground))
+  (magit-diff-context-highlight
+   :inherit hl-line)
+  (magit-section-highlight
+   :inherit hl-line)
+
+  (git-commit-summary
+   :foreground ,(mango-theme--get-color 'khaki))
+  (git-commit-overlong-summary
+   :foreground ,(mango-theme--get-color 'foreground)
+   :background ,(mango-theme--get-color 'spanish-red)
+   :weight bold)
+
+  ;; Vertico
+  (vertico-current
+   :inherit hl-line))
-- 
cgit v1.2.3