From 77a712419513bb476da3a6b80c7fa530e066240f Mon Sep 17 00:00:00 2001
From: Aryadev Chavali <aryadev@aryadevchavali.com>
Date: Fri, 9 May 2025 00:07:03 +0100
Subject: Too lazy to explain this

---
 Emacs/.config/emacs/config.org | 3607 ++++++++++++++++++++--------------------
 1 file changed, 1837 insertions(+), 1770 deletions(-)

(limited to 'Emacs/.config')

diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org
index 34b593b..b1c2763 100644
--- a/Emacs/.config/emacs/config.org
+++ b/Emacs/.config/emacs/config.org
@@ -82,27 +82,29 @@ Let's setup a few absolute essentials:
 (use-package emacs
   :demand t
   :init
-  (setq user-full-name "Aryadev Chavali"
-        user-mail-address "aryadev@aryadevchavali.com"
-        buffer-file-coding-system 'utf-8-unix
-        save-buffer-coding-system 'utf-8-unix
-        backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "saves/")))
-        global-auto-revert-non-file-buffers t
-        auto-revert-verbose nil
+  (setq auth-sources '("~/.authinfo.gpg")
         auto-revert-use-notify nil
-        select-enable-clipboard t
+        auto-revert-verbose nil
+        backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "saves/")))
+        buffer-file-coding-system 'utf-8-unix
         delete-by-moving-to-trash t
+        global-auto-revert-non-file-buffers t
         remote-file-name-inhibit-delete-by-moving-to-trash t
-        use-file-dialog nil
+        save-buffer-coding-system 'utf-8-unix
+        select-enable-clipboard t
         use-dialog-box nil
+        use-file-dialog nil
+        user-full-name "Aryadev Chavali"
+        user-mail-address "aryadev@aryadevchavali.com"
         warning-minimum-level :error)
   :config
   (fset 'yes-or-no-p 'y-or-n-p)
   (global-auto-revert-mode)
-  (set-face-attribute 'default nil :height
-                      (pcase (system-name)
-                        ("rhmaiden" 120)
-                        (_ 120))))
+  (let ((font-size (pcase (system-name)
+                     ("rhmaiden" 150)
+                     (_ 120))))
+    (set-face-attribute 'default nil :height font-size)
+    (set-face-attribute 'mode-line nil :height font-size)))
 #+end_src
 * Custom functionality and libraries
 This is custom Lisp that I or someone else has written which I really
@@ -127,6 +129,11 @@ this macro.
   "For a given list of forms BODY, return a quoted 0 argument
 lambda."
   `(function (lambda nil ,@BODY)))
+
+(defmacro proc-int (&rest BODY)
+  "For a given list of forms BODY, return a quoted 0 argument
+lambda with the first form of the lambda being (INTERACTIVE)."
+  `(function (lambda nil (interactive) ,@BODY)))
 #+end_src
 ** Clean buffer list
 If you've got a particularly long running Emacs instance, as I usually
@@ -271,6 +278,20 @@ forcefully adjust the font size.
 
 (add-to-list 'enable-theme-functions #'+oreo/font-reset)
 #+end_src
+** Proper paths in Emacs
+Imagine you adjust your path in ZSH.  This change won't necessarily
+affect the results of ~(getenv "PATH")~ - you'd need to ensure Emacs
+was loaded from a recent ZSH instance.  This allows you to synchronise
+the PATH variable with the shell to avoid any silly issues.
+
+#+begin_src emacs-lisp
+(use-package exec-path-from-shell
+  :straight t
+  :demand t
+  :config
+  (when (member window-system '(mac ns x))
+    (exec-path-from-shell-initialize)))
+#+end_src
 * Essential packages
 External and internal packages absolutely necessary for the rest of
 this configuration.
@@ -398,28 +419,31 @@ set of examples on how to use general.
   :init
   (setq duplicate-line-final-position -1
         async-shell-command-buffer 'new-buffer)
+  :config
+  (defmacro +oreo/then-recenter-top (&rest actions)
+    `(proc-int ,@actions (recenter 0)))
   :general
   (leader
     "SPC" #'execute-extended-command
     "R"   #'revert-buffer
-    ":"   (proc (interactive) (switch-to-buffer "*scratch*"))
+    ":"   (proc-int (switch-to-buffer "*scratch*"))
     "!"   #'async-shell-command
     "h"   #'help-command)
 
   (mode-leader
-    "t" (proc (interactive) (+oreo/load-theme))
-    "T" (proc (interactive) (+oreo/switch-theme)))
+    "t" (proc-int (+oreo/load-theme))
+    "T" (proc-int (+oreo/switch-theme)))
 
   (code-leader
-    "F" (proc (interactive) (find-file "~/Code/")))
+    "F" (proc-int (find-file "~/Code/")))
 
   (search-leader
     "i" #'imenu)
 
   (file-leader
     "f" #'find-file
-    "P" (proc (interactive)
-              (find-file (concat user-emacs-directory "config.org")))
+    "P" (proc-int
+         (find-file (concat user-emacs-directory "config.org")))
     "F" #'find-file-other-window
     "t" #'find-file-other-tab
     "v" #'add-file-local-variable
@@ -448,25 +472,31 @@ set of examples on how to use general.
     "c" #'+literate/compile-config
     "C" #'+literate/clean-config
     "l" #'+literate/load-config
-    "s" (proc (interactive) (find-file (concat user-emacs-directory "straight/"))))
+    "s" (proc-int (find-file (concat user-emacs-directory "straight/"))))
+
+  (leader
+    :prefix "SPC n"
+    "p" #'narrow-to-page
+    "f" #'narrow-to-defun
+    "r" #'narrow-to-region
+    "w" #'widen)
 
   ;; General normal/motion state maps
   (nmmap
     :keymaps 'override
-    "M-%" #'replace-regexp-as-diff
+    "M-'" #'replace-regexp-as-diff
+    "M-%" #'query-replace-regexp
     "M-o" #'duplicate-dwim
     "M-;" #'comment-dwim
     "gC"  #'comment-dwim
     "g="  #'align-regexp
     "C--" #'text-scale-decrease
     "C-=" #'text-scale-increase
-    "C-+" #'text-scale-adjust)
+    "C-+" #'text-scale-adjust
+    "M-[" (+oreo/then-recenter-top (backward-paragraph))
+    "M-]" (+oreo/then-recenter-top (forward-paragraph)))
 
   ;; Key chord jk to exit insert-state
-  (imap
-    "j" (general-key-dispatch #'self-insert-command
-          :timeout 0.25
-          "k" #'evil-normal-state))
 
   (:keymaps 'override
    "M-ESC" #'keyboard-quit)
@@ -598,7 +628,7 @@ in it.
   :defer t
   :init
   (setq enable-recursive-minibuffers t
-        completion-styles '(basic substring flex)
+        completion-styles '(basic flex substring)
         completion-category-defaults nil
         completion-category-overrides
         '((file (styles flex partial-completion substring)))
@@ -682,6 +712,8 @@ outperforming ~icomplete~ consistently when displaying results.
    "DEL" #'vertico-directory-delete-char)
   (:state '(normal insert)
    :keymaps 'vertico-grid-map
+   "M-K" #'vertico-grid-scroll-down
+   "M-J" #'vertico-grid-scroll-up
    "M-h" #'vertico-grid-left
    "M-l" #'vertico-grid-right))
 #+end_src
@@ -721,6 +753,10 @@ embark act more like how you wish, which I've barely touch on here.
   :general
   (:keymaps 'override
    "M-m" #'embark-act)
+  :display
+  ("\\*Embark Collect \\(Live\\|Completions\\)\\*"
+   nil
+   (window-parameters (mode-line-format . none)))
   :init
   (setq embark-verbose-indicator-display-action
         '((display-buffer-in-side-window)
@@ -1539,6 +1575,7 @@ description I give won't do it justice.
 (use-package aggressive-indent
   :straight t
   :hook (emacs-lisp-mode-hook . aggressive-indent-mode)
+  :hook (scheme-mode-hook     . aggressive-indent-mode)
   :hook (lisp-mode-hook       . aggressive-indent-mode))
 #+end_src
 ** Compilation
@@ -1576,7 +1613,9 @@ so you can actually read the text.
   (nmap
     "M-r" #'recompile)
   (:keymaps 'compilation-mode-map
-   "g" nil) ;; by default this is recompile
+   "g"   nil ;; by default this is recompile
+   "M-j" #'compilation-next-error
+   "M-k" #'compilation-previous-error)
   (nmmap
     :keymaps 'compilation-mode-map
     "c" #'recompile)
@@ -1640,6 +1679,7 @@ Here I:
   (leader
     "p" project-prefix-map)
   :config
+  (setq project-vc-extra-root-markers '(".project"))
   (defun +project/command (folder)
     (format "ctags -Re -f %sTAGS %s*"
             folder folder))
@@ -1705,25 +1745,17 @@ clearly.
     "L" #'+license/insert-complete-license))
 #+end_src
 ** diff mode
-Oh diffs; the way of the ancient ones.  Nowadays we use our newfangled
-"pull requests" and "cool web interfaces" to manage changes in our
-code repositories, but old school projects use patches to make code
-changes.  They're a pain to distribute and can be very annoying to use
-when applying them to code.  Even then I somewhat like patches, if
-only for their simplicity.
-
-[[https://git.aryadevchavali.com/dwm][dwm]] uses patches for adding
-new features and Emacs has great functionality to work with patches
-effectively.  Here I configure ~diff-mode~, which provides most of
-this cool stuff, to be a bit more ergonomic with ~evil~.
-
+Good diff management is essentially mandatory in development.  Emacs
+comes with functionality out of the box to generate, manipulate, and
+apply diffs - here I configure a small subset.
 #+begin_src emacs-lisp
 (use-package diff-mode
   :general
   (nmmap
     :keymaps 'diff-mode-map
-    "}" #'diff-hunk-next
-    "{" #'diff-hunk-prev
+    "J" #'diff-hunk-next
+    "K" #'diff-hunk-prev
+    "M-RET" #'diff-apply-hunk
     "RET" #'diff-goto-source))
 #+end_src
 * Org mode
@@ -1847,6 +1879,7 @@ Emacs was very helpful here.
   :defer t
   :init
   (setq org-edit-src-content-indentation 0
+        org-bookmark-names-plist nil
         org-eldoc-breadcrumb-separator " → "
         org-enforce-todo-dependencies t
         org-export-backends '(ascii html latex odt icalendar)
@@ -1901,6 +1934,9 @@ write the code.
   :general
   (nmmap
     "M-F" #'org-open-at-point)
+  (nmmap
+    :keymaps 'org-mode-map
+    "TAB" #'org-cycle)
   (file-leader
     "l"   #'org-store-link)
   (insert-leader
@@ -1911,9 +1947,6 @@ write the code.
   (local-leader
     :states '(normal motion)
     :keymaps 'org-mode-map
-    "l" nil
-    "'" nil
-    "c" nil
     "r" #'org-list-repair
     "d" #'org-date-from-calendar
     "t" #'org-todo
@@ -1966,7 +1999,7 @@ a very tidy way to manage your time.
   (evil-set-initial-state 'org-agenda-mode 'normal)
   :general
   (file-leader
-    "a" (proc (interactive)
+    "a" (proc-int
               (--> (directory-files (car org-agenda-files))
                    (mapcar #'(lambda (x) (concat (car org-agenda-files) x)) it)
                    (completing-read "Enter directory: " it nil t)
@@ -2093,12 +2126,13 @@ learnt the basics of org).
   (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng"
         org-msg-greeting-name-limit 3)
 
-  (add-to-list 'org-msg-enforce-css
-               '(img latex-fragment-inline
-                     ((transform . ,(format "translateY(-1px) scale(%.3f)"
-                                            (/ 1.0 (if (boundp 'preview-scale)
-                                                       preview-scale 1.4))))
-                      (margin . "0 -0.35em")))))
+  (add-to-list
+   'org-msg-enforce-css
+   '(img latex-fragment-inline
+         ((transform . ,(format "translateY(-1px) scale(%.3f)"
+                                (/ 1.0 (if (boundp 'preview-scale)
+                                           preview-scale 1.4))))
+          (margin . "0 -0.35em")))))
 #+end_src
 ** Org for evil
 Evil org for some nice bindings.
@@ -2107,1928 +2141,1958 @@ Evil org for some nice bindings.
 (use-package evil-org
   :straight t
   :defer t
-  :hook (org-mode-hook . evil-org-mode)
-  :general
-  (nmmap
-    :keymaps 'org-mode-map
-    "TAB" #'org-cycle))
+  :hook (org-mode-hook . evil-org-mode))
 #+end_src
-** Org bookmark
-I maintain a bookmarks file at =~/Text/bookmarks.org=.  I would like
-the ability to construct new bookmarks and open bookmarks.  They may
-be either articles I want to read, useful information documents or
-just straight up youtube videos.  So I wrote a
-[[file:elisp/org-bookmark.el][library]] myself which does the
-appropriate dispatching and work for me.  Pretty sweet!
+* Applications
+Emacs is an operating system, now with a good text editor through
+[[*Evil - Vim emulation][Evil]].  Let's configure some apps for it.
+** Magit
+Magit is *the* git porcelain for Emacs, which perfectly encapsulates
+the git CLI.  It's so good that some people use Emacs just for it.
+It's another one of those "so indescribably good you have to try it"
+things.  I've hardly touched the Git CLI since getting Magit, and it
+has actively taught me _new_ things about Git.
 
-Also I define a template for org-capture here for bookmarks and add it
-to the list ~org-capture-templates~.
+In this case I just need to setup the bindings for it.
 
 #+begin_src emacs-lisp
-(use-package org-bookmark
+(use-package transient
+  :straight t)
+
+(use-package magit
+  :after transient
+  :straight t
   :defer t
-  :load-path "elisp/"
+  :display
+  ("magit:.*"
+   (display-buffer-same-window)
+   (inhibit-duplicate-buffer . t))
+  ("magit-diff:.*"
+   (display-buffer-below-selected))
+  ("magit-log:.*"
+   (display-buffer-same-window))
+  ("magit-revision:.*"
+   (display-buffer-below-selected)
+   (inhibit-duplicate-buffer . t))
   :general
-  (file-leader
-    "b" #'org-bookmark/open-bookmark)
+  (leader
+    "g" #'magit-dispatch)
+  (code-leader
+    "b" #'magit-blame)
+  (nmap :keymaps 'magit-status-mode-map
+    "}" #'magit-section-forward-sibling
+    "{" #'magit-section-backward-sibling)
   :init
-  (with-eval-after-load "org-capture"
-    (add-to-list
-     'org-capture-templates
-     '("b" "Bookmark" entry
-       (file "bookmarks.org")
-       "* %? :bookmark:
-%T
-%^{url|%x}p
-"
-       ))))
+  (setq vc-follow-symlinks t
+        magit-blame-echo-style 'lines
+        magit-copy-revision-abbreviated t)
+  :config
+  (with-eval-after-load "evil"
+    (evil-set-initial-state 'magit-status-mode 'motion))
+  (with-eval-after-load "evil-collection"
+    (evil-collection-magit-setup)))
 #+end_src
-* Languages
-For a variety of (programming) languages Emacs comes with default
-modes but this configures them as well as pulls any modes Emacs
-doesn't come with.
-** Makefile
-Defines an auto-insert for Makefiles.  Assumes C but it's very easy to
-change it for C++.
+*** Magit Forge
+Imagine being able to do all the bureaucratic nonsense involved on
+GitHub i.e. pull requests, issue handling, etc. all through Emacs!  No
+need to imagine any more, with Magit Forge.
+#+begin_src emacs-lisp
+(use-package forge
+  :after magit
+  :straight t
+  :config
+  (with-eval-after-load "evil-collection"
+    (evil-collection-forge-setup)))
+#+end_src
+** EWW
+Emacs Web Wowser is the inbuilt text based web browser for Emacs.  It
+can render images and basic CSS styles but doesn't have a JavaScript
+engine, which makes sense as it's primarily a text interface.
 
 #+begin_src emacs-lisp
-(use-package make-mode
+(use-package eww
   :defer t
-  :auto-insert
-  (("[mM]akefile\\'" . "Makefile skeleton")
-   ""
-	 "CC=gcc
-OUT=main.out
-LIBS=
-ARGS=
-
-RELEASE=0
-GFLAGS=-Wall -Wextra -Werror -Wswitch-enum -std=c11
-DFLAGS=-ggdb -fsanitize=address -fsanitize=undefined
-RFLAGS=-O3
-ifeq ($(RELEASE), 1)
-CFLAGS=$(GFLAGS) $(RFLAGS)
-else
-CFLAGS=$(GFLAGS) $(DFLAGS)
-endif
-
-.PHONY: all
-all: $(OUT)
-
-$(OUT): main.c
-	$(CC) $(CFLAGS) $^ -o $@ $(LIBS)
-
-.PHONY: run
-run: $(OUT)
-	./$^ $(ARGS)
-
-.PHONY:
-clean:
-	rm -v $(OUT)
-"
-   _))
+  :general
+  (app-leader
+    "w" #'eww)
+  (nmmap
+    :keymaps 'eww-mode-map
+    "w" #'evil-forward-word-begin
+    "Y" #'eww-copy-page-url))
 #+end_src
-** WAIT SQL
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no :results none
-:END:
-The default SQL package provides support for connecting to common
-database types (sqlite, mysql, etc) for auto completion and query
-execution.  I don't use SQL currently but whenever I need it it's
-there.
+** Calendar
+Calendar is a simple inbuilt application that helps with date
+functionalities.  I add functionality to copy dates from the calendar
+to the kill ring and bind it to "Y".
 
 #+begin_src emacs-lisp
-(use-package sql
+(use-package calendar
   :defer t
-  :init
-  (setq sql-display-sqli-buffer-function nil))
+  :commands (+calendar/copy-date +calendar/toggle-calendar)
+  :display
+  ("\\*Calendar\\*"
+   (display-buffer-at-bottom)
+   (inhibit-duplicate-buffer . t)
+   (window-height . 0.17))
+  :general
+  (nmmap
+    :keymaps 'calendar-mode-map
+    "Y" #'+calendar/copy-date)
+  (app-leader
+    "d" #'calendar)
+  :config
+  (defun +calendar/copy-date ()
+    "Copy date under cursor into kill ring."
+    (interactive)
+    (if (use-region-p)
+        (call-interactively #'kill-ring-save)
+      (let ((date (calendar-cursor-to-date)))
+        (when date
+          (setq date (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))
+          (kill-new (format-time-string "%Y-%m-%d" date)))))))
 #+end_src
-** NHexl
-Hexl-mode is the inbuilt package within Emacs to edit hex and binary
-format buffers.  There are a few problems with hexl-mode though,
-including an annoying prompt on /revert-buffer/.
+** Mail
+Mail is a funny thing; most people use it just for business or
+advertising and it's come out of use in terms of personal
+communication in the west for the most part (largely due to "social"
+media applications).  However, this isn't true for the open source and
+free software movement who heavily use mail for communication.
 
-Thus, nhexl-mode!  It comes with a few other improvements. Check out
-the [[https://elpa.gnu.org/packages/nhexl-mode.html][page]] yourself.
+Integrating mail into Emacs helps as I can send source code and
+integrate it into my workflow just a bit better.  There are a few
+ways of doing this, both in built and via package.
+*** Notmuch
+Notmuch is an application for categorising some local mail system.
+It's really fast, has tons of customisable functionality and has good
+integration with Emacs.  I use ~mbsync~ separately to pull my mail
+from the remote server.
 
 #+begin_src emacs-lisp
-(use-package nhexl-mode
+(use-package notmuch
   :straight t
   :defer t
-  :mode ("\\.bin" "\\.out"))
+  :commands (notmuch +mail/flag-thread)
+  :general
+  (app-leader "m" #'notmuch)
+  (nmap
+    :keymaps 'notmuch-search-mode-map
+    "f" #'+mail/flag-thread)
+  :init
+  (defconst +mail/local-dir (no-littering-expand-var-file-name "mail/"))
+  (setq notmuch-show-logo nil
+        notmuch-search-oldest-first nil
+        notmuch-hello-sections '(notmuch-hello-insert-saved-searches
+                                 notmuch-hello-insert-alltags
+                                 notmuch-hello-insert-recent-searches)
+        notmuch-archive-tags '("-inbox" "-unread" "+archive")
+        message-auto-save-directory +mail/local-dir
+        message-directory +mail/local-dir)
+  :config
+  (defun +mail/flag-thread (&optional unflag beg end)
+    (interactive (cons current-prefix-arg (notmuch-interactive-region)))
+    (notmuch-search-tag
+     (notmuch-tag-change-list '("-inbox" "+flagged") unflag) beg end)
+    (when (eq beg end)
+      (notmuch-search-next-thread))))
 #+end_src
-** NASM
+*** Smtpmail
+Setup the smtpmail package, which is used when sending mail.  Mostly
+custom configuration for integration with other parts of Emacs' mail
+system.
+
 #+begin_src emacs-lisp
-(use-package nasm-mode
-  :straight t
+(use-package smtpmail
   :defer t
-  :mode ("\\.asm" . nasm-mode))
+  :commands mail-send
+  :init
+  (setq-default
+   smtpmail-smtp-server "mail.aryadevchavali.com"
+   smtpmail-smtp-user "aryadev"
+   smtpmail-smtp-service 587
+   smtpmail-stream-type 'starttls
+   send-mail-function #'smtpmail-send-it
+   message-send-mail-function #'smtpmail-send-it))
 #+end_src
-** C/C++
-Setup for C and C++ modes, using Emacs' default package: cc-mode.
-*** cc-mode
-Tons of stuff, namely:
-+ ~auto-fill-mode~ for 80 char limit
-+ Some keybindings to make evil statement movement easy
-+ Lots of pretty symbols
-+ Indenting options and a nice (for me) code style for C
-+ Auto inserts to get a C file going
+*** Mail signature using fortune
+Generate a mail signature using the ~fortune~ executable.  Pretty
+cool!
 
 #+begin_src emacs-lisp
-(use-package cc-mode
-  :defer t
-  :hook
-  ((c-mode-hook c++-mode-hook) . auto-fill-mode)
-  :general
-  (:keymaps '(c-mode-map c++-mode-map)
-   :states '(normal motion visual)
-   "(" #'c-beginning-of-statement
-   ")" #'c-end-of-statement
-   "{" #'c-beginning-of-defun
-   "}" #'c-end-of-defun)
+(use-package fortune
+  :after message
   :init
-  (setq c-basic-offset 2
-        c-auto-newline nil
-        c-default-style '((other . "user")))
-  (add-hook 'c-mode-hook (proc (c-toggle-comment-style -1)))
-  (add-hook 'c++-mode-hook (proc (c-toggle-comment-style -1)))
-  (defun +cc/copyright-notice ()
-    (let* ((lines (split-string (+license/copyright-notice) "\n"))
-           (copyright-line (car lines))
-           (rest (cdr lines)))
-      (concat
-       "* "
-       copyright-line
-       "\n"
-       (mapconcat
-        #'(lambda (x)
-            (if (string= x "")
-                ""
-              (concat " * " x)))
-        rest
-        "\n"))))
-  :auto-insert
-  (("\\.c\\'" . "C skeleton")
-   ""
-   "/" (+cc/copyright-notice) "\n\n"
-   " * Created: " (format-time-string "%Y-%m-%d") "\n"
-   " * Description: " _ "\n"
-   " */\n"
-   "\n")
-  (("\\.cpp\\'" "C++ skeleton")
-   ""
-   "/" (+cc/copyright-notice) "\n\n"
-   " * Created: " (format-time-string "%Y-%m-%d") "\n"
-   " * Description: " _ "\n"
-   " */\n"
-   "\n")
-  (("\\.\\([Hh]\\|hh\\|hpp\\|hxx\\|h\\+\\+\\)\\'" . "C / C++ header")
-   (replace-regexp-in-string "[^A-Z0-9]" "_"
-                             (string-replace "+" "P"
-                                             (upcase
-                                              (file-name-nondirectory buffer-file-name))))
-   "/" (+cc/copyright-notice) "\n\n"
-   " * Created: " (format-time-string "%Y-%m-%d") "\n"
-   " * Description: " _ "\n"
-   " */\n\n"
-   "#ifndef " str n "#define " str "\n\n" "\n\n#endif")
-  :config
-  (c-add-style
-   "user"
-   '((c-basic-offset . 2)
-     (c-comment-only-line-offset . 0)
-     (c-hanging-braces-alist (brace-list-open)
-                             (brace-entry-open)
-                             (substatement-open after)
-                             (block-close . c-snug-do-while)
-                             (arglist-cont-nonempty))
-     (c-cleanup-list brace-else-brace)
-     (c-offsets-alist
-      (statement-block-intro . +)
-      (substatement-open . 0)
-      (access-label . -)
-      (inline-open  . 0)
-      (label . 0)
-      (statement-cont . +)))))
-#+end_src
-*** Clang format
-clang-format is a program that formats C/C++ files.  It's highly
-configurable and quite fast.  I have a root configuration in my
-Dotfiles (check it out
-[[file:~/Dotfiles/ClangFormat/).clang-format][here]].
-
-Clang format comes inbuilt with clang/LLVM, so it's quite likely to be
-on your machine.
-
-#+begin_src emacs-lisp
-(use-package clang-format
-  :load-path "/usr/share/clang/"
-  :defer t
-  :after cc-mode
-  :commands (+code/clang-format-region-or-buffer
-             clang-format-mode)
-  :general
-  (code-leader
-    :keymaps '(c-mode-map c++-mode-map)
-    "f" #'clang-format-buffer)
+  (setq fortune-dir "/usr/share/fortune"
+        fortune-file "/usr/share/fortune/cookie")
   :config
-  (define-minor-mode clang-format-mode
-    "On save formats the current buffer via clang-format."
-    :lighter nil
-    (let ((save-func (proc (interactive)
-                           (clang-format-buffer))))
-      (if clang-format-mode
-          (add-hook 'before-save-hook save-func nil t)
-        (remove-hook 'before-save-hook save-func t))))
-  (defun +code/clang-format-region-or-buffer ()
+  (defvar +mail/signature "---------------\nAryadev Chavali\n---------------\n%s")
+  (defun +mail/make-signature ()
     (interactive)
-    (if (mark)
-        (clang-format-region (region-beginning) (region-end))
-      (clang-format-buffer))))
-#+end_src
-*** cc org babel
-To ensure org-babel executes language blocks of C/C++, I need to load
-it as an option in ~org-babel-load-languages~.
-
-#+begin_src emacs-lisp
-(use-package org
-  :after cc-mode
-  :init
-  (org-babel-do-load-languages
-   'org-babel-load-languages
-   '((C . t))))
-#+end_src
-*** cc compile fsan
-Sanitisers are a blessing for C/C++.  An additional runtime on top of
-the executable which catches stuff like undefined behaviour or memory
-leaks make it super easy to see where and how code is failing.
-However, by default, Emacs' compilation-mode doesn't understand the
-logs =fsanitize= makes so you usually have to manually deal with it
-yourself.
-
-Compilation mode uses regular expressions to figure out whether
-something is an error and how to navigate to the file where that error
-is located.  So adding support for =-fsanitize= is as simple as making
-a regular expression which captures file names and digits
-
-#+begin_src emacs-lisp
-(use-package compile
-  :after cc-mode
-  :config
-  (add-to-list 'compilation-error-regexp-alist-alist
-               `(fsan ,(rx (and
-                            line-start "    #" digit " 0x" (1+ hex) " in "
-                            (1+ (or word "_")) " "
-                            (group (seq (* any) (or ".c" ".cpp" ".h" ".hpp"))) ":"
-                            (group (+ digit))))
-
-                      1 2))
-  (add-to-list 'compilation-error-regexp-alist
-               'fsan))
-#+end_src
-** Markdown
-Why use Markdown when you have org-mode?  Because LSP servers
-sometimes format their documentation as markdown, which
-[[*Eglot][Eglot]] can use to provide nicer views on docs!
-#+begin_src emacs-lisp
-(use-package markdown-mode
-  :defer t
-  :straight t)
-#+end_src
-** WAIT Rust
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no :results none
-:END:
-2025-02-15: Haven't needed to use Rust at all recently - but leaving
-this here in case.
-
-Rust is the systems programming language that also does web stuff and
-CLI programs and basically tries to be a jack of all trades.  It's got
-some interesting stuff but most importantly it's very new, so everyone
-must learn it, right?
-
-#+begin_src emacs-lisp
-(use-package rust-mode
-  :straight t
-  :defer t
-  :general
-  (code-leader
-    :keymaps 'rust-mode-map
-    "f" #'rust-format-buffer)
-  (local-leader
-    :keymaps 'rust-mode-map
-    "c" #'rust-run-clippy)
-  :init
-  (setq rust-format-on-save t)
-  (with-eval-after-load "eglot"
-    (add-to-list 'eglot-server-programs '(rust-mode "rust-analyzer"))))
-#+end_src
-** WAIT Racket
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no :results none
-:END:
-A scheme with lots of stuff inside it.  Using it for a language design
-book so it's useful to have some Emacs binds for it.
-
-#+begin_src emacs-lisp
-(use-package racket-mode
-  :straight t
-  :defer t
-  :hook (racket-mode-hook . racket-xp-mode)
-  :display
-  ("\\*Racket REPL*"
-   (display-buffer-at-bottom)
-   (window-height . 0.3))
-  :init
-  (setq racket-documentation-search-location 'local)
-  :general
-  (nmap
-    :keymaps 'racket-describe-mode-map
-    "q" #'quit-window)
-  (nmap
-    :keymaps 'racket-mode-map
-    "gr" #'racket-eval-last-sexp)
-  (local-leader
-    :keymaps '(racket-mode-map racket-repl-mode-map)
-    "d" #'racket-repl-describe)
-  (local-leader
-    :keymaps 'racket-mode-map
-    "r" #'racket-run
-    "i" #'racket-repl
-    "e" #'racket-send-definition
-    "sr" #'racket-send-region
-    "sd" #'racket-send-definition))
+    (format +mail/signature
+            (with-temp-buffer
+              (let ((fortune-buffer-name (current-buffer)))
+                (fortune-in-buffer t)
+                (if (bolp) (delete-char -1))
+                (buffer-string)))))
+  ;; (add-hook 'message-setup-hook
+  ;;           (lambda nil (setq message-signature (+mail/make-signature))))
+  )
 #+end_src
-** WAIT Haskell
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no :results none
-:END:
-2025-02-15: Haskell is a fun language so I'll leave this configuration
-for now.
-
-Haskell is a static lazy functional programming language (what a
-mouthful).  It's quite a beautiful language and really learning it
-will change the way you think about programming.  However, my
-preferred functional language is still unfortunately Lisp so no extra
-brownie points there.
-
-Here I configure the REPL for Haskell via the
-~haskell-interactive-mode~.  I also load my custom package
-[[file:elisp/haskell-multiedit.el][haskell-multiedit]] which allows a
-user to create temporary ~haskell-mode~ buffers that, upon completion,
-will run in the REPL.  Even easier than making your own buffer.
+** Dired
+Dired: Directory editor for Emacs.  An incredibly nifty piece of
+software which deeply integrates with Emacs as a whole.  I can't think
+of a better file management tool than this.
+*** Dired Core
+Here I setup dired with a few niceties
++ Hide details by default (no extra stuff from ~ls~)
++ Omit dot files by default (using ~dired-omit-mode~)
++ If I have two dired windows open, moving or copying files in one
+  dired instance will automatically target the other dired window
+  (~dired-dwim~)
++ If opening an application on a PDF file, suggest ~zathura~
++ Examine all the subdirectories within the same buffer
+  (~+dired/insert-all-subdirectories~)
 
 #+begin_src emacs-lisp
-(use-package haskell-mode
-  :straight t
+(use-package dired
   :defer t
+  :commands (dired find-dired)
   :hook
-  (haskell-mode-hook . haskell-indentation-mode)
-  (haskell-mode-hook . interactive-haskell-mode)
-  :display
-  ("\\*haskell.**\\*"
-   (display-buffer-at-bottom)
-   (window-height . 0.3))
-  :general
-  (shell-leader
-    "h" #'haskell-interactive-bring)
-  (local-leader
-    :keymaps 'haskell-mode-map
-    "c" #'haskell-compile
-    "t" #'haskell-process-do-type)
-  (nmmap
-    :keymaps 'haskell-mode-map
-    "C-c C-c" #'haskell-process-load-file)
-  (local-leader
-    :keymaps 'haskell-interactive-mode-map
-    "c" #'haskell-interactive-mode-clear)
-  (imap
-    :keymaps 'haskell-interactive-mode-map
-    "M-k" #'haskell-interactive-mode-history-previous
-    "M-j" #'haskell-interactive-mode-history-next)
+  (dired-mode-hook . auto-revert-mode)
+  (dired-mode-hook . dired-hide-details-mode)
+  (dired-mode-hook . dired-omit-mode)
   :init
-  (setq haskell-interactive-prompt "[λ] "
-        haskell-interactive-prompt-cont "{λ} "
-        haskell-interactive-popup-errors nil
-        haskell-stylish-on-save t
-        haskell-process-type 'auto)
-  :config
-  (load (concat user-emacs-directory "elisp/haskell-multiedit.el")))
-#+end_src
-** Python
-Works well for python.  If you have ~pyls~ it should be on your path, so
-just run eglot if you need.  But an LSP server is not necessary for a
-lot of my time in python.  Here I also setup org-babel for python
-source code blocks.
-
-#+begin_src emacs-lisp
-(use-package python
-  :defer t
+  (setq-default dired-listing-switches "-AFBlu --group-directories-first"
+                dired-omit-files "^\\." ; dotfiles
+                dired-omit-verbose nil
+                dired-dwim-target t
+                dired-kill-when-opening-new-dired-buffer t)
   :general
   (nmmap
-    :keymaps 'python-mode-map
-    "C-M-x" #'python-shell-send-defun)
-  (local-leader
-    :keymaps 'python-mode-map
-    "c" #'python-check)
-  (local-leader
-    :keymaps 'python-mode-map
-    :infix "e"
-    "e" #'python-shell-send-statement
-    "r" #'python-shell-send-region
-    "f" #'python-shell-send-buffer)
-  :pretty
-  (python-mode-hook
-   ("None"   . "Ø")
-   ("list"   . "ℓ")
-   ("List"   . "ℓ")
-   ("str"    . "𝕊")
-   ("!"      . "¬")
-   ("for"    . "∀")
-   ("print"  . "φ")
-   ("lambda" . "λ")
-   ("reduce" . "↓")
-   ("map"    . "→")
-   ("return" . "≡")
-   ("yield"  . "≈"))
-  :init
-  (setq python-indent-offset 4)
-  :config
-  (with-eval-after-load "org-mode"
-    (setf (alist-get 'python org-babel-load-languages) t)))
-#+end_src
-*** Python shell
-Setup for python shell, including a toggle option
-
-#+begin_src emacs-lisp
-(use-package python
-  :defer t
-  :commands +python/toggle-repl
-  :general
-  (shell-leader
-    "p" #'run-python)
-  :hook
-  (inferior-python-mode-hook . company-mode)
-  :display
-  ("\\*Python\\*"
-   (display-buffer-at-bottom)
-   (window-height . 0.3)))
-#+end_src
-** YAML
-YAML is a data language which is useful for config files.
-
-#+begin_src emacs-lisp
-(use-package yaml-mode
-  :defer t
-  :straight t)
-#+end_src
-** HTML/CSS/JS
-Firstly, web mode for consistent colouring of syntax.
-
-#+begin_src emacs-lisp
-(use-package web-mode
-  :straight t
-  :defer t
-  :mode ("\\.html" . web-mode)
-  :mode ("\\.css"  . web-mode)
-  :custom
-  ((web-mode-code-indent-offset 2)
-   (web-mode-markup-indent-offset 2)
-   (web-mode-css-indent-offset 2)))
-#+end_src
-*** Emmet
-Emmet for super speed code writing.
-
-#+begin_src emacs-lisp
-(use-package emmet-mode
-  :straight t
-  :defer t
-  :hook (web-mode-hook . emmet-mode)
-  :general
-  (imap
-    :keymaps 'emmet-mode-keymap
-    "TAB" #'emmet-expand-line
-    "M-j" #'emmet-next-edit-point
-    "M-k" #'emmet-prev-edit-point))
-#+end_src
-*** HTML Auto insert
-An auto-insert for HTML buffers, which just adds some nice stuff.
-
-#+begin_src emacs-lisp
-(use-package web-mode
-  :defer t
-  :auto-insert
-  (("\\.html\\'" . "HTML Skeleton")
-   ""
-   "<!doctype html>
-<html lang=''>
-  <head>
-    <meta charset='utf-8'>
-    <title>"(read-string "Enter title: ") | """</title>
-    <meta name='description' content='" (read-string "Enter description: ") | "" "'>
-    <meta name='author' content='"user-full-name"'/>
-    <meta name='viewport' content='width=device-width, initial-scale=1'>
+    :keymaps 'dired-mode-map
+    "SPC"   nil
+    "SPC ," nil
+    "M-k"                    #'dired-prev-subdir
+    "M-j"                    #'dired-next-subdir
+    "q"                      #'quit-window
+    "j"                      #'dired-next-line
+    "k"                      #'dired-previous-line
+    "("                      #'dired-hide-details-mode
+    ")"                      #'dired-omit-mode
+    "T"                      #'dired-create-empty-file
+    "H"                      #'dired-up-directory
+    "L"                      #'dired-find-file
+    "#"                      #'dired-flag-auto-save-files
+    "."                      #'dired-clean-directory
+    "~"                      #'dired-flag-backup-files
+    "A"                      #'dired-do-find-regexp
+    "C"                      #'dired-do-copy
+    "B"                      #'dired-do-byte-compile
+    "D"                      #'dired-do-delete
+    "M"                      #'dired-do-chmod
+    "O"                      #'dired-do-chown
+    "P"                      #'dired-do-print
+    "Q"                      #'dired-do-find-regexp-and-replace
+    "R"                      #'dired-do-rename
+    "S"                      #'dired-do-symlink
+    "T"                      #'dired-do-touch
+    "X"                      #'dired-do-shell-command
+    "Z"                      #'dired-do-compress
+    "c"                      #'dired-do-compress-to
+    "!"                      #'dired-do-shell-command
+    "&"                      #'dired-do-async-shell-command
+    "{"                      #'dired-prev-marked-file
+    "}"                      #'dired-next-marked-file
+    "%" nil
+    "%u"                     #'dired-upcase
+    "%l"                     #'dired-downcase
+    "%d"                     #'dired-flag-files-regexp
+    "%g"                     #'dired-mark-files-containing-regexp
+    "%m"                     #'dired-mark-files-regexp
+    "%r"                     #'dired-do-rename-regexp
+    "%C"                     #'dired-do-copy-regexp
+    "%H"                     #'dired-do-hardlink-regexp
+    "%R"                     #'dired-do-rename-regexp
+    "%S"                     #'dired-do-symlink-regexp
+    "%&"                     #'dired-flag-garbage-files
+    "*" nil
+    "**"                     #'dired-mark-executables
+    "*/"                     #'dired-mark-directories
+    "*@"                     #'dired-mark-symlinks
+    "*%"                     #'dired-mark-files-regexp
+    "*c"                     #'dired-change-marks
+    "*s"                     #'dired-mark-subdir-files
+    "*m"                     #'dired-mark
+    "*t"                     #'dired-toggle-marks
+    "*?"                     #'dired-unmark-all-files
+    "*!"                     #'dired-unmark-all-marks
+    "U"                      #'dired-unmark-all-marks
+    "a"                      #'dired-find-alternate-file
+    "d"                      #'dired-flag-file-deletion
+    "gf"                     #'browse-url-of-dired-file
+    "gr"                     #'revert-buffer
+    "i"                      #'dired-toggle-read-only
+    "J"                      #'dired-goto-file
+    "K"                      #'dired-do-kill-lines
+    "r"                      #'revert-buffer
+    "m"                      #'dired-mark
+    "t"                      #'dired-toggle-marks
+    "u"                      #'dired-unmark
+    "x"                      #'dired-do-flagged-delete
+    "gt"                     #'dired-show-file-type
+    "Y"                      #'dired-copy-filename-as-kill
+    "+"                      #'dired-create-directory
+    "RET"                    #'dired-find-file
+    "C-<return>"             #'dired-find-file-other-window
+    "o"                      #'dired-sort-toggle-or-edit
+    "[["                     #'dired-prev-dirline
+    "]]"                     #'dired-next-dirline
+    [remap next-line]        #'dired-next-line
+    [remap previous-line]    #'dired-previous-line
+    "zt"                     #'dired-hide-subdir
+    "zC"                     #'dired-hide-all
+    [remap read-only-mode]   #'dired-toggle-read-only
+    [remap toggle-read-only] #'dired-toggle-read-only
+    [remap undo]             #'dired-undo
+    [remap advertised-undo]  #'dired-undo)
+  (leader
+    "D" #'dired-jump)
+  (dir-leader
+    "f" #'find-dired
+    "d" #'dired
+    "D" #'dired-other-window
+    "i" #'image-dired
+    "b" (proc-int (find-file "~/Text/Books/")))
+  (local-leader
+    :keymaps 'dired-mode-map
+    "i" #'dired-maybe-insert-subdir
+    "d" #'dired-goto-subdir
+    "I" #'+dired/insert-all-subdirectories
+    "o" #'dired-omit-mode
+    "K" #'dired-kill-subdir
+    "m" #'dired-mark-files-regexp
+    "u" #'dired-undo)
+  :config
+  (add-multiple-to-list dired-guess-shell-alist-user
+                        '("\\.pdf\\'"    "zathura")
+                        '("\\.epub\\'"   "zathura")
+                        '("\\.jpg\\'"    "feh")
+                        '("\\.png\\'"    "feh")
+                        '("\\.webm\\'"   "mpv")
+                        '("\\.mp[34]\\'" "mpv")
+                        '("\\.mkv\\'"    "mpv"))
 
-    <link rel='apple-touch-icon' href='/apple-touch-icon.png'>
-    <link rel='shortcut icon' href='/favicon.ico'/>
-  </head>
-  <body>
-"
-   _
-   "     </body>
-</html>"))
-#+end_src
-*** Javascript Mode
-A better mode for JavaScript that also has automatic integration with
-eglot.
+  (defun +dired/--subdirs-not-inserted ()
+    (dired-unmark-all-marks)
+    (dired-mark-directories nil)
+    (let* ((subdirs-inserted (mapcar #'car dired-subdir-alist))
+           (subdirs-available (mapcar #'(lambda (x) (concat x "/"))
+                                 (dired-get-marked-files))))
+      (dired-unmark-all-marks)
+      (cl-remove-if #'(lambda (f) (member f subdirs-inserted)) subdirs-available)))
 
-#+begin_src emacs-lisp
-(use-package js
-  :defer t
-  :mode ("\\.js" . js-mode)
-  :hook (js-mode-hook . auto-fill-mode)
-  :init
-  (setq js-indent-level 2))
+  (defun +dired/insert-all-subdirectories (&optional arg)
+    "Insert all subdirectories recursively."
+    (interactive "P")
+    (let ((subdirs-left (+dired/--subdirs-not-inserted)))
+      (if (null arg)
+          (mapc #'dired-insert-subdir subdirs-left)
+        (while subdirs-left
+          (mapc #'dired-insert-subdir subdirs-left)
+          (setq subdirs-left (+dired/--subdirs-not-inserted)))))))
 #+end_src
-*** Typescript
-A language that adds a build step to JavaScript projects for "static"
-typing.  It's nice because it adds good auto completion.
+*** image-dired
+Image dired is a little cherry on top for Dired: the ability to look
+through swathes of images in a centralised fashion while still being
+able to do all the usual dired stuff as well is really cool.
 
 #+begin_src emacs-lisp
-(use-package typescript-mode
-  :straight t
+(use-package dired
   :defer t
   :init
-  (setq typescript-indent-level 2))
+  (setq image-dired-external-viewer "nsxiv")
+  :general
+  (nmmap
+    :keymaps 'image-dired-thumbnail-mode-map
+    "h"   #'image-dired-backward-image
+    "l"   #'image-dired-forward-image
+    "j"   #'image-dired-next-line
+    "k"   #'image-dired-previous-line
+    "H"   #'image-dired-display-previous
+    "L"   #'image-dired-display-next
+    "RET" #'image-dired-display-this
+    "m"   #'image-dired-mark-thumb-original-file
+    "q"   #'quit-window))
 #+end_src
-** Scheme
-Another Lisp but simpler than the rest.  A beauty of engineering and
-fun to write programs in.  Here I setup ~geiser~, which is the
-premiere way to interact with scheme REPLs.
+*** fd-dired
+Uses fd for finding file results in a directory: ~find-dired~ ->
+~fd-dired~.
 
 #+begin_src emacs-lisp
-(use-package geiser
-  :defer t
+(use-package fd-dired
   :straight t
-  :display
-  ("\\*Geiser.*"
-   (display-buffer-reuse-mode-window display-buffer-at-bottom)
-   (window-height . 0.3))
+  :after dired
   :general
-  (shell-leader
-    "S" #'geiser)
-  (local-leader
-    :keymaps 'scheme-mode-map
-    "t"  #'geiser
-    "m"  #'geiser-doc-look-up-manual
-    "d" #'geiser-doc-symbol-at-point)
-  (local-leader
-    :keymaps 'scheme-mode-map
-    :infix "e"
-    "e" #'geiser-eval-last-sexp
-    "b" #'geiser-eval-buffer
-    "d" #'geiser-eval-definition
-    "r" #'geiser-eval-region)
-  :init
-  (with-eval-after-load "evil"
-    (evil-set-initial-state 'geiser-debug-mode-map 'emacs)))
-
-(use-package geiser-guile
-  :defer t
-  :straight t)
-#+end_src
-** WAIT Ocaml
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no :results none
-:END:
-*** Ocaml Setup
-Firstly, install ~opam~ and ~ocaml~.  Then run the following script:
-#+begin_src sh
-opam install tuareg ocamlformat odoc utop merlin user-setup;
-opam user-setup install;
-mv ~/.emacs.d/opam-user-setup.el ~/.config/emacs/elisp;
-rm -rf ~/.emacs.d ~/.emacs;
+  (dir-leader
+    "g" #'fd-dired))
 #+end_src
+*** wdired
+Similar to [[*(Rip)grep][wgrep]] =wdired= provides
+the ability to use Emacs motions and editing on file names.  This
+makes stuff like mass renaming and other file management tasks way
+easier than even using the mark based system.
 
-This sets up the necessary packages (particularly Emacs Lisp) and some
-configuration that ensures Emacs is consistent with the user
-installation.  Notice the moving of =opam-user-setup.el= into
-=~/.config/emacs/elisp=, which we'll use to setup the ocaml
-experience.
-*** Ocaml Configuration
-Here I load the =opam-user-setup= package setup earlier, with some
-neat tips from the default =~/.emacs= generated by ~opam user-setup
-install~.
 #+begin_src emacs-lisp
-(use-package opam-user-setup
-  :defer t
-  :load-path "elisp/"
-  :mode ("\\.ml" . tuareg-mode)
-  :hook (tuareg-mode-hook . whitespace-mode)
-  :display
-  ("\\*utop\\*"
-   (display-buffer-at-bottom)
-   (window-height . 0.3))
+(use-package wdired
+  :after dired
+  :hook (wdired-mode-hook . undo-tree-mode)
   :general
-  (code-leader
-    :keymaps 'tuareg-mode-map
-    "f" #'+ocaml/format-buffer)
+  (nmmap
+    :keymaps 'dired-mode-map
+    "W" #'wdired-change-to-wdired-mode)
+  (nmmap
+    :keymaps 'wdired-mode-map
+    "ZZ" #'wdired-finish-edit
+    "ZQ" #'wdired-abort-changes)
   :config
-  (defun +ocaml/format-buffer ()
-    (interactive)
-    (when (eq major-mode 'tuareg-mode)
-      (let ((name (buffer-file-name (current-buffer)))
-            (format-str "ocamlformat -i --enable-outside-detected-project %s"))
-        (save-buffer)
-        (set-process-sentinel (start-process-shell-command "ocamlformat" "*ocamlformat*"
-                                                           (format format-str name))
-                              (lambda (p event)
-                                (when (string= event "finished\n")
-                                  (revert-buffer nil t)
-                                  (message "[ocamlformat] Finished.")))))))
-  (add-to-list 'compilation-error-regexp-alist-alist
-               `(ocaml
-                 "[Ff]ile \\(\"\\(.*?\\)\", line \\(-?[0-9]+\\)\\(, characters \\(-?[0-9]+\\)-\\([0-9]+\\)\\)?\\)\\(:\n\\(\\(Warning .*?\\)\\|\\(Error\\)\\):\\)?"
-                 2 3 (5 . 6) (9 . 11) 1 (8 compilation-message-face)))
-  (add-to-list 'compilation-error-regexp-alist
-               'ocaml)
-  :general
-  (local-leader
-    :keymaps 'tuareg-mode-map
-    "u" #'utop)
-  (local-leader
-    :keymaps 'tuareg-mode-map
-    :infix "e"
-    "r" #'utop-eval-region
-    "e" #'utop-eval-phrase
-    "b" #'utop-eval-buffer))
-
-(use-package merlin-eldoc
-  :straight t
-  :after opam-user-setup
-  :hook
-  (tuareg-mode-hook . merlin-eldoc-setup)
-  :init
-  (setq merlin-eldoc-occurrences nil))
+  (eval-after-load "evil"
+    ;; 2024-09-07: Why does evil-set-initial-state returning a list of modes for
+    ;; normal state make eval-after-load evaluate as if it were an actual
+    ;; expression?
+    (progn (evil-set-initial-state 'wdired-mode 'normal)
+           nil)))
 #+end_src
-** Lisp
-Emacs is the greatest Lisp editor around, there are no two ways about
-it.  Here I setup the configuration for Emacs Lisp and Common Lisp.
-*** Lisp configuration
-All the general stuff I do for any other language: pretty symbols and
-key bindings.
+*** dired-rsync
+Rsync is a great way of transferring files around *nix machines, and I
+use dired for all my file management concerns.  So I should be able to
+rsync stuff around if I want.
+
 #+begin_src emacs-lisp
-(use-package lisp-mode
-  :pretty
-  (lisp-mode-hook
-   ("lambda" . "λ")
-   ("nil"    . "Ø")
-   ("<="     . "≤")
-   (">="     . "≥")
-   ("defun"  . "ƒ")
-   ("mapcar" . "→")
-   ("reduce" . "↓")
-   ("some"   . "∃")
-   ("every"  . "∀")
-   ("LAMBDA" . "λ")
-   ("NIL"    . "Ø")
-   ("<="     . "≤")
-   (">="     . "≥")
-   ("DEFUN"  . "ƒ")
-   ("MAPCAR" . "→")
-   ("REDUCE" . "↓")
-   ("SOME"   . "∃")
-   ("EVERY"  . "∀"))
-  (emacs-lisp-mode-hook
-   ("lambda" . "λ")
-   ("nil"    . "Ø")
-   ("defun"  . "ƒ")
-   ("mapcar" . "→")
-   ("LAMBDA" . "λ")
-   ("NIL"    . "Ø")
-   ("DEFUN"  . "ƒ")
-   ("MAPCAR" . "→"))
+(use-package dired-rsync
+  :straight t
+  :after dired
   :general
-  (:states '(normal motion insert visual)
-   :keymaps 'lisp-mode-shared-map
-   "C-j" #'sp-forward-slurp-sexp
-   "C-k" #'sp-forward-barf-sexp)
-  (:states '(normal motion visual)
-   :keymaps 'lisp-mode-shared-map
-   ")" #'sp-next-sexp
-   "(" #'sp-previous-sexp))
+  (nmmap
+    :keymaps 'dired-mode-map
+    "M-r" #'dired-rsync))
 #+end_src
-*** Common Lisp auto insert
-Like C/C++'s auto insert, but with Common Lisp comments.
+** EShell
+*** Why EShell?
+EShell is an integrated shell environment for Emacs, written in Emacs
+Lisp.  Henceforth I will argue that it is the best shell/command
+interpreter to use in Emacs, so good that you should eschew any second
+class terminal emulators (~term~, ~shell~, etc).
+
+EShell is unlike the other alternatives in Emacs as it's a /shell/
+first, not a terminal emulator (granted, with the ability to spoof
+some aspects of a terminal emulator).
+
+The killer benefits of EShell (which would appeal particularly to an
+Emacs user) are a direct consequence of EShell being written in Emacs
+Lisp:
+- strong integration with Emacs utilities (such as ~dired~,
+  ~find-file~, any read functions, etc)
+- very extensible, easy to write new commands which leverage Emacs
+  commands as well as external utilities
+- agnostic of platform: "eshell/cd" will call the underlying change
+  directory function for you, so commands will (usually) mean the same
+  thing regardless of platform
+  - this means as long as Emacs can run on an operating system, one
+    may run EShell
+- mixing of Lisp and shell commands, with piping!
+
+However, my favourite feature of EShell is the set of evaluators that
+run on command input.  Some of the benefits listed above come as a
+consequence of this powerful feature.
+
+The main evaluator for any expression for EShell evaluates an
+expression by testing the first symbol against different namespaces.
+The namespaces are ordered such that if a symbol is not found in one,
+the next namespace is tested.  These namespaces are:
+- alias (defined in the [[file:.config/eshell/aliases][aliases
+  file]])
+- "built-in" command i.e. in the ~eshell/~ namespace of functions
+- external command
+- Lisp function
+
+You can direct EShell to use these latter two namespaces: any
+expression delimited by parentheses is considered a Lisp expression,
+and any expression delimited by curly braces is considered an external
+command.  You may even pipe the results of one into another, allowing
+a deeper level of integration between Emacs Lisp and the shell!
+*** EShell basics
+Setup some niceties of any shell program and some evil-like movements
+for easy shell usage, both in and out of insert mode.
+
+NOTE: This mode doesn't allow you to set maps the normal way; you need
+to set keybindings on eshell-mode-hook, otherwise it'll just overwrite
+them.
+
 #+begin_src emacs-lisp
-(use-package lisp-mode
+(use-package eshell
+  :defer t
+  :display
+  ("\\*eshell\\*"
+   (display-buffer-same-window)
+   (reusable-frames . t))
   :init
-  (defun +lisp/copyright-notice ()
-    (let* ((lines (split-string (+license/copyright-notice) "\n"))
-           (copyright-line (car lines))
-           (rest (cdr lines)))
-      (-->
-       (lambda (x)
-         (if (string= x "")
-             ""
-           (concat ";; " x)))
-       (mapconcat it rest "\n")
-       (format ";; %s\n%s\n"
-               copyright-line
-               it))))
-  :auto-insert
-  (("\\.lisp\\'" . "Common Lisp Skeleton")
-   ""
-   ";;; " (file-name-nondirectory (buffer-file-name)) " - "
-   (format-time-string "%Y-%m-%d") "\n\n"
-   (+lisp/copyright-notice) "\n"
-   ";;; Commentary:\n\n;;\n\n;;; Code:\n"))
+  (defun +eshell/banner-message ()
+    (concat (shell-command-to-string "fortune") "\n"))
+
+  (setq eshell-cmpl-ignore-case t
+        eshell-cd-on-directory t
+        eshell-cd-shows-directory nil
+        eshell-highlight-prompt nil
+        eshell-banner-message '(+eshell/banner-message))
+
+  (defun +eshell/good-clear ()
+    (interactive)
+    (eshell/clear-scrollback)
+    (eshell-send-input))
+
+  (add-hook
+   'eshell-mode-hook
+   (defun +eshell/--setup-keymap nil
+     (interactive)
+     (general-def
+       :states '(normal insert visual)
+       :keymaps 'eshell-mode-map
+       "M-j" #'eshell-next-prompt
+       "M-k" #'eshell-previous-prompt
+       "C-j" #'eshell-next-matching-input-from-input
+       "C-k" #'eshell-previous-matching-input-from-input)
+
+     (local-leader
+       :keymaps 'eshell-mode-map
+       "g" (proc-int
+                 (let ((buffer (current-buffer)))
+                   (eshell/goto)
+                   (with-current-buffer buffer
+                     (eshell-send-input))))
+       "l" (proc-int
+                 (eshell-return-to-prompt)
+                 (insert "ls")
+                 (eshell-send-input))
+       "c" #'+eshell/good-clear
+       "k" #'eshell-kill-process))))
 #+end_src
-*** Sly
-While Emacs does an okay job for editing Common Lisp it's not amazing
-for actually developing large scale projects.  Considering how good an
-environment Emacs is for Emacs Lisp, and how similar the two languages
-are, we shouldn't need an LSP.
+*** EShell prompt
+Here I use my external library
+[[file:elisp/eshell-prompt.el][eshell-prompt]], which provides a
+dynamic prompt for EShell.  Current features include:
+- Git repository details (with difference from remote and number of
+  modified files)
+- Current date and time
+- A coloured prompt character which changes colour based on the exit
+  code of the previous command
 
-Enter /SLY/.  Sly is a fork of /SLIME/ and it provides the essential
-components to elevate Emacs' ability to develop Common Lisp.  I feel
-calling the ability Sly gives you "IDE-like" a slight against it - no
-IDE I have used is as capable in aiding development as Emacs + Sly.
+NOTE: I don't defer this package because it doesn't use any EShell
+internals without autoloading.
 
 #+begin_src emacs-lisp
-(use-package sly
-  :defer t
-  :straight t
-  :init
-  (setq inferior-lisp-program "sbcl"
-        sly-lisp-loop-body-forms-indentation 0)
-  :display
-  ("\\*sly-db"
-   (display-buffer-at-bottom)
-   (window-height . 0.25))
-  ("\\*sly-inspector"
-   (display-buffer-at-bottom)
-   (window-height . 0.25))
-  ("\\*sly-mrepl"
-   (display-buffer-in-side-window)
-   (window-width . 0.3)
-   (side . right))
+(use-package eshell-prompt
+  :load-path "elisp/"
   :config
-  (evil-set-initial-state 'sly-db-mode 'normal)
-  (with-eval-after-load "org"
-    (setq-default org-babel-lisp-eval-fn #'sly-eval))
-  (with-eval-after-load "company"
-    (add-hook 'sly-mrepl-hook #'company-mode))
-  :general
-  (shell-leader
-    "s" #'sly)
-  (nmap
-    :keymaps 'lisp-mode-map
-    "gr"  #'sly-eval-buffer
-    "gd"  #'sly-edit-definition
-    "gR"  #'sly-who-calls)
-
-  (local-leader
-    :keymaps 'lisp-mode-map
-    "a" #'sly-apropos
-    "d" #'sly-describe-symbol
-    "s" #'sly-mrepl-sync
-    "l" #'sly-load-file
-    "c" #'sly-compile-defun
-    "D" #'sly-documentation-lookup
-    "C" #'sly-compile-file)
-  (local-leader
-    :keymaps 'lisp-mode-map
-    :infix "e"
-    "b" #'sly-eval-buffer
-    "e" #'sly-eval-last-expression
-    "f" #'sly-eval-defun
-    "r" #'sly-eval-region)
-  (nmap
-    :keymaps 'sly-mrepl-mode-map
-    "M-j" #'sly-mrepl-next-input-or-button
-    "M-k" #'sly-mrepl-previous-input-or-button
-    "C-j" #'sly-mrepl-next-prompt
-    "C-k" #'sly-mrepl-previous-prompt)
-  (local-leader
-    :keymaps 'sly-mrepl-mode-map
-    "c" #'sly-mrepl-clear-repl
-    "s" #'sly-mrepl-shortcut)
-  (nmap
-    :keymaps 'sly-db-mode-map
-    "C-i" #'sly-db-cycle
-    "g?"  #'describe-mode
-    "S"   #'sly-db-show-frame-source
-    "e"   #'sly-db-eval-in-frame
-    "d"   #'sly-db-pprint-eval-in-frame
-    "D"   #'sly-db-disassemble
-    "i"   #'sly-db-inspect-in-frame
-    "gj"  #'sly-db-down
-    "gk"  #'sly-db-up
-    "C-j" #'sly-db-down
-    "C-k" #'sly-db-up
-    "]]"  #'sly-db-details-down
-    "[["  #'sly-db-details-up
-    "M-j" #'sly-db-details-down
-    "M-k" #'sly-db-details-up
-    "G"   #'sly-db-end-of-backtrace
-    "t"   #'sly-db-toggle-details
-    "gr"  #'sly-db-restart-frame
-    "I"   #'sly-db-invoke-restart-by-name
-    "R"   #'sly-db-return-from-frame
-    "c"   #'sly-db-continue
-    "s"   #'sly-db-step
-    "n"   #'sly-db-next
-    "o"   #'sly-db-out
-    "b"   #'sly-db-break-on-return
-    "a"   #'sly-db-abort
-    "q"   #'sly-db-quit
-    "A"   #'sly-db-break-with-system-debugger
-    "B"   #'sly-db-break-with-default-debugger
-    "P"   #'sly-db-print-condition
-    "C"   #'sly-db-inspect-condition
-    "g:"  #'sly-interactive-eval
-    "0"   #'sly-db-invoke-restart-0
-    "1"   #'sly-db-invoke-restart-1
-    "2"   #'sly-db-invoke-restart-2
-    "3"   #'sly-db-invoke-restart-3
-    "4"   #'sly-db-invoke-restart-4
-    "5"   #'sly-db-invoke-restart-5
-    "6"   #'sly-db-invoke-restart-6
-    "7"   #'sly-db-invoke-restart-7
-    "8"   #'sly-db-invoke-restart-8
-    "9"   #'sly-db-invoke-restart-9)
-  (nmap
-    :keymaps 'sly-inspector-mode-map
-    "q" #'sly-inspector-quit))
+  (setq eshell-prompt-function #'+eshell-prompt/make-prompt))
 #+end_src
-*** Lisp indent function
-Add a new lisp indent function which indents newline lists more
-appropriately.
+*** EShell additions
+Using my external library
+[[file:elisp/eshell-additions.el][eshell-additions]], I get a few new
+internal EShell commands and a command to open EShell at the current
+working directory.
 
+NOTE: I don't defer this package because it must be loaded *before*
+EShell is.  This is because any ~eshell/*~ functions need to be loaded
+before launching it.
 #+begin_src emacs-lisp
-(use-package lisp-mode
-  :defer t
+(use-package eshell-additions
+  :demand t
+  :load-path "elisp/"
   :config
-  (defun +oreo/lisp-indent-function (indent-point state)
-    (let ((normal-indent (current-column))
-          (orig-point (point)))
-      (goto-char (1+ (elt state 1)))
-      (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
-      (cond
-       ;; car of form doesn't seem to be a symbol, or is a keyword
-       ((and (elt state 2)
-             (or (not (looking-at "\\sw\\|\\s_"))
-                 (looking-at ":")))
-        (if (not (> (save-excursion (forward-line 1) (point))
-                    calculate-lisp-indent-last-sexp))
-            (progn (goto-char calculate-lisp-indent-last-sexp)
-                   (beginning-of-line)
-                   (parse-partial-sexp (point)
-                                       calculate-lisp-indent-last-sexp 0 t)))
-        ;; Indent under the list or under the first sexp on the same
-        ;; line as calculate-lisp-indent-last-sexp.  Note that first
-        ;; thing on that line has to be complete sexp since we are
-        ;; inside the innermost containing sexp.
-        (backward-prefix-chars)
-        (current-column))
-       ((and (save-excursion
-               (goto-char indent-point)
-               (skip-syntax-forward " ")
-               (not (looking-at ":")))
-             (save-excursion
-               (goto-char orig-point)
-               (looking-at ":")))
-        (save-excursion
-          (goto-char (+ 2 (elt state 1)))
-          (current-column)))
-       (t
-        (let ((function (buffer-substring (point)
-                                          (progn (forward-sexp 1) (point))))
-              method)
-          (setq method (or (function-get (intern-soft function)
-                                         'lisp-indent-function)
-                           (get (intern-soft function) 'lisp-indent-hook)))
-          (cond ((or (eq method 'defun)
-                     (and (null method)
-                          (> (length function) 3)
-                          (string-match "\\`def" function)))
-                 (lisp-indent-defform state indent-point))
-                ((integerp method)
-                 (lisp-indent-specform method state
-                                       indent-point normal-indent))
-                (method
-                 (funcall method indent-point state))))))))
-  (setq-default lisp-indent-function #'+oreo/lisp-indent-function))
+  ;; FIXME: Why do I need to double load this?  Otherwise +eshell/open doesn't
+  ;; work as intended when using universal argument.
+  (load-file (concat user-emacs-directory "elisp/eshell-additions.el"))
+  :general
+  (shell-leader
+    "t" #'+eshell/open)
+  (leader
+    "T" #'+eshell/at-cwd
+    "E" #'eshell-command))
 #+end_src
-* Applications
-Emacs is an operating system, now with a good text editor through
-[[*Evil - Vim emulation][Evil]].  Let's configure some apps for it.
-** EWW
-Emacs Web Wowser is the inbuilt text based web browser for Emacs.  It
-can render images and basic CSS styles but doesn't have a JavaScript
-engine, which makes sense as it's primarily a text interface.
+*** EShell syntax highlighting
+This package external package adds syntax highlighting to EShell
+(disabling it for remote work).  Doesn't require a lot of config
+thankfully.
 
 #+begin_src emacs-lisp
-(use-package eww
-  :defer t
-  :general
-  (app-leader
-    "w" #'eww)
-  (nmmap
-    :keymaps 'eww-mode-map
-    "w" #'evil-forward-word-begin
-    "Y" #'eww-copy-page-url))
+(use-package eshell-syntax-highlighting
+  :straight t
+  :after eshell
+  :hook (eshell-mode-hook . eshell-syntax-highlighting-mode))
 #+end_src
-** Magit
-Magit is *the* git porcelain for Emacs, which perfectly encapsulates
-the git CLI.  It's so good that some people are use Emacs just for it.
-It's difficult to describe it well without using it and it integrates
-so well with Emacs that there is very little need to use the git CLI
-ever.
+** WAIT VTerm
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no :results none
+:END:
+2025-02-17: I haven't used this in at least 1.5 years.  Why would I
+use this when I can:
++ Use [[*EShell][EShell]]
++ Use ~async-shell-command~
++ Just spawn a terminal like a normie
 
-In this case I just need to setup the bindings for it.  Also, define
-an auto insert for commit messages so that I don't need to write
-everything myself.
+There are a few times when EShell doesn't cut it, particularly in the
+domain of TUI applications like ~cfdisk~.  Emacs comes by default with
+some terminal emulators that can run a system wide shell like SH or
+ZSH (~shell~ and ~term~ for example), but they're pretty terrible.
+~vterm~ is an external package using a shared library for terminal
+emulation, and is much better than the default Emacs stuff.
 
+Since my ZSH configuration enables vim emulation, using ~evil~ on top
+of it would lead to some weird states.  Instead, use the Emacs state
+so vim emulation is completely controlled by the shell.
 #+begin_src emacs-lisp
-(use-package transient
-  :defer t
-  :straight (:host github :repo "magit/transient" :tag "v0.7.5"))
-
-(use-package magit
-  :straight (:host github :repo "magit/magit" :tag "v4.1.0")
-  :defer t
-  :display
-  ("magit:.*"
-   (display-buffer-same-window)
-   (inhibit-duplicate-buffer . t))
-  ("magit-diff:.*"
-   (display-buffer-below-selected))
-  ("magit-log:.*"
-   (display-buffer-same-window))
-  ("magit-revision:.*"
-   (display-buffer-below-selected)
-   (inhibit-duplicate-buffer . t))
+(use-package vterm
+  :straight t
   :general
-  (leader
-    "g" #'magit-dispatch)
-  (code-leader
-    "b" #'magit-blame)
-  (nmap :keymaps 'magit-status-mode-map
-    "}" #'magit-section-forward-sibling
-    "{" #'magit-section-backward-sibling)
+  (shell-leader
+    "v" #'vterm)
   :init
-  (setq vc-follow-symlinks t
-        magit-blame-echo-style 'lines
-        magit-copy-revision-abbreviated t)
-  :config
   (with-eval-after-load "evil"
-    (evil-set-initial-state 'magit-status-mode 'motion))
-  (with-eval-after-load "evil-collection"
-    (evil-collection-magit-setup)))
+    (evil-set-initial-state 'vterm-mode 'emacs)))
 #+end_src
-** Calendar
-Calendar is a simple inbuilt application that helps with date
-functionalities.  I add functionality to copy dates from the calendar
-to the kill ring and bind it to "Y".
+** (Rip)grep
+Grep is a great piece of software, a necessary tool in any Linux
+user's inventory.  Out of the box Emacs has a family of functions
+utilising grep which present results in a
+[[*Compilation][compilation]] buffer: ~grep~ searches files, ~rgrep~
+searches files in a directory using the ~find~ program and ~zgrep~
+searches archives.
 
+Ripgrep is a program that attempts to perform better than grep, and it
+does.  This is because of many optimisations, such as reading
+=.gitignore= to exclude certain files from being searched.  The
+ripgrep package provides utilities to search projects and files.  Of
+course, this requires installing the rg binary which is available in
+most distribution nowadays.
+*** Grep
 #+begin_src emacs-lisp
-(use-package calendar
+(use-package grep
   :defer t
-  :commands (+calendar/copy-date +calendar/toggle-calendar)
   :display
-  ("\\*Calendar\\*"
-   (display-buffer-at-bottom)
-   (inhibit-duplicate-buffer . t)
-   (window-height . 0.17))
+  ("^\\*grep.*"
+   (display-buffer-reuse-window display-buffer-at-bottom)
+   (window-height . 0.35)
+   (reusable-frames . t))
   :general
+  (search-leader
+    "g" #'grep-this-file
+    "c" #'grep-config-file
+    "d" #'rgrep)
   (nmmap
-    :keymaps 'calendar-mode-map
-    "Y" #'+calendar/copy-date)
-  (app-leader
-    "d" #'calendar)
-  :config
-  (defun +calendar/copy-date ()
-    "Copy date under cursor into kill ring."
-    (interactive)
-    (if (use-region-p)
-        (call-interactively #'kill-ring-save)
-      (let ((date (calendar-cursor-to-date)))
-        (when date
-          (setq date (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))
-          (kill-new (format-time-string "%Y-%m-%d" date)))))))
-#+end_src
-** Mail
-Mail is a funny thing; most people use it just for business or
-advertising and it's come out of use in terms of personal
-communication in the west for the most part (largely due to "social"
-media applications).  However, this isn't true for the open source and
-free software movement who heavily use mail for communication.
-
-Integrating mail into Emacs helps as I can send source code and
-integrate it into my workflow just a bit better.  There are a few
-ways of doing this, both in built and via package.
-*** Notmuch
-Notmuch is an application for categorising some local mail system.
-It's really fast, has tons of customisable functionality and has good
-integration with Emacs.  I use ~mbsync~ separately to pull my mail
-from the remote server.
-
-#+begin_src emacs-lisp
-(use-package notmuch
-  :straight t
-  :defer t
-  :commands (notmuch +mail/flag-thread)
-  :general
-  (app-leader "m" #'notmuch)
-  (nmap
-    :keymaps 'notmuch-search-mode-map
-    "f" #'+mail/flag-thread)
-  :init
-  (defconst +mail/local-dir (no-littering-expand-var-file-name "mail/"))
-  (setq notmuch-show-logo nil
-        notmuch-search-oldest-first nil
-        notmuch-hello-sections '(notmuch-hello-insert-saved-searches
-                                 notmuch-hello-insert-alltags
-                                 notmuch-hello-insert-recent-searches)
-        notmuch-archive-tags '("-inbox" "-unread" "+archive")
-        message-auto-save-directory +mail/local-dir
-        message-directory +mail/local-dir)
+    :keymaps 'grep-mode-map
+    "0" #'evil-beginning-of-line
+    "q" #'quit-window
+    "i" #'wgrep-change-to-wgrep-mode
+    "c" #'recompile)
+  (nmmap
+    :keymaps 'wgrep-mode-map
+    "q"  #'evil-record-macro
+    "ZZ" #'wgrep-finish-edit
+    "ZQ" #'wgrep-abort-changes)
   :config
-  (defun +mail/flag-thread (&optional unflag beg end)
-    (interactive (cons current-prefix-arg (notmuch-interactive-region)))
-    (notmuch-search-tag
-     (notmuch-tag-change-list '("-inbox" "+flagged") unflag) beg end)
-    (when (eq beg end)
-      (notmuch-search-next-thread))))
-#+end_src
-*** Smtpmail
-Setup the smtpmail package, which is used when sending mail.  Mostly
-custom configuration for integration with other parts of Emacs' mail
-system.
+  ;; Without this wgrep doesn't work properly
+  (evil-set-initial-state 'grep-mode 'normal)
 
+  (defun grep-file (query filename)
+    (grep (format "grep --color=auto -nIiHZEe \"%s\" -- %s"
+                  query filename)))
+
+  (defun grep-this-file ()
+    (interactive)
+    (let ((query (read-string "Search for: ")))
+      (if (buffer-file-name (current-buffer))
+          (grep-file query (buffer-file-name (current-buffer)))
+        (let ((temp-file (make-temp-file "temp-grep")))
+          (write-region (point-min) (point-max) temp-file)
+          (grep-file query temp-file)))))
+
+  (defun grep-config-file ()
+    (interactive)
+    (let ((query (read-string "Search for: " "^[*]+ .*")))
+      (grep-file query (concat user-emacs-directory "config.org")))))
+#+end_src
+*** rg
 #+begin_src emacs-lisp
-(use-package smtpmail
+(use-package rg
+  :straight t
   :defer t
-  :commands mail-send
+  :commands (+rg/project-todo)
+  :display
+  ("^\\*\\*ripgrep\\*\\*"
+   (display-buffer-reuse-window display-buffer-at-bottom)
+   (window-height . 0.35))
+  :general
+  (search-leader
+    "r" #'rg)
+  (:keymaps 'project-prefix-map
+   "t" #'+rg/project-todo)
+  (nmmap
+    :keymaps 'rg-mode-map
+    "c"  #'rg-recompile
+    "C"  #'rg-rerun-toggle-case
+    "]]" #'rg-next-file
+    "[[" #'rg-prev-file
+    "q"  #'quit-window
+    "i"  #'wgrep-change-to-wgrep-mode)
   :init
-  (setq-default
-   smtpmail-smtp-server "mail.aryadevchavali.com"
-   smtpmail-smtp-user "aryadev"
-   smtpmail-smtp-service 587
-   smtpmail-stream-type 'starttls
-   send-mail-function #'smtpmail-send-it
-   message-send-mail-function #'smtpmail-send-it))
+  (setq rg-group-result t
+        rg-hide-command t
+        rg-show-columns nil
+        rg-show-header t
+        rg-custom-type-aliases nil
+        rg-default-alias-fallback "all"
+        rg-buffer-name "*ripgrep*")
+  :config
+  (defun +rg/project-todo ()
+    (interactive)
+    (rg "TODO|WIP|FIXME" "*"
+        (if (project-current)
+            (project-root (project-current))
+          default-directory)))
+  (evil-set-initial-state 'rg-mode 'normal))
 #+end_src
-*** Mail signature using fortune
-Generate a mail signature using the ~fortune~ executable.  Pretty
-cool!
+** Elfeed
+Elfeed is the perfect RSS feed reader, integrated into Emacs
+perfectly.  I've got a set of feeds that I use for a large variety of
+stuff, mostly media and entertainment.  I've also bound "<leader> ar"
+to elfeed for loading the system.
 
 #+begin_src emacs-lisp
-(use-package fortune
-  :after message
+(use-package elfeed
+  :straight t
+  :general
+  (app-leader "r" #'elfeed)
+  (nmmap
+    :keymaps 'elfeed-search-mode-map
+    "gr"       #'elfeed-update
+    "s"        #'elfeed-search-live-filter
+    "<return>" #'elfeed-search-show-entry)
+  (nmmap
+    :keymaps '(elfeed-search-mode-map elfeed-show-mode-map)
+    "M-RET"    #'elfeed-dispatch)
   :init
-  (setq fortune-dir "/usr/share/fortune"
-        fortune-file "/usr/share/fortune/cookie")
+  (setq elfeed-db-directory (no-littering-expand-var-file-name "elfeed/"))
   :config
-  (defvar +mail/signature "---------------\nAryadev Chavali\n---------------\n%s")
-  (defun +mail/make-signature ()
+  (with-eval-after-load "evil-collection"
+    (evil-collection-elfeed-setup))
+
+  (defvar +elfeed/dispatch-options
+    '(("Yank URL" .
+       (lambda (url)
+         (kill-new url)
+         (message "elfeed-dispatch: Yanked %s" url)))
+      ("Open via EWW" . eww)
+      ("Play via EMPV" .
+       (lambda (url)
+         (if (member 'empv features)
+             ;; FIXME: Using internal macro
+             (empv--with-video-enabled
+              (empv-play-or-enqueue url))
+           (message "elfeed-dispatch: EMPV is not available")))))
+    "Options available on entering an elfeed post.")
+
+  (defun elfeed-dispatch ()
+    "Provide some extra options once you've clicked on an article."
     (interactive)
-    (format +mail/signature
-            (with-temp-buffer
-              (let ((fortune-buffer-name (current-buffer)))
-                (fortune-in-buffer t)
-                (if (bolp) (delete-char -1))
-                (buffer-string)))))
-  ;; (add-hook 'message-setup-hook
-  ;;           (lambda nil (setq message-signature (+mail/make-signature))))
-  )
+    (if (not (or elfeed-show-entry (eq major-mode 'elfeed-search-mode)))
+        (user-error "elfeed-dispatch: Not in an elfeed post."))
+    (let ((choice (completing-read "Choose action: " (mapcar #'car +elfeed/dispatch-options)))
+          (url (elfeed-entry-link (if elfeed-show-entry
+                                      elfeed-show-entry
+                                    (elfeed-search-selected :ignore-region)))))
+      (if-let ((option (cdr (assoc choice +elfeed/dispatch-options #'string=))))
+          (funcall option url)))))
 #+end_src
-** Dired
-Dired: Directory editor for Emacs.  An incredibly nifty piece of
-software which deeply integrates with Emacs as a whole.  I can't think
-of a better file management tool than this.
-*** Dired Core
-Here I setup dired with a few niceties
-+ Hide details by default (no extra stuff from ~ls~)
-+ Omit dot files by default (using ~dired-omit-mode~)
-+ If I have two dired windows open, moving or copying files in one
-  dired instance will automatically target the other dired window
-  (~dired-dwim~)
-+ If opening an application on a PDF file, suggest ~zathura~
-+ Examine all the subdirectories within the same buffer
-  (~+dired/insert-all-subdirectories~)
-
+*** Elfeed-org
 #+begin_src emacs-lisp
-(use-package dired
-  :defer t
-  :commands (dired find-dired)
-  :hook
-  (dired-mode-hook . auto-revert-mode)
-  (dired-mode-hook . dired-hide-details-mode)
-  (dired-mode-hook . dired-omit-mode)
+(use-package elfeed-org
+  :load-path "elisp/"
+  :after elfeed
   :init
-  (setq-default dired-listing-switches "-AFBlu --group-directories-first"
-                dired-omit-files "^\\." ; dotfiles
-                dired-omit-verbose nil
-                dired-dwim-target t
-                dired-kill-when-opening-new-dired-buffer t)
-  :general
-  (nmmap
-    :keymaps 'dired-mode-map
-    "SPC"   nil
-    "SPC ," nil
-    "M-k"                    #'dired-prev-subdir
-    "M-j"                    #'dired-next-subdir
-    "q"                      #'quit-window
-    "j"                      #'dired-next-line
-    "k"                      #'dired-previous-line
-    "("                      #'dired-hide-details-mode
-    ")"                      #'dired-omit-mode
-    "T"                      #'dired-create-empty-file
-    "H"                      #'dired-up-directory
-    "L"                      #'dired-find-file
-    "#"                      #'dired-flag-auto-save-files
-    "."                      #'dired-clean-directory
-    "~"                      #'dired-flag-backup-files
-    "A"                      #'dired-do-find-regexp
-    "C"                      #'dired-do-copy
-    "B"                      #'dired-do-byte-compile
-    "D"                      #'dired-do-delete
-    "M"                      #'dired-do-chmod
-    "O"                      #'dired-do-chown
-    "P"                      #'dired-do-print
-    "Q"                      #'dired-do-find-regexp-and-replace
-    "R"                      #'dired-do-rename
-    "S"                      #'dired-do-symlink
-    "T"                      #'dired-do-touch
-    "X"                      #'dired-do-shell-command
-    "Z"                      #'dired-do-compress
-    "c"                      #'dired-do-compress-to
-    "!"                      #'dired-do-shell-command
-    "&"                      #'dired-do-async-shell-command
-    "{"                      #'dired-prev-marked-file
-    "}"                      #'dired-next-marked-file
-    "%" nil
-    "%u"                     #'dired-upcase
-    "%l"                     #'dired-downcase
-    "%d"                     #'dired-flag-files-regexp
-    "%g"                     #'dired-mark-files-containing-regexp
-    "%m"                     #'dired-mark-files-regexp
-    "%r"                     #'dired-do-rename-regexp
-    "%C"                     #'dired-do-copy-regexp
-    "%H"                     #'dired-do-hardlink-regexp
-    "%R"                     #'dired-do-rename-regexp
-    "%S"                     #'dired-do-symlink-regexp
-    "%&"                     #'dired-flag-garbage-files
-    "*" nil
-    "**"                     #'dired-mark-executables
-    "*/"                     #'dired-mark-directories
-    "*@"                     #'dired-mark-symlinks
-    "*%"                     #'dired-mark-files-regexp
-    "*c"                     #'dired-change-marks
-    "*s"                     #'dired-mark-subdir-files
-    "*m"                     #'dired-mark
-    "*t"                     #'dired-toggle-marks
-    "*?"                     #'dired-unmark-all-files
-    "*!"                     #'dired-unmark-all-marks
-    "U"                      #'dired-unmark-all-marks
-    "a"                      #'dired-find-alternate-file
-    "d"                      #'dired-flag-file-deletion
-    "gf"                     #'browse-url-of-dired-file
-    "gr"                     #'revert-buffer
-    "i"                      #'dired-toggle-read-only
-    "J"                      #'dired-goto-file
-    "K"                      #'dired-do-kill-lines
-    "r"                      #'revert-buffer
-    "m"                      #'dired-mark
-    "t"                      #'dired-toggle-marks
-    "u"                      #'dired-unmark
-    "x"                      #'dired-do-flagged-delete
-    "gt"                     #'dired-show-file-type
-    "Y"                      #'dired-copy-filename-as-kill
-    "+"                      #'dired-create-directory
-    "RET"                    #'dired-find-file
-    "C-<return>"             #'dired-find-file-other-window
-    "o"                      #'dired-sort-toggle-or-edit
-    "[["                     #'dired-prev-dirline
-    "]]"                     #'dired-next-dirline
-    [remap next-line]        #'dired-next-line
-    [remap previous-line]    #'dired-previous-line
-    "zt"                     #'dired-hide-subdir
-    "zC"                     #'dired-hide-all
-    [remap read-only-mode]   #'dired-toggle-read-only
-    [remap toggle-read-only] #'dired-toggle-read-only
-    [remap undo]             #'dired-undo
-    [remap advertised-undo]  #'dired-undo)
-  (leader
-    "D" #'dired-jump)
-  (dir-leader
-    "f" #'find-dired
-    "d" #'dired
-    "D" #'dired-other-window
-    "i" #'image-dired
-    "b" (proc (interactive) (find-file "~/Text/Books/")))
-  (local-leader
-    :keymaps 'dired-mode-map
-    "i" #'dired-maybe-insert-subdir
-    "d" #'dired-goto-subdir
-    "I" #'+dired/insert-all-subdirectories
-    "o" #'dired-omit-mode
-    "K" #'dired-kill-subdir
-    "m" #'dired-mark-files-regexp
-    "u" #'dired-undo)
+  (thread-last "elfeed/feeds.org"
+               no-littering-expand-etc-file-name
+               (setq elfeed-org/file))
   :config
-  (add-multiple-to-list dired-guess-shell-alist-user
-                        '("\\.pdf\\'"    "zathura")
-                        '("\\.epub\\'"   "zathura")
-                        '("\\.jpg\\'"    "feh")
-                        '("\\.png\\'"    "feh")
-                        '("\\.webm\\'"   "mpv")
-                        '("\\.mp[34]\\'" "mpv")
-                        '("\\.mkv\\'"    "mpv"))
+  (elfeed-org))
+#+end_src
+** IBuffer
+IBuffer is the dired of buffers.  Nothing much else to be said.
 
-  (defun +dired/--subdirs-not-inserted ()
-    (dired-unmark-all-marks)
-    (dired-mark-directories nil)
-    (let* ((subdirs-inserted (mapcar #'car dired-subdir-alist))
-           (subdirs-available (mapcar #'(lambda (x) (concat x "/"))
-                                 (dired-get-marked-files))))
-      (dired-unmark-all-marks)
-      (cl-remove-if #'(lambda (f) (member f subdirs-inserted)) subdirs-available)))
+#+begin_src emacs-lisp
+(use-package ibuffer
+  :defer t
+  :general
+  (buffer-leader
+    "i" #'ibuffer))
+#+end_src
+** Proced
+Emacs has two systems for process management:
++ proced: a general 'top' like interface which allows general
+  management of linux processes
++ list-processes: a specific Emacs based system that lists processes
+  spawned by Emacs (similar to a top for Emacs specifically)
 
-  (defun +dired/insert-all-subdirectories (&optional arg)
-    "Insert all subdirectories recursively."
-    (interactive "P")
-    (let ((subdirs-left (+dired/--subdirs-not-inserted)))
-      (if (null arg)
-          (mapc #'dired-insert-subdir subdirs-left)
-        (while subdirs-left
-          (mapc #'dired-insert-subdir subdirs-left)
-          (setq subdirs-left (+dired/--subdirs-not-inserted)))))))
+Core Proced config, just a few bindings and evil collection setup.
+
+#+begin_src emacs-lisp
+(use-package proced
+  :defer t
+  :general
+  (app-leader
+    "p" #'proced)
+  (nmap
+    :keymaps 'proced-mode-map
+    "za" #'proced-toggle-auto-update)
+  :display
+  ("\\*Proced\\*"
+   (display-buffer-at-bottom)
+   (window-height . 0.25))
+  :init
+  (setq proced-auto-update-interval 5))
 #+end_src
-*** image-dired
-Image dired is a little cherry on top for Dired: the ability to look
-through swathes of images in a centralised fashion while still being
-able to do all the usual dired stuff as well is really cool.
+** Calculator
+~calc-mode~ is a calculator system within Emacs that provides a
+diverse array of mathematical operations.  It uses reverse polish
+notation, but there is a standard infix algebraic notation mode so
+don't be too shocked.  It can do a surprising amount of stuff, such
+as:
++ finding derivatives/integrals of generic equations
++ matrix operations
++ finding solutions for equations, such as for finite degree multi
+  variable polynomials
+
+Perhaps most powerful is ~embedded-mode~.  This allows one to perform
+computation within a non ~calc-mode~ buffer.  Surround any equation
+with dollar signs and call ~(calc-embedded)~ with your cursor on it to
+compute it.  It'll replace the equation with the result it computed.
+This is obviously incredibly useful; I don't even need to leave the
+current buffer to perform some quick mathematics in it.
 
 #+begin_src emacs-lisp
-(use-package dired
+(use-package calc
   :defer t
+  :display
+  ("*Calculator*"
+   (display-buffer-at-bottom)
+   (window-height . 0.2))
+  :general
+  (app-leader
+    "c" #'calc-dispatch)
   :init
-  (setq image-dired-external-viewer "nsxiv")
+  (setq calc-algebraic-mode t))
+#+end_src
+** Zone
+Emacs' out of the box screensaver software.
+
+#+begin_src emacs-lisp
+(use-package zone
+  :defer t
+  :commands (zone)
+  :general
+  (leader
+    "z" #'zone)
+  :init
+
+  (setq zone-programs
+        [zone-pgm-drip
+         zone-pgm-drip-fretfully]))
+#+end_src
+** (Wo)man
+Man pages are the user manuals for most software on Linux.  Of course,
+Emacs comes out of the box with a renderer for man pages and some
+searching capabilities.
+
+2023-08-17: `Man-notify-method' is the reason the `:display' record
+doesn't work here.  I think it's to do with how Man pages are rendered
+or something, but very annoying as it's a break from standards!
+
+2024-10-08: Man pages are rendered via a separate process, which is
+why this is necessary.
+
+#+begin_src emacs-lisp
+(use-package man
+  :defer t
+  :init
+  (setq Man-notify-method 'thrifty)
+  :display
+  ("\\*Man.*"
+   (display-buffer-reuse-mode-window display-buffer-same-window)
+   (mode . Man-mode))
   :general
+  (file-leader
+    "m" #'man) ;; kinda like "find man page"
   (nmmap
-    :keymaps 'image-dired-thumbnail-mode-map
-    "h"   #'image-dired-backward-image
-    "l"   #'image-dired-forward-image
-    "j"   #'image-dired-next-line
-    "k"   #'image-dired-previous-line
-    "H"   #'image-dired-display-previous
-    "L"   #'image-dired-display-next
-    "RET" #'image-dired-display-this
-    "m"   #'image-dired-mark-thumb-original-file
-    "q"   #'quit-window))
+    :keymaps 'Man-mode-map
+    "RET" #'man-follow))
 #+end_src
-*** fd-dired
-Uses fd for finding file results in a directory: ~find-dired~ ->
-~fd-dired~.
+** Info
+Info is GNU's attempt at better man pages.  Most Emacs packages have
+info pages so I'd like nice navigation options.
 
 #+begin_src emacs-lisp
-(use-package fd-dired
+(use-package info
+  :defer t
+  :general
+  (nmmap
+    :keymaps 'Info-mode-map
+    "h"   #'evil-backward-char
+    "k"   #'evil-previous-line
+    "l"   #'evil-forward-char
+    "H"   #'Info-history-back
+    "L"   #'Info-history-forward
+    "C-j" #'Info-forward-node
+    "C-k" #'Info-backward-node
+    "RET" #'Info-follow-nearest-node
+    "m"   #'Info-menu
+    "C-o" #'Info-history-back
+    "s"   #'Info-search
+    "S"   #'Info-search-case-sensitively
+    "i"   #'Info-index
+    "a"   #'info-apropos
+    "gj"  #'Info-next
+    "gk"  #'Info-prev
+    "g?"  #'Info-summary
+    "q"   #'quit-window)
+  :init
+  (with-eval-after-load "evil"
+    (evil-set-initial-state 'Info-mode 'normal)))
+#+end_src
+** Image-mode
+Image mode, for viewing images.  Supports tons of formats, easy to use
+and integrates slickly into image-dired.  Of course,
+
+#+begin_src emacs-lisp
+(use-package image-mode
+  :defer t
+  :general
+  (nmmap
+    :keymaps 'image-mode-map
+    "q" #'quit-window
+    ;; motion
+    "gg" 'image-bob
+    "G" 'image-eob
+    [remap evil-forward-char] 'image-forward-hscroll
+    [remap evil-backward-char] 'image-backward-hscroll
+    [remap evil-next-line] 'image-next-line
+    [remap evil-previous-line] 'image-previous-line
+    "0" 'image-bol
+    "^" 'image-bol
+    "$" 'image-eol
+    (kbd "C-d") 'image-scroll-up
+    (kbd "SPC") 'image-scroll-up
+    (kbd "S-SPC") 'image-scroll-down
+    (kbd "<delete>") 'image-scroll-down
+    ;; animation
+    (kbd "RET") 'image-toggle-animation
+    "F" 'image-goto-frame
+    "," 'image-previous-frame ; mplayer/mpv style
+    "." 'image-next-frame ; mplayer/mpv style
+    ";" 'image-next-frame ; Evil style
+    "{" 'image-decrease-speed ; mplayer/mpv style
+    "}" 'image-increase-speed ; mplayer/mpv style
+
+    "H" 'image-transform-fit-to-height
+    "W" 'image-transform-fit-to-width
+
+    "+" 'image-increase-size
+    "=" 'image-increase-size
+    "-" 'image-decrease-size
+
+    "[[" 'image-previous-file
+    "]]" 'image-next-file
+    "gk" 'image-previous-file
+    "gj" 'image-next-file
+    (kbd "C-k") 'image-previous-file
+    (kbd "C-j") 'image-next-file
+
+    (kbd "C-c C-c") 'image-toggle-display
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window))
+#+end_src
+** empv
+Emacs MPV bindings, with very cool controls for queuing files for
+playing.
+#+begin_src emacs-lisp
+(use-package empv
   :straight t
-  :after dired
+  :defer t
+  :init
+  (setq empv-audio-dir (list (expand-file-name "~/Media/audio")
+                             ;; "/sshx:oldboy:/media/hdd/content/Audio"
+                             )
+        empv-video-dir (list (expand-file-name "~/Media/videos")
+                             ;; "/sshx:oldboy:/media/hdd/content/Videos"
+                             )
+        empv-playlist-dir (expand-file-name "~/Media/playlists")
+        empv-audio-file-extensions (list "mp3" "ogg" "wav" "m4a" "flac" "aac" "opus")
+        empv-video-file-extensions (list "mkv" "mp4" "avi" "mov" "webm")
+        empv-radio-channels
+        '(("SomaFM - Groove Salad"   . "http://www.somafm.com/groovesalad.pls")
+          ("SomaFM - Drone Zone"     . "http://www.somafm.com/dronezone.pls")
+          ("SomaFM - Sonic Universe" . "http://www.somafm.com/sonicuniverse.pls")
+          ("SomaFM - Metal"          . "http://www.somafm.com/metal.pls")
+          ("SomaFM - Vaporwaves"     . "http://www.somafm.com/vaporwaves.pls")
+          ("SomaFM - DEFCON"         . "http://www.somafm.com/defcon.pls")
+          ("SomaFM - The Trip"       . "http://www.somafm.com/thetrip.pls"))))
+
+(use-package empv-hydra
+  :after hydra
+  :general
+  (app-leader
+    "e" #'empv-hydra/body))
+#+end_src
+** Grand Unified Debugger (GUD)
+GUD is a system for debugging, hooking into processes and
+providing an interface to the user all in Emacs.  Here I define a
+hydra which provides a ton of the useful =gud= keybindings that exist
+in an Emacs-only map.
+#+begin_src emacs-lisp
+(use-package gud
+  :general
+  :after hydra
+  :hydra
+  (gud-hydra
+   (:hint nil) "Hydra for GUD"
+   ("<"   #'gud-up "Up"
+    :column "Stack")
+   (">"   #'gud-down "Down"
+    :column "Stack")
+   ("b"   #'gud-break "Break"
+    :column "Breakpoints")
+   ("d"   #'gud-remove "Remove"
+    :column "Breakpoints")
+   ("f"   #'gud-finish "Finish"
+    :column "Control Flow")
+   ("J"   #'gud-jump "Jump"
+    :column "Control Flow")
+   ("L"   #'gud-refresh "Refresh"
+    :column "Misc")
+   ("n"   #'gud-next "Next"
+    :column "Control Flow")
+   ("p"   #'gud-print "Print"
+    :column "Misc")
+   ("c"   #'gud-cont "Cont"
+    :column "Breakpoints")
+   ("s"   #'gud-step "Step"
+    :column "Control Flow")
+   ("t"   #'gud-tbreak "Tbreak"
+    :column "Breakpoints")
+   ("u"   #'gud-until "Until"
+    :column "Control Flow")
+   ("w"   #'gud-watch "Watch"
+    :column "Breakpoints")
+   ("TAB" #'gud-stepi "Stepi"
+    :column "Control Flow"))
   :general
-  (dir-leader
-    "g" #'fd-dired))
+  (code-leader "d" #'gud-hydra/body
+    "D" #'gud-gdb))
 #+end_src
-*** wdired
-Similar to [[*(Rip)grep][wgrep]] =wdired= provides
-the ability to use Emacs motions and editing on file names.  This
-makes stuff like mass renaming and other file management tasks way
-easier than even using the mark based system.
-
+** Jira
 #+begin_src emacs-lisp
-(use-package wdired
-  :after dired
-  :hook (wdired-mode-hook . undo-tree-mode)
+(use-package jira
+  :straight (:host github :repo "unmonoqueteclea/jira.el")
+  :init
+  (setq jira-base-url "https://reframe.atlassian.net")
   :general
+  (app-leader
+    "j" #'jira-issues)
   (nmmap
-    :keymaps 'dired-mode-map
-    "W" #'wdired-change-to-wdired-mode)
-  (nmmap
-    :keymaps 'wdired-mode-map
-    "ZZ" #'wdired-finish-edit
-    "ZQ" #'wdired-abort-changes)
-  :config
-  (eval-after-load "evil"
-    ;; 2024-09-07: Why does evil-set-initial-state returning a list of modes for
-    ;; normal state make eval-after-load evaluate as if it were an actual
-    ;; expression?
-    (progn (evil-set-initial-state 'wdired-mode 'normal)
-           nil)))
+    :keymaps 'jira-issues-mode-map
+    "M-RET" #'jira-issues-actions-menu))
 #+end_src
-*** dired-rsync
-Rsync is a great way of transferring files around *nix machines, and I
-use dired for all my file management concerns.  So I should be able to
-rsync stuff around if I want.
+* Languages
+For a variety of (programming) languages Emacs comes with default
+modes but this configures them as well as pulls any modes Emacs
+doesn't come with.
+** Makefile
+Defines an auto-insert for Makefiles.  Assumes C but it's very easy to
+change it for C++.
 
 #+begin_src emacs-lisp
-(use-package dired-rsync
-  :straight t
-  :after dired
-  :general
-  (nmmap
-    :keymaps 'dired-mode-map
-    "M-r" #'dired-rsync))
-#+end_src
-** EShell
-*** Why EShell?
-EShell is an integrated shell environment for Emacs, written in Emacs
-Lisp.  Henceforth I will argue that it is the best shell/command
-interpreter to use in Emacs, so good that you should eschew any second
-class terminal emulators (~term~, ~shell~, etc).
-
-EShell is unlike the other alternatives in Emacs as it's a /shell/
-first, not a terminal emulator (granted, with the ability to spoof
-some aspects of a terminal emulator).
+(use-package make-mode
+  :defer t
+  :auto-insert
+  (("[mM]akefile\\'" . "Makefile skeleton")
+   ""
+	 "CC=gcc
+OUT=main.out
+LIBS=
+ARGS=
 
-The killer benefits of EShell (which would appeal particularly to an
-Emacs user) are a direct consequence of EShell being written in Emacs
-Lisp:
-- strong integration with Emacs utilities (such as ~dired~,
-  ~find-file~, any read functions, etc)
-- very extensible, easy to write new commands which leverage Emacs
-  commands as well as external utilities
-- agnostic of platform: "eshell/cd" will call the underlying change
-  directory function for you, so commands will (usually) mean the same
-  thing regardless of platform
-  - this means as long as Emacs can run on an operating system, one
-    may run EShell
-- mixing of Lisp and shell commands, with piping!
+RELEASE=0
+GFLAGS=-Wall -Wextra -Werror -Wswitch-enum -std=c11
+DFLAGS=-ggdb -fsanitize=address -fsanitize=undefined
+RFLAGS=-O3
+ifeq ($(RELEASE), 1)
+CFLAGS=$(GFLAGS) $(RFLAGS)
+else
+CFLAGS=$(GFLAGS) $(DFLAGS)
+endif
 
-However, my favourite feature of EShell is the set of evaluators that
-run on command input.  Some of the benefits listed above come as a
-consequence of this powerful feature.
+.PHONY: all
+all: $(OUT)
 
-The main evaluator for any expression for EShell evaluates an
-expression by testing the first symbol against different namespaces.
-The namespaces are ordered such that if a symbol is not found in one,
-the next namespace is tested.  These namespaces are:
-- alias (defined in the [[file:.config/eshell/aliases][aliases
-  file]])
-- "built-in" command i.e. in the ~eshell/~ namespace of functions
-- external command
-- Lisp function
+$(OUT): main.c
+	$(CC) $(CFLAGS) $^ -o $@ $(LIBS)
 
-You can direct EShell to use these latter two namespaces: any
-expression delimited by parentheses is considered a Lisp expression,
-and any expression delimited by curly braces is considered an external
-command.  You may even pipe the results of one into another, allowing
-a deeper level of integration between Emacs Lisp and the shell!
-*** EShell basics
-Setup some niceties of any shell program and some evil-like movements
-for easy shell usage, both in and out of insert mode.
+.PHONY: run
+run: $(OUT)
+	./$^ $(ARGS)
 
-NOTE: This mode doesn't allow you to set maps the normal way; you need
-to set keybindings on eshell-mode-hook, otherwise it'll just overwrite
-them.
+.PHONY:
+clean:
+	rm -v $(OUT)
+"
+   _))
+#+end_src
+** WAIT SQL
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no :results none
+:END:
+The default SQL package provides support for connecting to common
+database types (sqlite, mysql, etc) for auto completion and query
+execution.  I don't use SQL currently but whenever I need it it's
+there.
 
 #+begin_src emacs-lisp
-(use-package eshell
+(use-package sql
   :defer t
-  :display
-  ("\\*eshell\\*"
-   (display-buffer-same-window)
-   (reusable-frames . t))
   :init
-  (defun +eshell/banner-message ()
-    (concat (shell-command-to-string "fortune") "\n"))
-
-  (setq eshell-cmpl-ignore-case t
-        eshell-cd-on-directory t
-        eshell-cd-shows-directory nil
-        eshell-highlight-prompt nil
-        eshell-banner-message '(+eshell/banner-message))
+  (setq sql-display-sqli-buffer-function nil))
+#+end_src
+** NHexl
+Hexl-mode is the inbuilt package within Emacs to edit hex and binary
+format buffers.  There are a few problems with hexl-mode though,
+including an annoying prompt on /revert-buffer/.
 
-  (defun +eshell/good-clear ()
-    (interactive)
-    (eshell/clear-scrollback)
-    (eshell-send-input))
+Thus, nhexl-mode!  It comes with a few other improvements. Check out
+the [[https://elpa.gnu.org/packages/nhexl-mode.html][page]] yourself.
 
-  (add-hook
-   'eshell-mode-hook
-   (defun +eshell/--setup-keymap nil
-     (interactive)
-     (general-def
-       :states '(normal insert visual)
-       :keymaps 'eshell-mode-map
-       "M-j" #'eshell-next-prompt
-       "M-k" #'eshell-previous-prompt
-       "C-j" #'eshell-next-matching-input-from-input
-       "C-k" #'eshell-previous-matching-input-from-input)
+#+begin_src emacs-lisp
+(use-package nhexl-mode
+  :straight t
+  :defer t
+  :mode ("\\.bin" "\\.out"))
+#+end_src
+** NASM
+#+begin_src emacs-lisp
+(use-package nasm-mode
+  :straight t
+  :defer t
+  :mode ("\\.asm" . nasm-mode))
+#+end_src
+** C/C++
+Setup for C and C++ modes, using Emacs' default package: cc-mode.
+*** cc-mode
+Tons of stuff, namely:
++ ~auto-fill-mode~ for 80 char limit
++ Some keybindings to make evil statement movement easy
++ Lots of pretty symbols
++ Indenting options and a nice (for me) code style for C
++ Auto inserts to get a C file going
 
-     (local-leader
-       :keymaps 'eshell-mode-map
-       "g" (proc (interactive)
-                 (let ((buffer (current-buffer)))
-                   (eshell/goto)
-                   (with-current-buffer buffer
-                     (eshell-send-input))))
-       "l" (proc (interactive)
-                 (eshell-return-to-prompt)
-                 (insert "ls")
-                 (eshell-send-input))
-       "c" #'+eshell/good-clear
-       "k" #'eshell-kill-process))))
+#+begin_src emacs-lisp
+(use-package cc-mode
+  :defer t
+  :hook
+  ((c-mode-hook c++-mode-hook) . auto-fill-mode)
+  :general
+  (:keymaps '(c-mode-map c++-mode-map)
+   :states '(normal motion visual)
+   "(" #'c-beginning-of-statement
+   ")" #'c-end-of-statement
+   "{" #'c-beginning-of-defun
+   "}" #'c-end-of-defun)
+  :init
+  (setq c-basic-offset 2
+        c-auto-newline nil
+        c-default-style '((other . "user")))
+  (add-hook 'c-mode-hook (proc (c-toggle-comment-style -1)))
+  (add-hook 'c++-mode-hook (proc (c-toggle-comment-style -1)))
+  (defun +cc/copyright-notice ()
+    (let* ((lines (split-string (+license/copyright-notice) "\n"))
+           (copyright-line (car lines))
+           (rest (cdr lines)))
+      (concat
+       "* "
+       copyright-line
+       "\n"
+       (mapconcat
+        #'(lambda (x)
+            (if (string= x "")
+                ""
+              (concat " * " x)))
+        rest
+        "\n"))))
+  :auto-insert
+  (("\\.c\\'" . "C skeleton")
+   ""
+   "/" (+cc/copyright-notice) "\n\n"
+   " * Created: " (format-time-string "%Y-%m-%d") "\n"
+   " * Description: " _ "\n"
+   " */\n"
+   "\n")
+  (("\\.cpp\\'" "C++ skeleton")
+   ""
+   "/" (+cc/copyright-notice) "\n\n"
+   " * Created: " (format-time-string "%Y-%m-%d") "\n"
+   " * Description: " _ "\n"
+   " */\n"
+   "\n")
+  (("\\.\\([Hh]\\|hh\\|hpp\\|hxx\\|h\\+\\+\\)\\'" . "C / C++ header")
+   (replace-regexp-in-string "[^A-Z0-9]" "_"
+                             (string-replace "+" "P"
+                                             (upcase
+                                              (file-name-nondirectory buffer-file-name))))
+   "/" (+cc/copyright-notice) "\n\n"
+   " * Created: " (format-time-string "%Y-%m-%d") "\n"
+   " * Description: " _ "\n"
+   " */\n\n"
+   "#ifndef " str n "#define " str "\n\n" "\n\n#endif")
+  :config
+  (c-add-style
+   "user"
+   '((c-basic-offset . 2)
+     (c-comment-only-line-offset . 0)
+     (c-hanging-braces-alist (brace-list-open)
+                             (brace-entry-open)
+                             (substatement-open after)
+                             (block-close . c-snug-do-while)
+                             (arglist-cont-nonempty))
+     (c-cleanup-list brace-else-brace)
+     (c-offsets-alist
+      (statement-block-intro . +)
+      (substatement-open . 0)
+      (access-label . -)
+      (inline-open  . 0)
+      (label . 0)
+      (statement-cont . +)))))
 #+end_src
-*** EShell prompt
-Here I use my external library
-[[file:elisp/eshell-prompt.el][eshell-prompt]], which provides a
-dynamic prompt for EShell.  Current features include:
-- Git repository details (with difference from remote and number of
-  modified files)
-- Current date and time
-- A coloured prompt character which changes colour based on the exit
-  code of the previous command
+*** Clang format
+clang-format is a program that formats C/C++ files.  It's highly
+configurable and quite fast.  I have a root configuration in my
+Dotfiles (check it out
+[[file:~/Dotfiles/ClangFormat/).clang-format][here]].
 
-NOTE: I don't defer this package because it doesn't use any EShell
-internals without autoloading.
+Clang format comes inbuilt with clang/LLVM, so it's quite likely to be
+on your machine.
 
 #+begin_src emacs-lisp
-(use-package eshell-prompt
-  :load-path "elisp/"
+(use-package clang-format
+  :load-path "/usr/share/clang/"
+  :defer t
+  :after cc-mode
+  :commands (+code/clang-format-region-or-buffer
+             clang-format-mode)
+  :general
+  (code-leader
+    :keymaps '(c-mode-map c++-mode-map)
+    "f" #'clang-format-buffer)
   :config
-  (setq eshell-prompt-function #'+eshell-prompt/make-prompt))
+  (define-minor-mode clang-format-mode
+    "On save formats the current buffer via clang-format."
+    :lighter nil
+    (let ((save-func (proc-int
+                      (clang-format-buffer))))
+      (if clang-format-mode
+          (add-hook 'before-save-hook save-func nil t)
+        (remove-hook 'before-save-hook save-func t))))
+  (defun +code/clang-format-region-or-buffer ()
+    (interactive)
+    (if (mark)
+        (clang-format-region (region-beginning) (region-end))
+      (clang-format-buffer))))
 #+end_src
-*** EShell additions
-Using my external library
-[[file:elisp/eshell-additions.el][eshell-additions]], I get a few new
-internal EShell commands and a command to open EShell at the current
-working directory.
+*** cc org babel
+To ensure org-babel executes language blocks of C/C++, I need to load
+it as an option in ~org-babel-load-languages~.
 
-NOTE: I don't defer this package because it must be loaded *before*
-EShell is.  This is because any ~eshell/*~ functions need to be loaded
-before launching it.
 #+begin_src emacs-lisp
-(use-package eshell-additions
-  :demand t
-  :load-path "elisp/"
-  :config
-  ;; FIXME: Why do I need to double load this?  Otherwise +eshell/open doesn't
-  ;; work as intended when using universal argument.
-  (load-file (concat user-emacs-directory "elisp/eshell-additions.el"))
-  :general
-  (shell-leader
-    "t" #'+eshell/open)
-  (leader
-    "T" #'+eshell/at-cwd
-    "E" #'eshell-command))
+(use-package org
+  :after cc-mode
+  :init
+  (org-babel-do-load-languages
+   'org-babel-load-languages
+   '((C . t))))
 #+end_src
-*** EShell syntax highlighting
-This package external package adds syntax highlighting to EShell
-(disabling it for remote work).  Doesn't require a lot of config
-thankfully.
+*** cc compile fsan
+Sanitisers are a blessing for C/C++.  An additional runtime on top of
+the executable which catches stuff like undefined behaviour or memory
+leaks make it super easy to see where and how code is failing.
+However, by default, Emacs' compilation-mode doesn't understand the
+logs =fsanitize= makes so you usually have to manually deal with it
+yourself.
+
+Compilation mode uses regular expressions to figure out whether
+something is an error and how to navigate to the file where that error
+is located.  So adding support for =-fsanitize= is as simple as making
+a regular expression which captures file names and digits
 
 #+begin_src emacs-lisp
-(use-package eshell-syntax-highlighting
-  :straight t
-  :after eshell
-  :hook (eshell-mode-hook . eshell-syntax-highlighting-mode))
+(use-package compile
+  :after cc-mode
+  :config
+  (add-to-list 'compilation-error-regexp-alist-alist
+               `(fsan ,(rx (and
+                            line-start "    #" digit " 0x" (1+ hex) " in "
+                            (1+ (or word "_")) " "
+                            (group (seq (* any) (or ".c" ".cpp" ".h" ".hpp"))) ":"
+                            (group (+ digit))))
+
+                      1 2))
+  (add-to-list 'compilation-error-regexp-alist
+               'fsan))
 #+end_src
-** WAIT VTerm
+** Markdown
+Why use Markdown when you have org-mode?  Because LSP servers
+sometimes format their documentation as markdown, which
+[[*Eglot][Eglot]] can use to provide nicer views on docs!
+#+begin_src emacs-lisp
+(use-package markdown-mode
+  :defer t
+  :straight t)
+#+end_src
+** WAIT Rust
 :PROPERTIES:
 :header-args:emacs-lisp: :tangle no :results none
 :END:
-2025-02-17: I haven't used this in at least 1.5 years.  Why would I
-use this when I can:
-+ Use [[*EShell][EShell]]
-+ Use ~async-shell-command~
-+ Just spawn a terminal like a normie
+2025-02-15: Haven't needed to use Rust at all recently - but leaving
+this here in case.
 
-There are a few times when EShell doesn't cut it, particularly in the
-domain of TUI applications like ~cfdisk~.  Emacs comes by default with
-some terminal emulators that can run a system wide shell like SH or
-ZSH (~shell~ and ~term~ for example), but they're pretty terrible.
-~vterm~ is an external package using a shared library for terminal
-emulation, and is much better than the default Emacs stuff.
+Rust is the systems programming language that also does web stuff and
+CLI programs and basically tries to be a jack of all trades.  It's got
+some interesting stuff but most importantly it's very new, so everyone
+must learn it, right?
 
-Since my ZSH configuration enables vim emulation, using ~evil~ on top
-of it would lead to some weird states.  Instead, use the Emacs state
-so vim emulation is completely controlled by the shell.
 #+begin_src emacs-lisp
-(use-package vterm
+(use-package rust-mode
   :straight t
+  :defer t
   :general
-  (shell-leader
-    "v" #'vterm)
+  (code-leader
+    :keymaps 'rust-mode-map
+    "f" #'rust-format-buffer)
+  (local-leader
+    :keymaps 'rust-mode-map
+    "c" #'rust-run-clippy)
   :init
-  (with-eval-after-load "evil"
-    (evil-set-initial-state 'vterm-mode 'emacs)))
+  (setq rust-format-on-save t)
+  (with-eval-after-load "eglot"
+    (add-to-list 'eglot-server-programs '(rust-mode "rust-analyzer"))))
 #+end_src
-** (Rip)grep
-Grep is a great piece of software, a necessary tool in any Linux
-user's inventory.  Out of the box Emacs has a family of functions
-utilising grep which present results in a
-[[*Compilation][compilation]] buffer: ~grep~ searches files, ~rgrep~
-searches files in a directory using the ~find~ program and ~zgrep~
-searches archives.
+** WAIT Racket
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no :results none
+:END:
+A scheme with lots of stuff inside it.  Using it for a language design
+book so it's useful to have some Emacs binds for it.
 
-Ripgrep is a program that attempts to perform better than grep, and it
-does.  This is because of many optimisations, such as reading
-=.gitignore= to exclude certain files from being searched.  The
-ripgrep package provides utilities to search projects and files.  Of
-course, this requires installing the rg binary which is available in
-most distribution nowadays.
-*** Grep
 #+begin_src emacs-lisp
-(use-package grep
+(use-package racket-mode
+  :straight t
   :defer t
+  :hook (racket-mode-hook . racket-xp-mode)
   :display
-  ("^\\*grep.*"
-   (display-buffer-reuse-window display-buffer-at-bottom)
-   (window-height . 0.35)
-   (reusable-frames . t))
+  ("\\*Racket REPL*"
+   (display-buffer-at-bottom)
+   (window-height . 0.3))
+  :init
+  (setq racket-documentation-search-location 'local)
   :general
-  (search-leader
-    "g" #'grep-this-file
-    "c" #'grep-config-file
-    "d" #'rgrep)
-  (nmmap
-    :keymaps 'grep-mode-map
-    "0" #'evil-beginning-of-line
-    "q" #'quit-window
-    "i" #'wgrep-change-to-wgrep-mode
-    "c" #'recompile)
-  (nmmap
-    :keymaps 'wgrep-mode-map
-    "q"  #'evil-record-macro
-    "ZZ" #'wgrep-finish-edit
-    "ZQ" #'wgrep-abort-changes)
-  :config
-  ;; Without this wgrep doesn't work properly
-  (evil-set-initial-state 'grep-mode 'normal)
+  (nmap
+    :keymaps 'racket-describe-mode-map
+    "q" #'quit-window)
+  (nmap
+    :keymaps 'racket-mode-map
+    "gr" #'racket-eval-last-sexp)
+  (local-leader
+    :keymaps '(racket-mode-map racket-repl-mode-map)
+    "d" #'racket-repl-describe)
+  (local-leader
+    :keymaps 'racket-mode-map
+    "r" #'racket-run
+    "i" #'racket-repl
+    "e" #'racket-send-definition
+    "sr" #'racket-send-region
+    "sd" #'racket-send-definition))
+#+end_src
+** WAIT Haskell
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no :results none
+:END:
+2025-02-15: Haskell is a fun language so I'll leave this configuration
+for now.
 
-  (defun grep-file (query filename)
-    (grep (format "grep --color=auto -nIiHZEe \"%s\" -- %s"
-                  query filename)))
+Haskell is a static lazy functional programming language (what a
+mouthful).  It's quite a beautiful language and really learning it
+will change the way you think about programming.  However, my
+preferred functional language is still unfortunately Lisp so no extra
+brownie points there.
 
-  (defun grep-this-file ()
-    (interactive)
-    (let ((query (read-string "Search for: ")))
-      (if (buffer-file-name (current-buffer))
-          (grep-file query (buffer-file-name (current-buffer)))
-        (let ((temp-file (make-temp-file "temp-grep")))
-          (write-region (point-min) (point-max) temp-file)
-          (grep-file query temp-file)))))
+Here I configure the REPL for Haskell via the
+~haskell-interactive-mode~.  I also load my custom package
+[[file:elisp/haskell-multiedit.el][haskell-multiedit]] which allows a
+user to create temporary ~haskell-mode~ buffers that, upon completion,
+will run in the REPL.  Even easier than making your own buffer.
 
-  (defun grep-config-file ()
-    (interactive)
-    (let ((query (read-string "Search for: " "^[*]+ .*")))
-      (grep-file query (concat user-emacs-directory "config.org")))))
-#+end_src
-*** rg
 #+begin_src emacs-lisp
-(use-package rg
+(use-package haskell-mode
   :straight t
   :defer t
-  :commands (+rg/project-todo)
+  :hook
+  (haskell-mode-hook . haskell-indentation-mode)
+  (haskell-mode-hook . interactive-haskell-mode)
   :display
-  ("^\\*\\*ripgrep\\*\\*"
-   (display-buffer-reuse-window display-buffer-at-bottom)
-   (window-height . 0.35))
+  ("\\*haskell.**\\*"
+   (display-buffer-at-bottom)
+   (window-height . 0.3))
   :general
-  (search-leader
-    "r" #'rg)
-  (:keymaps 'project-prefix-map
-   "t" #'+rg/project-todo)
+  (shell-leader
+    "h" #'haskell-interactive-bring)
+  (local-leader
+    :keymaps 'haskell-mode-map
+    "c" #'haskell-compile
+    "t" #'haskell-process-do-type)
   (nmmap
-    :keymaps 'rg-mode-map
-    "c"  #'rg-recompile
-    "C"  #'rg-rerun-toggle-case
-    "]]" #'rg-next-file
-    "[[" #'rg-prev-file
-    "q"  #'quit-window
-    "i"  #'wgrep-change-to-wgrep-mode)
+    :keymaps 'haskell-mode-map
+    "C-c C-c" #'haskell-process-load-file)
+  (local-leader
+    :keymaps 'haskell-interactive-mode-map
+    "c" #'haskell-interactive-mode-clear)
+  (imap
+    :keymaps 'haskell-interactive-mode-map
+    "M-k" #'haskell-interactive-mode-history-previous
+    "M-j" #'haskell-interactive-mode-history-next)
   :init
-  (setq rg-group-result t
-        rg-hide-command t
-        rg-show-columns nil
-        rg-show-header t
-        rg-custom-type-aliases nil
-        rg-default-alias-fallback "all"
-        rg-buffer-name "*ripgrep*")
+  (setq haskell-interactive-prompt "[λ] "
+        haskell-interactive-prompt-cont "{λ} "
+        haskell-interactive-popup-errors nil
+        haskell-stylish-on-save t
+        haskell-process-type 'auto)
   :config
-  (defun +rg/project-todo ()
-    (interactive)
-    (rg "TODO" "*"
-        (if (project-current)
-            (project-root (project-current))
-          default-directory)))
-  (evil-set-initial-state 'rg-mode 'normal))
+  (load (concat user-emacs-directory "elisp/haskell-multiedit.el")))
 #+end_src
-** Elfeed
-Elfeed is the perfect RSS feed reader, integrated into Emacs
-perfectly.  I've got a set of feeds that I use for a large variety of
-stuff, mostly media and entertainment.  I've also bound "<leader> ar"
-to elfeed for loading the system.
+** Python
+Works well for python.  If you have ~pyls~ it should be on your path, so
+just run eglot if you need.  But an LSP server is not necessary for a
+lot of my time in python.  Here I also setup org-babel for python
+source code blocks.
 
 #+begin_src emacs-lisp
-(use-package elfeed
-  :straight t
+(use-package python
+  :defer t
   :general
-  (app-leader "r" #'elfeed)
-  (nmmap
-    :keymaps 'elfeed-search-mode-map
-    "gr"       #'elfeed-update
-    "s"        #'elfeed-search-live-filter
-    "<return>" #'elfeed-search-show-entry)
   (nmmap
-    :keymaps 'elfeed-show-mode-map
-    "M-RET"    #'+elfeed/dispatch)
+    :keymaps 'python-mode-map
+    "C-M-x" #'python-shell-send-defun)
+  (local-leader
+    :keymaps 'python-mode-map
+    "c" #'python-check)
+  (local-leader
+    :keymaps 'python-mode-map
+    :infix "e"
+    "e" #'python-shell-send-statement
+    "r" #'python-shell-send-region
+    "f" #'python-shell-send-buffer)
+  :pretty
+  (python-mode-hook
+   ("None"   . "Ø")
+   ("list"   . "ℓ")
+   ("List"   . "ℓ")
+   ("str"    . "𝕊")
+   ("!"      . "¬")
+   ("for"    . "∀")
+   ("print"  . "φ")
+   ("lambda" . "λ")
+   ("reduce" . "↓")
+   ("map"    . "→")
+   ("return" . "≡")
+   ("yield"  . "≈"))
   :init
-  (setq elfeed-db-directory (no-littering-expand-var-file-name "elfeed/"))
+  (setq python-indent-offset 4)
   :config
-  (with-eval-after-load "evil-collection"
-    (evil-collection-elfeed-setup))
+  (with-eval-after-load "org-mode"
+    (setf (alist-get 'python org-babel-load-languages) t)))
+#+end_src
+*** Python shell
+Setup for python shell, including a toggle option
 
-  (defvar +elfeed/dispatch-options
-    '(("Yank URL" .
-       (lambda (url)
-         (kill-new url)
-         (message "elfeed-dispatch: Yanked %s" url)))
-      ("Open via EWW" . eww)
-      ("Play via EMPV" .
-       (lambda (url)
-         (if (member 'empv features)
-             ;; FIXME: Using internal macro
-             (empv--with-video-enabled
-              (empv-play-or-enqueue url))
-           (message "elfeed-dispatch: EMPV is not available")))))
-    "Options available on entering an elfeed post.")
+#+begin_src emacs-lisp
+(use-package python
+  :defer t
+  :commands +python/toggle-repl
+  :general
+  (shell-leader
+    "p" #'run-python)
+  :hook
+  (inferior-python-mode-hook . company-mode)
+  :display
+  ("\\*Python\\*"
+   (display-buffer-at-bottom)
+   (window-height . 0.3)))
+#+end_src
+** YAML
+YAML is a data language which is useful for config files.
 
-  (defun +elfeed/dispatch ()
-    "Provide some extra options once you've clicked on an article."
-    (interactive)
-    (if (null elfeed-show-entry)
-        (user-error "elfeed-dispatch: Not in an elfeed post."))
-    (let ((choice (completing-read "Choose action: " (mapcar #'car +elfeed/dispatch-options)))
-          (url (elfeed-entry-link elfeed-show-entry)))
-      (if-let ((option (cdr (assoc choice +elfeed/dispatch-options #'string=))))
-          (funcall option url)))))
+#+begin_src emacs-lisp
+(use-package yaml-mode
+  :defer t
+  :straight t)
 #+end_src
-*** Elfeed-org
+** HTML/CSS/JS
+Firstly, web mode for consistent colouring of syntax.
+
 #+begin_src emacs-lisp
-(use-package elfeed-org
-  :load-path "elisp/"
-  :after elfeed
-  :init
-  (thread-last "elfeed/feeds.org"
-               no-littering-expand-etc-file-name
-               (setq elfeed-org/file))
-  :config
-  (elfeed-org))
+(use-package web-mode
+  :straight t
+  :defer t
+  :mode ("\\.html" . web-mode)
+  :mode ("\\.css"  . web-mode)
+  :custom
+  ((web-mode-code-indent-offset 2)
+   (web-mode-markup-indent-offset 2)
+   (web-mode-css-indent-offset 2)))
 #+end_src
-** IBuffer
-IBuffer is the dired of buffers.  Nothing much else to be said.
+*** Emmet
+Emmet for super speed code writing.
 
 #+begin_src emacs-lisp
-(use-package ibuffer
+(use-package emmet-mode
+  :straight t
   :defer t
+  :hook (web-mode-hook . emmet-mode)
   :general
-  (buffer-leader
-    "i" #'ibuffer))
+  (imap
+    :keymaps 'emmet-mode-keymap
+    "TAB" #'emmet-expand-line
+    "M-j" #'emmet-next-edit-point
+    "M-k" #'emmet-prev-edit-point))
 #+end_src
-** Proced
-Emacs has two systems for process management:
-+ proced: a general 'top' like interface which allows general
-  management of linux processes
-+ list-processes: a specific Emacs based system that lists processes
-  spawned by Emacs (similar to a top for Emacs specifically)
-
-Core Proced config, just a few bindings and evil collection setup.
+*** HTML Auto insert
+An auto-insert for HTML buffers, which just adds some nice stuff.
 
 #+begin_src emacs-lisp
-(use-package proced
+(use-package web-mode
   :defer t
-  :general
-  (app-leader
-    "p" #'proced)
-  (nmap
-    :keymaps 'proced-mode-map
-    "za" #'proced-toggle-auto-update)
-  :display
-  ("\\*Proced\\*"
-   (display-buffer-at-bottom)
-   (window-height . 0.25))
+  :auto-insert
+  (("\\.html\\'" . "HTML Skeleton")
+   ""
+   "<!doctype html>
+<html lang=''>
+  <head>
+    <meta charset='utf-8'>
+    <title>"(read-string "Enter title: ") | """</title>
+    <meta name='description' content='" (read-string "Enter description: ") | "" "'>
+    <meta name='author' content='"user-full-name"'/>
+    <meta name='viewport' content='width=device-width, initial-scale=1'>
+
+    <link rel='apple-touch-icon' href='/apple-touch-icon.png'>
+    <link rel='shortcut icon' href='/favicon.ico'/>
+  </head>
+  <body>
+"
+   _
+   "     </body>
+</html>"))
+#+end_src
+*** Javascript Mode
+A better mode for JavaScript that also has automatic integration with
+eglot.
+
+#+begin_src emacs-lisp
+(use-package js
+  :defer t
+  :mode ("\\.js" . js-mode)
+  :hook (js-mode-hook . auto-fill-mode)
   :init
-  (setq proced-auto-update-interval 5))
+  (setq js-indent-level 2))
 #+end_src
-** Calculator
-~calc-mode~ is a calculator system within Emacs that provides a
-diverse array of mathematical operations.  It uses reverse polish
-notation, but there is a standard infix algebraic notation mode so
-don't be too shocked.  It can do a surprising amount of stuff, such
-as:
-+ finding derivatives/integrals of generic equations
-+ matrix operations
-+ finding solutions for equations, such as for finite degree multi
-  variable polynomials
-
-Perhaps most powerful is ~embedded-mode~.  This allows one to perform
-computation within a non ~calc-mode~ buffer.  Surround any equation
-with dollar signs and call ~(calc-embedded)~ with your cursor on it to
-compute it.  It'll replace the equation with the result it computed.
-This is obviously incredibly useful; I don't even need to leave the
-current buffer to perform some quick mathematics in it.
+*** Typescript
+A language that adds a build step to JavaScript projects for "static"
+typing.  It's nice because it adds good auto completion.
 
 #+begin_src emacs-lisp
-(use-package calc
+(use-package typescript-mode
+  :straight t
   :defer t
-  :display
-  ("*Calculator*"
-   (display-buffer-at-bottom)
-   (window-height . 0.2))
-  :general
-  (app-leader
-    "c" #'calc-dispatch)
   :init
-  (setq calc-algebraic-mode t))
+  (setq typescript-indent-level 2))
 #+end_src
-** Zone
-Emacs' out of the box screensaver software.
+** Scheme
+Another Lisp but simpler than the rest.  A beauty of engineering and
+fun to write programs in.  Here I setup ~geiser~, which is the
+premiere way to interact with scheme REPLs.
 
 #+begin_src emacs-lisp
-(use-package zone
+(use-package geiser
   :defer t
-  :commands (zone)
+  :straight t
+  :display
+  ("\\*Geiser.*"
+   (display-buffer-reuse-mode-window display-buffer-at-bottom)
+   (window-height . 0.3))
   :general
-  (leader
-    "z" #'zone)
+  (shell-leader
+    "S" #'geiser)
+  (local-leader
+    :keymaps 'scheme-mode-map
+    "t"  #'geiser
+    "m"  #'geiser-doc-look-up-manual
+    "d" #'geiser-doc-symbol-at-point)
+  (local-leader
+    :keymaps 'scheme-mode-map
+    :infix "e"
+    "e" #'geiser-eval-last-sexp
+    "b" #'geiser-eval-buffer
+    "d" #'geiser-eval-definition
+    "r" #'geiser-eval-region)
   :init
+  (with-eval-after-load "evil"
+    (evil-set-initial-state 'geiser-debug-mode-map 'emacs)))
 
-  (setq zone-programs
-        [zone-pgm-drip
-         zone-pgm-drip-fretfully]))
+(use-package geiser-guile
+  :defer t
+  :straight t)
+#+end_src
+** WAIT Ocaml
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no :results none
+:END:
+*** Ocaml Setup
+Firstly, install ~opam~ and ~ocaml~.  Then run the following script:
+#+begin_src sh
+opam install tuareg ocamlformat odoc utop merlin user-setup;
+opam user-setup install;
+mv ~/.emacs.d/opam-user-setup.el ~/.config/emacs/elisp;
+rm -rf ~/.emacs.d ~/.emacs;
 #+end_src
-** (Wo)man
-Man pages are the user manuals for most software on Linux.  Of course,
-Emacs comes out of the box with a renderer for man pages and some
-searching capabilities.
-
-2023-08-17: `Man-notify-method' is the reason the `:display' record
-doesn't work here.  I think it's to do with how Man pages are rendered
-or something, but very annoying as it's a break from standards!
-
-2024-10-08: Man pages are rendered via a separate process, which is
-why this is necessary.
 
+This sets up the necessary packages (particularly Emacs Lisp) and some
+configuration that ensures Emacs is consistent with the user
+installation.  Notice the moving of =opam-user-setup.el= into
+=~/.config/emacs/elisp=, which we'll use to setup the ocaml
+experience.
+*** Ocaml Configuration
+Here I load the =opam-user-setup= package setup earlier, with some
+neat tips from the default =~/.emacs= generated by ~opam user-setup
+install~.
 #+begin_src emacs-lisp
-(use-package man
+(use-package opam-user-setup
   :defer t
-  :init
-  (setq Man-notify-method 'thrifty)
+  :load-path "elisp/"
+  :mode ("\\.ml" . tuareg-mode)
+  :hook (tuareg-mode-hook . whitespace-mode)
   :display
-  ("\\*Man.*"
-   (display-buffer-reuse-mode-window display-buffer-same-window)
-   (mode . Man-mode))
+  ("\\*utop\\*"
+   (display-buffer-at-bottom)
+   (window-height . 0.3))
   :general
-  (file-leader
-    "m" #'man) ;; kinda like "find man page"
-  (nmmap
-    :keymaps 'Man-mode-map
-    "RET" #'man-follow))
-#+end_src
-** Info
-Info is GNU's attempt at better man pages.  Most Emacs packages have
-info pages so I'd like nice navigation options.
+  (code-leader
+    :keymaps 'tuareg-mode-map
+    "f" #'+ocaml/format-buffer)
+  :config
+  (defun +ocaml/format-buffer ()
+    (interactive)
+    (when (eq major-mode 'tuareg-mode)
+      (let ((name (buffer-file-name (current-buffer)))
+            (format-str "ocamlformat -i --enable-outside-detected-project %s"))
+        (save-buffer)
+        (set-process-sentinel (start-process-shell-command "ocamlformat" "*ocamlformat*"
+                                                           (format format-str name))
+                              (lambda (p event)
+                                (when (string= event "finished\n")
+                                  (revert-buffer nil t)
+                                  (message "[ocamlformat] Finished.")))))))
+  (add-to-list 'compilation-error-regexp-alist-alist
+               `(ocaml
+                 "[Ff]ile \\(\"\\(.*?\\)\", line \\(-?[0-9]+\\)\\(, characters \\(-?[0-9]+\\)-\\([0-9]+\\)\\)?\\)\\(:\n\\(\\(Warning .*?\\)\\|\\(Error\\)\\):\\)?"
+                 2 3 (5 . 6) (9 . 11) 1 (8 compilation-message-face)))
+  (add-to-list 'compilation-error-regexp-alist
+               'ocaml)
+  :general
+  (local-leader
+    :keymaps 'tuareg-mode-map
+    "u" #'utop)
+  (local-leader
+    :keymaps 'tuareg-mode-map
+    :infix "e"
+    "r" #'utop-eval-region
+    "e" #'utop-eval-phrase
+    "b" #'utop-eval-buffer))
 
+(use-package merlin-eldoc
+  :straight t
+  :after opam-user-setup
+  :hook
+  (tuareg-mode-hook . merlin-eldoc-setup)
+  :init
+  (setq merlin-eldoc-occurrences nil))
+#+end_src
+** Lisp
+Emacs is the greatest Lisp editor around, there are no two ways about
+it.  Here I setup the configuration for Emacs Lisp and Common Lisp.
+*** Lisp configuration
+All the general stuff I do for any other language: pretty symbols and
+key bindings.
 #+begin_src emacs-lisp
-(use-package info
-  :defer t
+(use-package lisp-mode
+  :pretty
+  (lisp-mode-hook
+   ("lambda" . "λ")
+   ("nil"    . "Ø")
+   ("<="     . "≤")
+   (">="     . "≥")
+   ("defun"  . "ƒ")
+   ("mapcar" . "→")
+   ("reduce" . "↓")
+   ("some"   . "∃")
+   ("every"  . "∀")
+   ("LAMBDA" . "λ")
+   ("NIL"    . "Ø")
+   ("<="     . "≤")
+   (">="     . "≥")
+   ("DEFUN"  . "ƒ")
+   ("MAPCAR" . "→")
+   ("REDUCE" . "↓")
+   ("SOME"   . "∃")
+   ("EVERY"  . "∀"))
+  (emacs-lisp-mode-hook
+   ("lambda" . "λ")
+   ("nil"    . "Ø")
+   ("defun"  . "ƒ")
+   ("mapcar" . "→")
+   ("LAMBDA" . "λ")
+   ("NIL"    . "Ø")
+   ("DEFUN"  . "ƒ")
+   ("MAPCAR" . "→"))
   :general
-  (nmmap
-    :keymaps 'Info-mode-map
-    "h"   #'evil-backward-char
-    "k"   #'evil-previous-line
-    "l"   #'evil-forward-char
-    "H"   #'Info-history-back
-    "L"   #'Info-history-forward
-    "C-j" #'Info-forward-node
-    "C-k" #'Info-backward-node
-    "RET" #'Info-follow-nearest-node
-    "m"   #'Info-menu
-    "C-o" #'Info-history-back
-    "s"   #'Info-search
-    "S"   #'Info-search-case-sensitively
-    "i"   #'Info-index
-    "a"   #'info-apropos
-    "gj"  #'Info-next
-    "gk"  #'Info-prev
-    "g?"  #'Info-summary
-    "q"   #'quit-window)
+  (:states '(normal motion insert visual)
+   :keymaps 'lisp-mode-shared-map
+   "C-j"   #'sp-forward-slurp-sexp
+   "C-k"   #'sp-forward-barf-sexp
+   "C-S-j" #'sp-backward-barf-sexp
+   "C-S-k" #'sp-backward-slurp-sexp
+   "M-h"   #'sp-previous-sexp
+   "M-j"   #'sp-down-sexp
+   "M-k"   #'sp-backward-up-sexp
+   "M-l"   #'sp-next-sexp
+   "M-S-j" #'sp-up-sexp
+   "M-S-k" #'sp-backward-down-sexp))
+#+end_src
+*** Common Lisp auto insert
+Like C/C++'s auto insert, but with Common Lisp comments.
+#+begin_src emacs-lisp
+(use-package lisp-mode
   :init
-  (with-eval-after-load "evil"
-    (evil-set-initial-state 'Info-mode 'normal)))
+  (defun +lisp/copyright-notice ()
+    (let* ((lines (split-string (+license/copyright-notice) "\n"))
+           (copyright-line (car lines))
+           (rest (cdr lines)))
+      (-->
+       (lambda (x)
+         (if (string= x "")
+             ""
+           (concat ";; " x)))
+       (mapconcat it rest "\n")
+       (format ";; %s\n%s\n"
+               copyright-line
+               it))))
+  :auto-insert
+  (("\\.lisp\\'" . "Common Lisp Skeleton")
+   ""
+   ";;; " (file-name-nondirectory (buffer-file-name)) " - "
+   (format-time-string "%Y-%m-%d") "\n\n"
+   (+lisp/copyright-notice) "\n"
+   ";;; Commentary:\n\n;;\n\n;;; Code:\n"))
 #+end_src
-** Image-mode
-Image mode, for viewing images.  Supports tons of formats, easy to use
-and integrates slickly into image-dired.  Of course,
+*** Sly
+While Emacs does an okay job for editing Common Lisp it's not amazing
+for actually developing large scale projects.  Considering how good an
+environment Emacs is for Emacs Lisp, and how similar the two languages
+are, we shouldn't need an LSP.
+
+Enter /SLY/.  Sly is a fork of /SLIME/ and it provides the essential
+components to elevate Emacs' ability to develop Common Lisp.  I feel
+calling the ability Sly gives you "IDE-like" a slight against it - no
+IDE I have used is as capable in aiding development as Emacs + Sly.
 
 #+begin_src emacs-lisp
-(use-package image-mode
-  :defer t
-  :general
-  (nmmap
-    :keymaps 'image-mode-map
-    "+" #'image-increase-size
-    "-" #'image-decrease-size
-    "a" #'image-toggle-animation
-    "p+" #'image-increase-speed
-    "p-" #'image-increase-speed
-    "h" #'image-backward-hscroll
-    "j" #'image-next-line
-    "k" #'image-previous-line
-    "l" #'image-forward-hscroll))
-#+end_src
-** empv
-Emacs MPV bindings, with very cool controls for queuing files for
-playing.
-#+begin_src emacs-lisp
-(use-package empv
-  :straight (:host github :repo "oreodave/empv.el")
+(use-package sly
   :defer t
+  :straight t
   :init
-  (setq empv-audio-dir (list (expand-file-name "~/Media/audio")
-                             "/sshx:oldboy:/media/hdd/content/Audio")
-        empv-video-dir (list (expand-file-name "~/Media/videos")
-                             "/sshx:oldboy:/media/hdd/content/Videos")
-        empv-playlist-dir (expand-file-name "~/Media/playlists")
-        empv-audio-file-extensions (list "mp3" "ogg" "wav" "m4a" "flac" "aac" "opus")
-        empv-video-file-extensions (list "mkv" "mp4" "avi" "mov" "webm")
-        empv-radio-channels
-        '(("SomaFM - Groove Salad"   . "http://www.somafm.com/groovesalad.pls")
-          ("SomaFM - Drone Zone"     . "http://www.somafm.com/dronezone.pls")
-          ("SomaFM - Sonic Universe" . "http://www.somafm.com/sonicuniverse.pls")
-          ("SomaFM - Metal"          . "http://www.somafm.com/metal.pls")
-          ("SomaFM - Vaporwaves"     . "http://www.somafm.com/vaporwaves.pls")
-          ("SomaFM - DEFCON"         . "http://www.somafm.com/defcon.pls")
-          ("SomaFM - The Trip"       . "http://www.somafm.com/thetrip.pls"))))
-
-(use-package empv-hydra
-  :after hydra
+  (setq inferior-lisp-program "sbcl"
+        sly-lisp-loop-body-forms-indentation 0)
+  :display
+  ("\\*sly-db"
+   (display-buffer-at-bottom)
+   (window-height . 0.25))
+  ("\\*sly-inspector"
+   (display-buffer-at-bottom)
+   (window-height . 0.25))
+  ("\\*sly-mrepl"
+   (display-buffer-in-side-window)
+   (window-width . 0.35)
+   (side . right))
+  :config
+  (evil-set-initial-state 'sly-db-mode 'normal)
+  (with-eval-after-load "org"
+    (setq-default org-babel-lisp-eval-fn #'sly-eval))
+  (with-eval-after-load "company"
+    (add-hook 'sly-mrepl-hook #'company-mode))
   :general
-  (app-leader
-    "e" #'empv-hydra/body))
+  (shell-leader
+    "s" #'sly)
+  (nmap
+    :keymaps 'lisp-mode-map
+    "gr"  #'sly-eval-buffer
+    "gd"  #'sly-edit-definition
+    "gR"  #'sly-who-calls)
+  (local-leader
+    :keymaps 'lisp-mode-map
+    "a" #'sly-apropos
+    "d" #'sly-describe-symbol
+    "s" #'sly-mrepl-sync
+    "l" #'sly-load-file
+    "c" #'sly-compile-defun
+    "D" #'sly-documentation-lookup
+    "C" #'sly-compile-file)
+  (local-leader
+    :keymaps 'lisp-mode-map
+    :infix "e"
+    "b" #'sly-eval-buffer
+    "e" #'sly-eval-last-expression
+    "f" #'sly-eval-defun
+    "r" #'sly-eval-region)
+  (nmap
+    :keymaps 'sly-mrepl-mode-map
+    "M-j" #'sly-mrepl-next-input-or-button
+    "M-k" #'sly-mrepl-previous-input-or-button
+    "C-j" #'sly-mrepl-next-prompt
+    "C-k" #'sly-mrepl-previous-prompt)
+  (local-leader
+    :keymaps 'sly-mrepl-mode-map
+    "c" #'sly-mrepl-clear-repl
+    "s" #'sly-mrepl-shortcut
+    "l" #'sly-load-file)
+  (nmap
+    :keymaps 'sly-db-mode-map
+    "C-i" #'sly-db-cycle
+    "g?"  #'describe-mode
+    "S"   #'sly-db-show-frame-source
+    "e"   #'sly-db-eval-in-frame
+    "d"   #'sly-db-pprint-eval-in-frame
+    "D"   #'sly-db-disassemble
+    "i"   #'sly-db-inspect-in-frame
+    "gj"  #'sly-db-down
+    "gk"  #'sly-db-up
+    "C-j" #'sly-db-down
+    "C-k" #'sly-db-up
+    "]]"  #'sly-db-details-down
+    "[["  #'sly-db-details-up
+    "M-j" #'sly-db-details-down
+    "M-k" #'sly-db-details-up
+    "G"   #'sly-db-end-of-backtrace
+    "t"   #'sly-db-toggle-details
+    "gr"  #'sly-db-restart-frame
+    "I"   #'sly-db-invoke-restart-by-name
+    "R"   #'sly-db-return-from-frame
+    "c"   #'sly-db-continue
+    "s"   #'sly-db-step
+    "n"   #'sly-db-next
+    "o"   #'sly-db-out
+    "b"   #'sly-db-break-on-return
+    "a"   #'sly-db-abort
+    "q"   #'sly-db-quit
+    "A"   #'sly-db-break-with-system-debugger
+    "B"   #'sly-db-break-with-default-debugger
+    "P"   #'sly-db-print-condition
+    "C"   #'sly-db-inspect-condition
+    "g:"  #'sly-interactive-eval
+    "0"   #'sly-db-invoke-restart-0
+    "1"   #'sly-db-invoke-restart-1
+    "2"   #'sly-db-invoke-restart-2
+    "3"   #'sly-db-invoke-restart-3
+    "4"   #'sly-db-invoke-restart-4
+    "5"   #'sly-db-invoke-restart-5
+    "6"   #'sly-db-invoke-restart-6
+    "7"   #'sly-db-invoke-restart-7
+    "8"   #'sly-db-invoke-restart-8
+    "9"   #'sly-db-invoke-restart-9)
+  (nmap
+    :keymaps 'sly-inspector-mode-map
+    "q" #'sly-inspector-quit))
 #+end_src
-** Grand Unified Debugger (GUD)
-GUD is a system for debugging, hooking into processes and
-providing an interface to the user all in Emacs.  Here I define a
-hydra which provides a ton of the useful =gud= keybindings that exist
-in an Emacs-only map.
+*** Lisp indent function
+Add a new lisp indent function which indents newline lists more
+appropriately.
+
 #+begin_src emacs-lisp
-(use-package gud
-  :general
-  :after hydra
-  :hydra
-  (gud-hydra
-   (:hint nil) "Hydra for GUD"
-   ("<"   #'gud-up "Up"
-    :column "Control Flow")
-   (">"   #'gud-down "Down"
-    :column "Control Flow")
-   ("b"   #'gud-break "Break"
-    :column "Breakpoints")
-   ("d"   #'gud-remove "Remove"
-    :column "Breakpoints")
-   ("f"   #'gud-finish "Finish"
-    :column "Control Flow")
-   ("J"   #'gud-jump "Jump"
-    :column "Control Flow")
-   ("L"   #'gud-refresh "Refresh"
-    :column "Misc")
-   ("n"   #'gud-next "Next"
-    :column "Control Flow")
-   ("p"   #'gud-print "Print"
-    :column "Misc")
-   ("c"   #'gud-cont "Cont"
-    :column "Control Flow")
-   ("s"   #'gud-step "Step"
-    :column "Control Flow")
-   ("t"   #'gud-tbreak "Tbreak"
-    :column "Control Flow")
-   ("u"   #'gud-until "Until"
-    :column "Control Flow")
-   ("v"   #'gud-go "Go"
-    :column "Control Flow")
-   ("w"   #'gud-watch "Watch"
-    :column "Breakpoints")
-   ("TAB" #'gud-stepi "Stepi"
-    :column "Control Flow"))
-  :general
-  (code-leader "d" #'gud-hydra/body
-    "D" #'gud-gdb))
+(use-package lisp-mode
+  :defer t
+  :config
+  (defun +oreo/lisp-indent-function (indent-point state)
+    (let ((normal-indent (current-column))
+          (orig-point (point)))
+      (goto-char (1+ (elt state 1)))
+      (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
+      (cond
+       ;; car of form doesn't seem to be a symbol, or is a keyword
+       ((and (elt state 2)
+             (or (not (looking-at "\\sw\\|\\s_"))
+                 (looking-at ":")))
+        (if (not (> (save-excursion (forward-line 1) (point))
+                    calculate-lisp-indent-last-sexp))
+            (progn (goto-char calculate-lisp-indent-last-sexp)
+                   (beginning-of-line)
+                   (parse-partial-sexp (point)
+                                       calculate-lisp-indent-last-sexp 0 t)))
+        ;; Indent under the list or under the first sexp on the same
+        ;; line as calculate-lisp-indent-last-sexp.  Note that first
+        ;; thing on that line has to be complete sexp since we are
+        ;; inside the innermost containing sexp.
+        (backward-prefix-chars)
+        (current-column))
+       ((and (save-excursion
+               (goto-char indent-point)
+               (skip-syntax-forward " ")
+               (not (looking-at ":")))
+             (save-excursion
+               (goto-char orig-point)
+               (looking-at ":")))
+        (save-excursion
+          (goto-char (+ 2 (elt state 1)))
+          (current-column)))
+       (t
+        (let ((function (buffer-substring (point)
+                                          (progn (forward-sexp 1) (point))))
+              method)
+          (setq method (or (function-get (intern-soft function)
+                                         'lisp-indent-function)
+                           (get (intern-soft function) 'lisp-indent-hook)))
+          (cond ((or (eq method 'defun)
+                     (and (null method)
+                          (> (length function) 3)
+                          (string-match "\\`def" function)))
+                 (lisp-indent-defform state indent-point))
+                ((integerp method)
+                 (lisp-indent-specform method state
+                                       indent-point normal-indent))
+                (method
+                 (funcall method indent-point state))))))))
+  (setq-default lisp-indent-function #'+oreo/lisp-indent-function))
 #+end_src
 * Miscellaneous
 ** Evil additions
@@ -4055,24 +4119,12 @@ A port of vim-commentary, providing generalised commenting of objects.
   :config
   (evil-commentary-mode))
 #+end_src
-*** Evil multi cursor
-Setup for multi cursors in Evil mode, which is a bit of very nice
-functionality.  Don't let evil-mc setup it's own keymap because it
-uses 'gr' as its prefix, which I don't like.
-
-#+begin_src emacs-lisp
-(use-package evil-mc
-  :after evil
-  :straight t
-  :init
-  (setq evil-mc-cursors-keymap-prefix "gz")
-  :config
-  (global-evil-mc-mode))
-#+end_src
 *** Evil multi edit
 Evil-ME provides a simpler parallel editing experience within the same
-buffer.  I use it in-tandem with Evil-MC, where I use Evil-ME for
-textual changes and Evil-MC for more complex motions.
+buffer.  I now use it exclusively over evil multi-cursor: this is
+designed better, its less buggy, and doesn't try to over complicate
+things.  There are many things it can't do, but normal Vim motions
+can.  It's useful for trialing
 
 #+begin_src emacs-lisp
 (use-package evil-multiedit
@@ -4097,8 +4149,8 @@ I may disagree with some.  So I use it in a mode to mode basis.
   :hook (after-init-hook . evil-collection-init)
   :straight t
   :init
-  (setq evil-collection-mode-list
-        '(flycheck eww magit calendar notmuch ibuffer proced calc)))
+  (setq evil-collection-mode-list '(eww flycheck magit calendar notmuch
+                                        ibuffer proced calc image)))
 #+end_src
 *** Evil number
 Increment/decrement a number at point like Vim does, but use bindings
@@ -4161,14 +4213,14 @@ effectively.
     "R" #'tab-rename
     "c" #'tab-close
     "d" #'tab-close
-    "f" #'tab-detach
     "h" #'tab-move-to
     "j" #'tab-next
     "k" #'tab-previous
     "l" #'tab-move
     "n" #'tab-new
     "r" #'tab-switch
-    "w" #'tab-window-detach))
+    "w" #'tab-window-detach
+    "b" (proc-int (switch-to-buffer-other-tab (current-buffer)))))
 #+end_src
 ** Registers
 Registers are essentially an alist of symbols mapped to some Lisp
@@ -4212,6 +4264,21 @@ but I prefer Emacs' hence the configuration here.
     "m"   #'point-to-register
     "'"   #'jump-to-register))
 #+end_src
+** Bookmarks
+Bookmarks are like persistent registers.  Like registers, they can
+kinda work anywhere in Emacs: from remote files via =tramp= to
+webpages with [[*EWW][EWW]].  Since they're persistent, they'll live
+regardless of the current Emacs session - and because they're like
+registers, they'll remember the exact context (position in buffer,
+time since last updated, etc).
+#+begin_src emacs-lisp
+(use-package bookmark
+  :general
+  (leader "x" bookmark-map)
+  :init
+  (setq bookmark-watch-bookmark-file t
+        bookmark-save-flag 1))
+#+end_src
 ** Recentf
 Recentf provides a method of keeping track of recently opened files.
 
-- 
cgit v1.2.3-13-gbd6f