]> git.earman.xyz Git - emacsinit.git/commitdiff
Switch to config.org instead of README
authorrearman <rearman@r717.net>
Mon, 11 May 2026 13:13:08 +0000 (09:13 -0400)
committerrearman <rearman@r717.net>
Mon, 11 May 2026 13:13:08 +0000 (09:13 -0400)
Much simpler when the org file and intended el file have the same name.  Makes
it so you can use the built-in org-babel-load-file, which checks for
write-time differences before tangling.  I also don't need a README for my own
configs, I know where everything is.

README.org [deleted file]
config.org [new file with mode: 0644]
init.el

diff --git a/README.org b/README.org
deleted file mode 100644 (file)
index efdd69e..0000000
+++ /dev/null
@@ -1,1362 +0,0 @@
-#+TITLE: Emacs literate config
-#+STARTUP: noindent
-#+PROPERTY: header-args emacs-lisp :tangle config.el
-
-* Header
-#+BEGIN_SRC emacs-lisp
-;;; config.el --- Emacs Configuration  -*- lexical-binding: t; -*-
-
-;; This file is not part of GNU emacs
-
-;;; Code:
-
-#+END_SRC
-* Load libraries
-Libraries Not from the package manager
-#+BEGIN_SRC emacs-lisp
-  (dolist (path '("sedit-mouse/" "themes/" "re/"))
-      (add-to-list 'load-path (concat user-emacs-directory path)))
-
-  (dolist (file '(pass-alike eng-paper-theme sedit-mouse))
-       (require file))
-#+END_SRC
-* OS specific stuff
-#+BEGIN_SRC emacs-lisp
-  (setq w32-recognize-altgr 'nil)
-
-  (unless (equal system-type 'windows-nt)
-    (require 're-mu4e)
-    (setq trash-directory "~/Trash/")
-    (defun doas ()
-      "Use TRAMP to reopen the current buffer as root using doas."
-      (interactive)
-      (when buffer-file-name
-       (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
-    (defun sudo ()
-      "Use TRAMP to reopen the current buffer as root using sudo."
-      (interactive)
-      (when buffer-file-name
-       (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))))
-
-#+END_SRC
-* Add melpa, and reduce the declarations by setting defaults
-#+BEGIN_SRC emacs-lisp
-(require 'package)
-
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
-
-(setq use-package-always-ensure t
-      use-package-always-defer t)
-#+END_SRC
-* Corfu
-#+BEGIN_SRC emacs-lisp
-(use-package corfu
-  :demand
-  t
-  :custom
-  (corfu-auto t)
-  (corfu-auto-delay 0)
-  (corfu-auto-prefix 1)
-  :config
-  (global-corfu-mode))
-
-(use-package corfu-popupinfo
-  :ensure
-  nil ; part of corfu
-  :after
-  corfu
-  :hook
-  (corfu-mode . corfu-popupinfo-mode)
-  :custom
-  (corfu-popupinfo-delay '(1.0 . 0.01)) ; start after one second, fast refresh once on
-  (corfu-popupinfo-hide nil)
-  :config
-  (corfu-popupinfo-mode))
-#+END_SRC
-* Expand Region
-#+BEGIN_SRC emacs-lisp
-(use-package expand-region
-  :bind
-  (("C-=" . er/expand-region)))
-#+END_SRC
-* Aggressive Indent
-#+BEGIN_SRC emacs-lisp
-(use-package aggressive-indent)
-#+END_SRC
-* Magit
-No longer needed, since I defer by default.
-* Page Break Lines
-Needs to be demanded so I don't have to manually load it
-#+BEGIN_SRC emacs-lisp
-(use-package page-break-lines
-  :demand
-  t
-  :config
-  (global-page-break-lines-mode))
-#+END_SRC
-* AucTeX and pdftools
-Make AucTeX use pdftools, prompt for master file, synctex, etc.  Be sure to run =pdf-tools-install= before first use.
-#+BEGIN_SRC emacs-lisp
-(use-package pdf-tools)
-
-(use-package auctex
-  :config
-  (setq-default TeX-master nil)
-  (add-to-list 'TeX-view-program-selection '(output-pdf "PDF Tools"))
-  (setq TeX-auto-save t
-       TeX-parse-self t
-       TeX-PDF-mode t
-       TeX-source-correlate-start-server t)
-  (add-hook 'TeX-after-compilation-finished-functions
-           #'TeX-revert-document-buffer))
-#+END_SRC
-* CSV Mode
-#+BEGIN_SRC emacs-lisp
-(use-package csv-mode
-  :config
-  (add-hook 'csv-mode-hook 'csv-align-mode))
-#+END_SRC
-* Markdown Mode
-Make markdown act more like org when I'm forced to use it
-#+BEGIN_SRC emacs-lisp
-(use-package markdown-mode
-  :config
-  (setq markdown-special-ctrl-a/e t)
-  :bind
-  (:map markdown-mode-map
-       ("M-<right>" . markdown-demote)
-       ("M-<left>" . markdown-promote)
-       ("M-<up>" . markdown-move-up)
-       ("M-<down>" . markdown-move-down)
-       ("C-M-u" . markdown-up-heading)
-       ("C-M-b" . markdown-outline-previous-same-level)
-       ("C-M-f" . markdown-outline-next-same-level)
-       ("C-M-p" . markdown-outline-previous)
-       ("C-M-n" . markdown-outline-next)))
-
-(use-package edit-indirect :after 'markdown-mode)
-#+END_SRC
-* Sly
-#+BEGIN_SRC emacs-lisp
-  (defun re/sly-repl-new-frame (&optional arg)
-    "Start a SLY repl in a new frame."
-    (interactive "P")
-    (re/open-with-new-frame "SLY" #'sly))
-
-  (defun re/sly-quit-current-lisp ()
-    "Quit the current lisp repl connection without prompting."
-    (interactive)
-    (sly-quit-lisp nil nil))
-
-  (defun re/sly-connect-stump (&optional arg)
-    "Connect to my typical stumpwm instance."
-    (interactive "P")
-    (sly-connect "localhost" 4004))
-
-  (use-package sly
-    :config
-    (setq inferior-lisp-program "sbcl"
-       sly-net-coding-system 'utf-8-unix
-       sly-command-switch-to-existing-lisp 'always)
-    (let ((core (expand-file-name "~/sbcl.core-for-sly")))
-      (when (file-exists-p core)
-       (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core))))))
-    :bind
-    (:map sly-mrepl-mode-map
-       (")" . (lambda () (interactive) (re/send-on-close-paren #'sly-mrepl-return)))
-       ("]" . (lambda () (interactive) (re/balance-and-eval-sexp #'sly-mrepl-return)))
-       ("C-c q" . re/sly-quit-current-lisp)))
-#+END_SRC
-** Eldoc settings
-Sly really doesn't play well with elodc in the minibuffer, so here are some settings to make it better.
-#+BEGIN_SRC emacs-lisp
-(add-to-list 'display-buffer-alist
-            '("^\\*eldoc" display-buffer-in-direction
-              (direction . 'down)
-              (window-height . 4)))
-(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer
-(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed
-#+END_SRC
-* Geiser
-#+BEGIN_SRC emacs-lisp
-  (use-package geiser
-    :config
-    (if (equal system-type 'windows-nt)
-       (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))
-      (setq geiser-chicken-binary "csi -:c"))
-    (setq scheme-program-name geiser-chicken-binary
-       geiser-active-implementations '(chicken))
-    (add-hook 'scheme-mode-hook 'geiser-mode)
-    :bind
-    (:map geiser-repl-mode-map
-       (")" . (lambda () (interactive) (re/send-on-close-paren #'geiser-repl-maybe-send)))
-       ("]" . (lambda () (interactive) (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))))
-
-  (use-package geiser-chicken :after 'geiser)
-#+END_SRC
-* Forth
-** TODO Try out this mode for gforth
-#+BEGIN_SRC emacs-lisp
-(use-package forth-mode)
-#+END_SRC
-* ORG
-** Load in the package and set bindings
-#+BEGIN_SRC emacs-lisp
-  (use-package org
-    :config
-    (require 'org-mouse)
-    :bind
-    (("C-c l" . org-store-link)
-     ("C-c a" . org-agenda)
-     ("C-c c" . org-capture)
-     ("C-c b" . org-switchb)
-     ("<f10>" . org-clock-out)
-     ("<f2>" . org-clock-goto)
-     :map org-mode-map
-     ("M-<right>" . org-shiftmetaright)
-     ("M-<left>" . org-shiftmetaleft)
-     ("M-S-<right>" . org-metaright)
-     ("M-S-<left>" . org-metaleft)
-     ("C-M-h" . org-mark-subtree)
-     ("C-M-u" . org-up-element)
-     ("C-M-d" . org-down-element)
-     ("C-M-b" . org-backward-heading-same-level)
-     ("C-M-f" . org-forward-heading-same-level)
-     ("C-M-p" . org-previous-visible-heading)
-     ("C-M-n" . org-next-visible-heading)
-     ("<f9>" . org-clock-in)))
-
-  (use-package org-transclusion
-    :after
-    org
-    :bind
-    (("C-c t" . org-transclusion-mode)))
-#+END_SRC
-** Configuration
-*** General options
-#+BEGIN_SRC emacs-lisp
-  (with-eval-after-load 'org-mode (add-to-list 'org-export-backends 'md))
-
-  (setq org-startup-indented nil
-       org-indent-indentation-per-level 1
-       org-startup-folded 'fold
-       org-startup-with-inline-images t
-       org-cycle-inline-images-display t
-       org-cycle-separator-lines 0
-       org-blank-before-new-entry '((heading) (plain-list-item . auto))
-       org-M-RET-may-split-line nil
-       org-treat-S-cursor-todo-selection-as-state-change nil
-       org-treat-insert-todo-heading-as-state-change nil
-       org-table-export-default-format "orgtbl-to-csv"
-       org-list-allow-alphabetical t
-       org-fold-catch-invisible-edits 'show-and-error
-       org-ellipsis "↴"
-       org-tags-column 0
-       org-reverse-note-order t
-       org-enforce-todo-dependencies t
-       org-enforce-todo-checkbox-dependencies t
-       org-fontify-done-headline nil
-       org-fontify-todo-headline nil
-       org-goto-interface 'outline-path-completion
-       org-outline-path-complete-in-steps nil
-       org-goto-auto-isearch nil
-       org-special-ctrl-a/e t
-       org-special-ctrl-k t
-       org-return-follows-link t
-       org-yank-adjusted-subtrees t
-       org-src-window-setup 'current-window
-       org-src-preserve-indentation t)
-#+END_SRC
-*** Time Clocking
-#+BEGIN_SRC emacs-lisp
-(org-clock-persistence-insinuate)
-(setq org-clock-history-length 10
-      org-clock-in-resume t
-      org-clock-out-remove-zero-time-clocks t
-      org-clock-persist t
-      org-clock-persist-query-resume nil
-      org-clock-report-include-clocking-task t
-      org-time-stamp-rounding-minutes '(1 1))
-#+END_SRC
-*** Agenda and Capture
-#+BEGIN_SRC emacs-lisp
-(add-hook 'org-agenda-mode-hook #'hl-line-mode)
-
-(setq org-agenda-files (append '("~/org/")
-                        (file-expand-wildcards "~/projects/*/"))
-      org-refile-targets '((nil :maxlevel . 9)
-                          (org-agenda-files :maxlevel . 9))
-      org-refile-use-outline-path 'file
-      org-refile-allow-creating-parent-nodes 'confirm
-      org-tag-alist '(("call" . ?c)
-                     ("email" . ?e)
-                     ("errand" . ?r)
-                     ("jobpc" . ?j)
-                     ("license" . ?l)
-                     ("meeting" . ?m)
-                     ("open" . ?o))
-      org-tags-exclude-from-inheritance '("open")
-      org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)")
-                         (sequence "MEETING(m)" "|" "MET(M)"))
-      org-todo-keyword-faces '(("WAITING" :foreground "#e85400" :weight bold)
-                              ("MEETING" :foreground "#315e9a" :weight bold))
-      org-agenda-restore-windows-after-quit t
-      org-agenda-start-on-weekday nil
-      org-agenda-compact-blocks t
-      org-agenda-span 'day
-      org-deadline-warning-days 30
-      org-agenda-window-setup 'current-window
-      org-agenda-time-grid '((daily today remove-match)
-                            (600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900)
-                            " ――――― "
-                            "")
-      org-agenda-tags-column 50
-      org-agenda-skip-additional-timestamps-same-entry t
-      org-agenda-skip-deadline-if-done t
-      org-agenda-skip-scheduled-if-done t
-      org-agenda-prefix-format '((agenda . "  %?-12t% s")
-                                (todo . "  ")
-                                (tags . "  ")
-                                (search . "  "))
-      org-agenda-scheduled-leaders '("BOOKED: " "Booked %2d d. ago: ")
-      org-agenda-deadline-leaders '("DEADLINE: " "In %3d d.: " "%2d d. ago: ")
-      org-read-date-prefer-future 'time
-      org-agenda-custom-commands '(("f" "Maybe Someday" tags "someday" ((org-agenda-overriding-header "SOMEDAY:")))
-                                  ("i" "Inbox" tags "inbox" ((org-agenda-overriding-header "INBOX:")))
-                                  ("l" "Licenses" tags "license" ((org-agenda-overriding-header "LICENSES:")))
-                                  ("n" "Next Actions" tags-todo "-recurring/TODO" ((org-agenda-overriding-header "NEXT:")))
-                                  ("p" "JobPCs" tags "jobpc" ((org-agenda-overriding-header "JOB PCS:")))
-                                  ("u" "Undertakings" tags "open" ((org-agenda-overriding-header "UNDERTAKINGS:")))
-                                  ("w" "Waiting" todo "WAITING" ((org-agenda-overriding-header "WAITING:")))
-                                  ("o" "Overview" ((agenda "")
-                                                   (tags "inbox" ((org-agenda-overriding-header "\nINBOX:")))
-                                                   (tags-todo "-recurring/TODO" ((org-agenda-overriding-header "\nNEXT:")
-                                                                                 (org-agenda-max-entries 10)))
-                                                   (tags "open" ((org-agenda-overriding-header "\nUNDERTAKINGS:")))
-                                                   (todo "WAITING" ((org-agenda-overriding-header "\nWAITING:"))))))
-      org-agenda-start-with-log-mode t
-      org-agenda-log-mode-items '(closed clock state)
-      org-log-done 'time
-      org-log-into-drawer nil
-      org-log-state-notes-insert-after-drawers t
-      org-log-state-notes-into-drawer nil
-      org-capture-templates '(("i" "Inbox" entry
-                              (file "gtd.org")
-                              "* %^{Description} :inbox:\n%U\n%?"
-                              :prepend t
-                              :clock-in t
-                              :clock-resume t)
-                             ("m" "Meeting" entry
-                              (file "gtd.org")
-                              "* MEETING %^{Description} :meeting:\n%^{Scheduled:}T\n%?"
-                              :prepend t
-                              :clock-in t
-                              :clock-resume t)
-                             ("p" "Phone Call" entry
-                              (file "gtd.org")
-                              "* %^{Description} :call:\n%U\n%?"
-                              :prepend t
-                              :clock-in t
-                              :clock-resume t)))
-#+END_SRC
-*** IDs
-#+BEGIN_SRC emacs-lisp
-(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
-      org-id-method 'ts
-      org-clone-delete-id t
-      org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
-                                           org-attach-id-uuid-folder-format))
-
-(defun re/org-auto-generate-ids-in-file ()
-  "Add ID properties to all headlines in the current
- file which do not already have one."
-  (interactive)
-  (org-map-entries 'org-id-get-create))
-
-(defun re/org-save-all ()
-  "Save all `org-agenda-files' without user confirmation."
-  (interactive)
-  (message "Saving all org-agenda-files buffers...")
-  (save-some-buffers t
-                    (lambda ()
-                      (when (member (buffer-file-name) org-agenda-files) t)))
-  (message "Saving all org-agenda-files buffers... done"))
-
-(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))
-#+END_SRC
-*** Archiving
-#+BEGIN_SRC emacs-lisp
-(defun re/org-archive-all ()
-  "Archive all tasks marked `DONE' in agenda files"
-  (interactive)
-  (message "Archiving all completed tasks in org-agenda-files...")
-  (org-map-entries (lambda ()
-                    (org-archive-subtree)
-                    (setq org-map-continue-from (org-element-property
-                                                 :begin
-                                                 (org-element-at-point))))
-                  "/DONE"
-                  'agenda)
-  (message "Archiving all completed tasks in org-agenda-files... done"))
-
-(setq org-archive-location (concat "~/org/old.org_keep::datetree/")
-      org-agenda-text-search-extra-files '(agenda-archives))
-
-(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))
-#+END_SRC
-* HOWM
-On-again, off-again relationship with this one
-** Load package and add bindings
-#+BEGIN_SRC emacs-lisp
-  (use-package howm
-    :bind
-    (("<f6>" . howm-menu)
-     ("S-<f6>" . re/howm-menu-new-frame)
-     :map howm-mode-map
-     ("C-c , k" . re/howm-create-keyword)
-     ("C-c , =" . howm-narrow-to-memo)))
-#+END_SRC
-** Config
-*** General settings
-#+BEGIN_SRC emacs-lisp
-(setq howm-template '("= %title%cursor #inbox\n%date %file\n\n"
-                     "= %title%cursor #meeting\n%date %file\n\nAttendees: \n"
-                     "= @%title%cursor\n%date %file\n\n")
-      howm-keyword-file "~/howm/.howm-keys"
-      howm-history-file "~/howm/.howm-history"
-      howm-menu-file "~/.emacs.d/0000-00-00-000000.txt"
-      howm-file-name-format "%Y%m%dT%H%M%S.txt"
-      howm-keyword-case-fold-search t
-      howm-remember-insertion-format "%s"
-      howm-menu-todo-num 10)
-
-(defun re/howm-menu-new-frame (&optional arg)
-  "Show the howm menu in a new frame"
-  (interactive "P")
-  (re/open-with-new-frame "HOWM" #'howm-menu))
-
-(defun re/howm-create-keyword ()
-  "Reads a keyword from the minibuffer and appends it to the keywords file."
-  (interactive)
-  (append-to-file (concat (read-string "New Keyword: ")
-                         "\n")
-                 nil
-                 howm-keyword-file
-                 "\n"))
-#+END_SRC
-*** Menu config
-#+BEGIN_SRC emacs-lisp
-;; add entries in howm-menu (press enter on the text)
-(defun re/howm-menu-legend ()
-  (cl-labels ((p (text face) (propertize text 'font-lock-face face)))
-    (concat (format "Top %s" howm-menu-todo-num)
-           " "
-           (p "!Deadline" howm-reminder-deadline-face)
-           "/"
-           (p "+ToDo" howm-reminder-todo-face)
-           "/"
-           (p "@Schedule" howm-reminder-schedule-face)
-           "/"
-           (p "~Defer" howm-reminder-defer-face)
-           "/"
-           (p "-Reminder" howm-reminder-normal-face)
-           " Entries:")))
-
-(with-eval-after-load 'howm
-  (dolist (aldr-additions '(("\\[Mtg\\]" (lambda (&optional dummy) (howm-create 2)))
-                           ("\\[Person\\]" (lambda (&optional dummy) (howm-create 3)))))
-    (add-to-list 'action-lock-default-rules aldr-additions t))
-  (add-to-list 'howm-menu-allow 're/howm-menu-legend)
-  ;; add coloring for custom "waiting" state
-  (add-to-list 'howm-reminder-font-lock-keywords
-              `(,(howm-reminder-regexp "[w]") (0 howm-reminder-defer-face prepend))
-              t))
-
-(dolist (hooks '(after-save-hook howm-mode-hook))
-  (add-hook hooks 'howm-mode-set-buffer-name))
-#+END_SRC
-
-* Trashed
-Shows the trash file as a dired buffer
-#+BEGIN_SRC emacs-lisp
-(use-package trashed
-  :config
-  (setq trashed-action-confirmer 'y-or-n-p
-       trashed-use-header-line t
-       trashed-sort-key '("Date deleted" . t)
-       trashed-date-format "%Y-%m-%d %H:%M:%S"))
-#+END_SRC
-* Editing
-** UNIX/vi-like bindings
-=C-h=, =C-w=, =C-u=, et. al to work as I expect.  Some functions get re-bound when these take over a default.
-#+BEGIN_SRC emacs-lisp
-  (defun re/open-line-below (n)
-    "Creates a new empty line below the current line and moves to it."
-    (interactive "*p")
-    (end-of-line)
-    (open-line n)
-    (next-line 1)
-    (indent-for-tab-command))
-
-  (keymap-global-set "C-o" #'re/open-line-below)
-
-  (defun re/open-line-above (n)
-    "Creates a new empty line above the current line."
-    (interactive "*p")
-    (beginning-of-line)
-    (open-line n)
-    (indent-for-tab-command))
-
-  (keymap-global-set "M-o" #'re/open-line-above)
-
-  (defun re/kill-bword-or-region (&optional arg)
-    "Kill region if active, otherwise kill back one word."
-    (interactive "p")
-    (if (use-region-p)
-       (kill-region (region-beginning) (region-end))
-      (backward-kill-word arg)))
-
-  (keymap-global-set "C-w" #'re/kill-bword-or-region)
-  (keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards
-  (keymap-global-set "C-S-U" #'universal-argument)
-  (keymap-set key-translation-map "C-h" "<DEL>") ; Rather F1 for help, also C-S-H works
-  (keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way
-#+END_SRC
-** Commenting and defun-level bindings
-#+BEGIN_SRC emacs-lisp
-  (defun re/comment-dwim (&optional arg)
-    "Comment region if active, otherwise comment line.
-  Stolen from https://depp.brause.cc/dotemacs"
-    (interactive "P")
-    (if (use-region-p)
-       (comment-or-uncomment-region (region-beginning) (region-end))
-      (comment-line arg)))
-
-  (keymap-global-set "M-;" #'re/comment-dwim)
-
-  (defun re/comment-defun (&optional arg)
-    "Mark a defun and comment it out.
-  Return to initial position after.  Arg works on `mark-defun'."
-    (interactive "P")
-    (save-excursion (mark-defun arg)
-                   (comment-region (region-beginning) (region-end))))
-
-  (keymap-global-set "C-M-;" #'re/comment-defun)
-
-  (defun re/kill-defun (&optional arg)
-    "Mark a defun and kill it.
-  Arg works on `mark-defun'."
-    (interactive "P")
-    (mark-defun arg)
-    (kill-region (region-beginning) (region-end)))
-
-  (keymap-global-set "C-M-S-K" #'re/kill-defun)
-#+END_SRC
-
-** Misc QOL bindings
-#+BEGIN_SRC emacs-lisp
-(keymap-global-set "<insert>" nil) ; I keep toggliŋ overwrite-mode haply
-(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes
-(keymap-global-set "C-S-K" #'kill-whole-line)
-(keymap-global-set "C-S-d" #'delete-pair)
-(keymap-global-set "C-z" #'zap-up-to-char)
-(keymap-global-set "C-c s" #'sort-lines)
-(keymap-global-set "<remap> <capitalize-word>" #'capitalize-dwim) ; M-c
-(keymap-global-set "<remap> <downcase-word>" #'downcase-dwim) ; M-l
-(keymap-global-set "<remap> <upcase-word>" #'upcase-dwim) ; M-u
-#+END_SRC
-* Tabs
-I want *TABS*, not spaces, dammit.  Globally overwrite the tab key to insert the tab character.  This makes it so that many things (completion) will have to be triggered with =C-i= instead, but I don't think it's necessarily bad to have things like that on a control combo instead of overloading the tab key at the expense of being able to actually insert tabs.
-#+BEGIN_SRC emacs-lisp
-;; Tabs
-(setq-default indent-tabs-mode t
-             tab-width 8
-             backward-delete-char-untabify-method nil)
-
-(advice-add 'indent-to :around
-           (lambda (orig-fun column &rest args)
-             (when indent-tabs-mode
-               (setq column (* tab-width (round column tab-width))))
-             (apply orig-fun column args)))
-
-(dolist (indent-level '(c-basic-offset cperl-indent-level LaTeX-indent-level))
-  (defvaralias indent-level 'tab-width))
-
-(defun Tab (width)
-  "Give me a function analagous to the Acme `Tab' command"
-  (interactive)
-  (setq-local tab-width width))
-
-(keymap-global-set "<tab>" (lambda () (interactive) (insert "\t")))
-#+END_SRC
-* Buffer dealiŋ
-#+BEGIN_SRC emacs-lisp
-;; Buffer dealiŋ
-(setq-default indicate-empty-lines t
-             truncate-lines t
-             fill-column 78)
-
-(dolist (hook '(text-mode-hook LaTeX-mode-hook))
-  (add-hook hook #'visual-line-mode))
-
-(blink-cursor-mode -1)
-(delete-selection-mode t)
-
-(setq delete-by-moving-to-trash t
-      delete-pair-blink-delay 0
-      use-short-answers t
-      use-file-dialog nil
-      echo-keystrokes 0.1
-      eldoc-idle-delay 0
-      read-buffer-completion-ignore-case t
-      history-delete-duplicates t
-      disabled-command-function nil
-      save-interprogram-paste-before-kill t
-      confirm-kill-processes nil)
-
-(keymap-global-set "C-x M-f" #'find-file-at-point)
-(keymap-global-set "C-x C-b" #'buffer-menu)
-(keymap-global-set "C-x M-b" #'buffer-menu-other-window)
-(keymap-global-set "C-x k" #'kill-current-buffer)
-(keymap-global-set "C-x K" #'kill-buffer)
-#+END_SRC
-* Recentering and page-by-page navigation
-#+BEGIN_SRC emacs-lisp
-(setq recenter-positions '(2 middle -3))
-
-(defun re/recenter-advice (&rest _)
-  "Recenter to page start."
-  (when (called-interactively-p 'any) (recenter 2)))
-
-(dolist (binding '(backward-page forward-page))
-  (advice-add binding :after #'re/recenter-advice))
-
-(keymap-global-set "C-x C-n" #'forward-page)
-(keymap-global-set "C-x C-p" #'backward-page)
-(keymap-global-set "<next>" #'forward-page)
-(keymap-global-set "<prior>" #'backward-page)
-#+END_SRC
-* Macro to open something in its own named frame
-Start a repl in a new frame, open dired in a new frame, etc. etc.
-#+BEGIN_SRC
-(defmacro re/open-with-new-frame (frname function)
-  "Run the function in its own named frame."
-  `(progn
-     (select-frame (make-frame '((name . ,(eval frname)))))
-     (call-interactively ,function)))
-#+END_SRC
-* Motion
-#+BEGIN_SRC emacs-lisp
-;; Motion
-(defun re/scratch-only ()
-  "Bring up the scratch buffer as the only visible buffer."
-  (interactive)
-  (scratch-buffer)
-  (delete-other-windows))
-
-(keymap-global-set "<f5>" #'scratch-buffer)
-(keymap-global-set "S-<f5>" #'re/scratch-only)
-
-(defun re/other-window-or-split-window (&optional window)
-  "Go to other window or split sensibly."
-  (interactive)
-  (if (= (count-windows) 1)
-      (funcall split-window-preferred-function window)
-    (other-window 1)))
-
-(keymap-global-set "C-M-o" #'re/other-window-or-split-window)
-
-(defun re/smart-beginning-of-line ()
-  "Move point to first non-whitespace character or `beginning-of-visual-line'.
-If point was already at that position, call `back-to-indentation'.
-Called a third time, move point back to `beginning-of-line'.
-If in org-mode, call `org-beginning-of-line' first."
-  (interactive "^")
-  (let ((oldpos (point)))
-    (if (equal major-mode 'org-mode)
-       (org-beginning-of-line)
-      (progn
-       (when visual-line-mode (beginning-of-visual-line 1))
-       (skip-syntax-forward " " (line-end-position))
-       (backward-prefix-chars)))
-    (and (= oldpos (point))
-        (let ((newpos (point)))
-          (back-to-indentation)
-          (and (= newpos (point)) (beginning-of-line))))))
-
-(keymap-global-set "<remap> <move-beginning-of-line>" #'re/smart-beginning-of-line)
-(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line)
-
-(defun re/smart-end-of-line ()
-  "Move point to the end of the visual line.
- If point was already at that position, call `move-end-of-line'.
-If in org-mode, call `org-end-of-line' first."
-  (interactive "^")
-  (let ((oldpos (point)))
-    (if (equal major-mode 'org-mode)
-       (org-end-of-line)
-      (when visual-line-mode
-       (end-of-visual-line 1)))
-    (and (= oldpos (point)) (move-end-of-line nil))))
-
-(keymap-global-set "<remap> <move-end-of-line>" #'re/smart-end-of-line)
-(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line)
-
-(defun re/goto-line ()
-  "Show line numbers before going to line, then hide them again."
-  (interactive)
-  (display-line-numbers-mode 1)
-  (call-interactively 'goto-line)
-  (display-line-numbers-mode -1))
-
-(keymap-global-set "<remap> <goto-line>" #'re/goto-line)
-(keymap-global-set "<home>" #'beginning-of-buffer)
-(keymap-global-set "<end>" #'end-of-buffer)
-(keymap-global-set "C-." #'next-buffer)
-(keymap-global-set "C-," #'previous-buffer)
-(keymap-global-set "C-<tab>" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers
-(keymap-global-set "<mouse-4>" #'previous-buffer) ; Back button
-(keymap-global-set "<mouse-5>" #'next-buffer) ; Forward button
-;; Disable M-mouse for window manager bindings
-(keymap-global-unset "M-<down-mouse-1>")
-(keymap-global-unset "M-<drag-mouse-1>")
-(keymap-global-unset "M-<mouse-1>")
-(keymap-global-unset "M-<mouse-2>")
-(keymap-global-unset "M-<mouse-3>")
-#+END_SRC
-* Search
-#+BEGIN_SRC emacs-lisp
-;; Search
-(defun re/add-region-to-search-ring ()
-  (when (use-region-p)
-    (add-to-history 'search-ring
-                   (buffer-substring (region-beginning) (region-end)))
-    (deactivate-mark)))
-
-(defun re/isearch-forward-use-region ()
-  "Search text in region if active, otherwise normal forward search."
-  (interactive)
-  (re/add-region-to-search-ring)
-  (isearch-forward))
-
-(keymap-global-set "C-s" #'re/isearch-forward-use-region)
-
-(defun re/isearch-backward-use-region ()
-  "Search text in region if active, otherwise normal backward search."
-  (interactive)
-  (re/add-region-to-search-ring)
-  (isearch-backward))
-
-(keymap-global-set "C-r" #'re/isearch-backward-use-region)
-
-(defun re/exchange-point-and-mark-maybe-activate (arg)
-  "Call `exchange-point-and-mark' but don't activate the region.
-Stolen from https://www.masteringemacs.org/article/fixing-mark-commands-transient-mark-mode"
-  (interactive "P")
-  (exchange-point-and-mark (if (and transient-mark-mode (not mark-active))
-                              (not arg)
-                            arg)))
-
-(keymap-global-set "<remap> <exchange-point-and-mark>" #'re/exchange-point-and-mark-maybe-activate)
-
-(keymap-global-set "M-s ." #'isearch-forward-thing-at-point)
-(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point)
-(keymap-global-set "M-%" #'replace-regexp)
-(keymap-global-set "C-%" #'replace-string)
-(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff)
-(keymap-global-set "C-S-S" #'isearch-forward-regexp)
-(keymap-global-set "C-S-R" #'isearch-backward-regexp)
-#+END_SRC
-* Recent Files/Buffers
-#+BEGIN_SRC emacs-lisp
-;; Recent Files/Buffers
-(midnight-mode t)
-(setq clean-buffer-list-delay-general 1)
-(dolist (never-re '("\\` \\*tramp/.*\\'"
-                   "\\` \\*eshell.*\\'"))
-  (add-to-list 'clean-buffer-list-kill-never-regexps never-re))
-(save-place-mode 1)
-(recentf-mode 1)
-#+END_SRC
-* File Handling
-#+BEGIN_SRC emacs-lisp
-;; File Handling
-(defun re/rename-current-buffer-file nil
-  "Renames the current buffer and the file it is visiting."
-  (interactive)
-  (let ((name (buffer-name))
-       (filename (buffer-file-name)))
-    (if (not (and filename (file-exists-p filename)))
-       (error "Buffer '%s' is not visiting a file!" name)
-      (let ((new-name (read-file-name "New name: " filename)))
-       (if (get-buffer new-name)
-           (error "A buffer named '%s' already exists!" new-name)
-         (rename-file filename new-name 1)
-         (rename-buffer new-name)
-         (set-visited-file-name new-name)
-         (set-buffer-modified-p nil)
-         (message "File '%s' successfully renamed to '%s'"
-                  name
-                  (file-name-nondirectory new-name)))))))
-
-(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file)
-
-(defun re/get-line-from-file (file-path line-number)
-  "Return the specified LINE-NUMBER from FILE-PATH as a string.
-Start from bottom if given a negative line number."
-  (with-temp-buffer
-    (insert-file-contents file-path)
-    (if (< line-number 0)
-       (progn
-         (goto-char (point-max))
-         (forward-line line-number))
-      (progn
-       (goto-char (point-min))
-       (forward-line (1- line-number))))
-    (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-
-(defun re/get-file-modified-time (filepath)
-  (interactive)
-  (format-time-string "%Y-%m-%d-%H%M"
-                     (file-attribute-modification-time (file-attributes filepath))))
-
-(defun re/filename-inject-mod-time (filepath)
-  (interactive)
-  (concat (file-name-sans-extension filepath)
-         "_"
-         (re/get-file-modified-time filepath)
-         (file-name-extension filepath t)))
-
-(defun re/copy-with-mod-time (&optional filepath)
-  (interactive)
-  (let ((filepath (if (eq major-mode 'dired-mode)
-                     (dired-get-filename t)
-                   (when (null filepath)
-                     (read-file-name "File to copy with datestring: "
-                                     default-directory
-                                     nil
-                                     t
-                                     nil)))))
-    (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t)))
-#+END_SRC
-* Dired
-#+BEGIN_SRC emacs-lisp
-;; Dired
-(defun re/dired-display-direction ()
-  "In dired mode, visit the file at the cursor in the right/below/left/above window."
-  (interactive)
-  (let* ((file-or-dir (dired-get-file-for-visit)) ;; get the file at cursor
-        (buffer (find-file-noselect file-or-dir))) ;; load the file into a buffer
-    (let ((window ;; figure out the window to use
-          (cond ((get-buffer-window buffer (selected-frame)))
-                ((window-in-direction 'right)) ;; try window in each direction
-                ((window-in-direction 'below)) ;; and default to right
-                ((window-in-direction 'left))  ;; if no window found.
-                ((window-in-direction 'above))
-                (t (split-window (selected-window) nil 'right)))))
-      (window--display-buffer buffer window 'window nil)
-      window)))
-
-(defun re/dired-new-frame ()
-  "Open dired in a new frame."
-  (interactive)
-  (re/open-with-new-frame "DIRED"
-                         #'(lambda () (interactive) (dired default-directory))))
-
-(keymap-global-set "<f8>" #'re/dired-new-frame)
-
-(defun re/dired-find-marked-files ()
-  "Open all marked files from `dired'."
-  (interactive)
-  (mapc #'find-file (reverse (dired-get-marked-files))))
-
-(defun re/dired-sort ()
-  "Change sort order of dired dir."
-  (interactive)
-  (let ((smenu '(("name" . "-Ahl")
-                ("mdate" . "-Ahlt")
-                ("adate" . "-Ahltu")
-                ("size" . "-AhlS")
-                ("dir" . "-Ahl --group-directories-first")))
-       ssortBy)
-    (setq ssortBy (completing-read "Sort by (default name):"
-                                  smenu
-                                  nil
-                                  t
-                                  nil
-                                  nil
-                                  (caar smenu)))
-    (dired-sort-other (cdr (assoc ssortBy smenu)))))
-
-(defun re/open-file-external (file)
-  "Open a file in an external program."
-  (interactive)
-  (let ((process-connection-type nil))
-    (cond ((eq system-type 'windows-nt)
-          (w32-shell-execute "open"
-                             (replace-regexp-in-string "/" "\\\\" file t t)))
-         ((eq system-type 'gnu/linux)
-          (start-process "" nil "xdg-open" file))
-         (t (error "Unable to automatically open this file")))))
-
-(defun re/dired-open-externally ()
-  "Open the file at point in an external program."
-  (interactive)
-  (re/open-file-external (dired-get-filename)))
-
-(defun re/dired-open-marked-externally ()
-  "Open all marked files from `dired' in an external program."
-  (interactive)
-  (mapc #'re/open-file-external (reverse (dired-get-marked-files))))
-
-(setq dired-listing-switches "-Ahl"
-      dired-vc-rename-file t
-      dired-auto-revert-buffer t
-      dired-hide-details-hide-symlink-targets nil
-      dired-kill-when-opening-new-dired-buffer t)
-
-(add-hook 'dired-mode-hook
-         (lambda ()
-           (progn
-             (keymap-set dired-mode-map
-                         "o"
-                         #'re/dired-display-direction)
-             ;; Rename r,R+M(mv), chmod M>c, compress-to c>z
-             (keymap-set dired-mode-map
-                         "z"
-                         #'dired-do-compress-to)
-             (keymap-set dired-mode-map
-                         "c"
-                         #'dired-do-chmod)
-             (keymap-set dired-mode-map
-                         "r"
-                         #'dired-do-rename)
-             (keymap-set dired-mode-map
-                         "M"
-                         #'dired-do-rename)
-             ;; My add-on defuns
-             (keymap-set dired-mode-map
-                         "s"
-                         #'re/dired-sort)
-             (keymap-set dired-mode-map
-                         "F"
-                         #'re/dired-find-marked-files)
-             (keymap-set dired-mode-map
-                         "M-C"
-                         #'re/copy-with-mod-time)
-             (keymap-set dired-mode-map
-                         "b"
-                         #'re/dired-open-externally)
-             (keymap-set dired-mode-map
-                         "B"
-                         #'re/dired-open-marked-externally)
-             (dired-hide-details-mode t)
-             (hl-line-mode))))
-#+END_SRC
-* Bookmarks
-#+BEGIN_SRC emacs-lisp
-;; Bookmarks
-(setq bookmark-save-flag 1)
-(keymap-global-set "<f7>" #'recentf-open-files)
-(keymap-global-set "C-x r B" #'bookmark-jump-other-window)
-#+END_SRC
-* GUI
-#+BEGIN_SRC emacs-lisp
-;; GUI Settings
-(load-theme 'eng-paper t)
-(menu-bar-mode -1)
-(tool-bar-mode -1)
-(set-scroll-bar-mode (if (eq system-type 'windows-nt) nil 'left))
-
-(setq frame-title-format "%b"
-      mouse-prefer-closest-glyph t
-      mouse-1-click-follows-link nil
-      focus-follows-mouse t
-      mouse-autoselect-window -0.25)
-
-(setq-default cursor-type 'hbar
-             cursor-in-non-selected-windows nil
-             mode-line-format
-             '("%e"
-               (:eval (propertize "  "
-                                  'face
-                                  (when (buffer-modified-p)
-                                      'mode-line-highlight)))
-               " "
-               (:propertize (buffer-file-name "%f" "%b")
-                            face
-                            mode-line)
-               (vc-mode vc-mode)
-               mode-line-format-right-align
-               (:eval (number-to-string (line-number-at-pos (point-max))))
-               "L @ %I%n %l,%C "))
-
-(setq prettify-symbols-alist '(("lambda" . 955)
-                              ("delta" . 120517)
-                              ("epsilon" . 120518)
-                              ("->" . 8594)
-                              ("<=" . 8804)
-                              (">=" . 8805)))
-
-(global-prettify-symbols-mode t)
-#+END_SRC
-* Parens
-#+BEGIN_SRC emacs-lisp
-;; Parens (must be after loading the theme)
-(setq show-paren-delay 0
-      show-paren-style 'expression)
-
-(setq electric-pair-pairs '((?\" . ?\")
-                           (?\‘ . ?\’)
-                           (?\“ . ?\”)
-                           (?\{ . ?\})
-                           (?\< . ?\>)))
-#+END_SRC
-* Help
-#+BEGIN_SRC emacs-lisp
-;; Help
-(setq apropos-do-all t)
-#+END_SRC
-* UTF-8
-#+BEGIN_SRC emacs-lisp
-;; UTF-8
-(set-charset-priority 'unicode)
-(prefer-coding-system 'utf-8-unix)
-(set-language-environment 'utf-8)
-(set-default-coding-systems 'utf-8)
-(set-keyboard-coding-system 'utf-8-unix)
-(set-terminal-coding-system 'utf-8-unix)
-#+END_SRC
-* Cleanup on write
-#+BEGIN_SRC emacs-lisp
-(defun re/flush-extra-lines ()
-  "Change all groups of blank lines to 1 blank line."
-  (interactive)
-  (save-excursion (mark-whole-buffer)
-                 (replace-regexp "^\n+"
-                                 "\n"
-                                 nil
-                                 (region-beginning)
-                                 (region-end))))
-
-(setq require-final-newline t)
-(add-hook 'before-save-hook #'re/flush-extra-lines)
-(add-hook 'before-save-hook #'whitespace-cleanup)
-(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
-#+END_SRC
-* Control
-#+BEGIN_SRC emacs-lisp
-;; Control
-(defun re/kill-emacs ()
-  "Save all open files and kill emacs."
-  (interactive)
-  (save-some-buffers t)
-  (kill-emacs))
-
-(keymap-global-set "C-x M-c" #'re/kill-emacs)
-
-(defun re/restart-emacs ()
-  "Save all open files and restart emacs."
-  (interactive)
-  (save-some-buffers t)
-  (kill-emacs nil t))
-
-(keymap-global-set "C-x M-r" #'re/restart-emacs)
-
-(defun re/keyboard-quit ()
-  "Smarter version of `keyboard-quit'.
-Close the minibuffer if not focused when hit.
-Stolen from emacsredux.com."
-  (interactive)
-  (if (active-minibuffer-window)
-      (if (minibufferp)
-         (minibuffer-keyboard-quit)
-       (abort-recursive-edit))
-    (keyboard-quit)))
-
-(keymap-global-set "<remap> <keyboard-quit>" #'re/keyboard-quit) ; Make C-g better
-(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask
-(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files
-#+END_SRC
-* Version-control mode
-#+BEGIN_SRC emacs-lisp
-;; Versioning and Backups
-(defun re/vc-clone ()
-  "Interactively clone with vc-mode.
-Prompt for url and local dir."
-  (interactive)
-  (let* ((url (read-string "Repository URL: "))
-        (dir (read-string "Local Dir: " (file-name-base url))))
-    (vc-git-clone url dir nil)))
-
-(keymap-global-set "C-x v C" #'re/vc-clone)
-
-(defun re/vc-show-branches (&optional arg)
-  "Display all Git branches in a separate buffer.
-Remotes as well when arg."
-  (interactive "P")
-  (let ((default-directory (if (boundp 'vc-dir-directory)
-                              vc-dir-directory
-                            default-directory)))
-    (vc-git-command "*git-branches*"
-                   nil
-                   nil
-                   "branch"
-                   "--verbose"
-                   (when arg "--remotes"))
-    (pop-to-buffer "*git-branches*")
-    (goto-char (point-min))
-    (special-mode)))
-
-(keymap-global-set "C-x v b b" #'re/vc-show-branches)
-
-(defun re/vc-fetch (&optional arg)
-  "Interactively fetch with vc-mode.
-Allows separate fetch in addition to pull.  Only care about git.
-With arg, ask for remote, otherwise fetch all."
-  (interactive "P")
-  (let* ((default-directory (if (boundp 'vc-dir-directory)
-                               vc-dir-directory
-                             default-directory)))
-    (vc-git-command "*vc-fetch*"
-                   nil
-                   nil
-                   "fetch"
-                   (if arg
-                       (read-string "Fetch From: " "origin")
-                     "--all")
-                   "--verbose")
-    (pop-to-buffer "*vc-fetch*")
-    (goto-char (point-min))
-    (special-mode)))
-
-(keymap-global-set "C-x v f" #'re/vc-fetch)
-
-(setq vc-git-root-log-format
-      `("%d %h %ai %an: %s"
-       ;; The first shy group matches the characters drawn by --graph.
-       ;; We use numbered groups because `log-view-message-re' wants the
-       ;; revision number to be group 1.
-       ,(concat "^\\(?:[*/\\|]+\\)\\(?:[*/\\| ]+\\)?"
-                "\\(?2: ([^)]+) \\)?\\(?1:[0-9a-z]+\\) "
-                "\\(?4:[0-9]\\{4\\}-[0-9-]\\{4\\}[0-9\s+:-]\\{16\\}\\) "
-                "\\(?3:.*?\\):")
-       ((1 'log-view-message)
-        (2 'change-log-list nil lax)
-        (3 'change-log-name)
-        (4 'change-log-date))))
-
-(add-hook 'vc-dir-mode-hook
-         (lambda ()
-           (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches)
-           (keymap-set vc-dir-mode-map "f" #'re/vc-fetch)))
-
-(setq vc-make-backup-files nil
-      vc-handled-backends '(Git)
-      vc-git-diff-switches '("--patch-with-stat" "--histogram")
-      vc-git-log-switches '("--oneline" "--all" "--graph")
-      vc-git-log-edit-summary-target-len 50
-      vc-git-log-edit-summary-max-len 70
-      vc-find-revision-no-save t)
-#+END_SRC
-* Backups
-#+BEGIN_SRC emacs-lisp
-
-(setq backup-directory-alist `((".*" . "~/emacs-backups/"))
-      backup-by-copying t
-      delete-old-versions t
-      kept-new-versions 5
-      kept-old-versions 5)
-#+END_SRC
-* Any Lisp Repl
-#+BEGIN_SRC emacs-lisp
-;; Any Lisp Repl
-(defmacro re/send-on-close-paren (executor)
-  "Generalizes sending an execute on close paren.
- Interactively call `executor'.  For `executor', use whatever
- function is called by `<RET>' in the applicable REPL.  For a
- non-repl, use `newline' or similar."
-  `(lambda (&optional arg)
-     (interactive "p")
-     (insert-char 41 arg)
-     (call-interactively ,executor)))
-
-(defun re/sexp-drop-paren-p ()
-  "Returns t if sexp needs fewer parens to balance."
-  (< (car (syntax-ppss)) 0))
-
-(defun re/sexp-need-paren-p ()
-  "Returns t if sexp needs more parens to balance."
-  (> (car (syntax-ppss)) 0))
-
-(defun re/sexp-unbalanced-count ()
-  "Returns distance from balanced sexp."
-  (abs (car (syntax-ppss))))
-
-(defun re/balance-sexp ()
-  "Balance the sexp before point.
-Either delete, move forward, or add as many ')' as needed."
-  (let ((distance (re/sexp-unbalanced-count)))
-    (cond ((re/sexp-need-paren-p)
-          (if (looking-at ")")
-              (progn
-                (forward-char)
-                (re/balance-sexp))
-            (insert-char 41 distance)))
-         ((re/sexp-drop-paren-p)
-          (backward-delete-char distance)))))
-
-(defmacro re/balance-and-eval-sexp (executor)
-  "Balance the sexp before point, then call `executor'.
-Call `re/balance-sexp', then interactively call `executor'.  Bind
-this to ']' for the interlisp experience.  For `executor', use
-whatever function is called by `<RET>' in the applicable REPL.
-For a non-repl, use `newline' or similar."
-  `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor)))
-
-(defvar *re/lisp-mode-hooks*
-  '(emacs-lisp-mode-hook
-    lisp-mode-hook
-    sly-mode-hook
-    scheme-mode-hook
-    geiser-mode-hook
-    lisp-interaction-mode-hook))
-
-(dolist (hook *re/lisp-mode-hooks*)
-  (add-hook hook
-           (lambda ()
-             (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1))
-             (sedit-mouse-mode 1)
-             (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region)
-             (keymap-set lisp-mode-shared-map
-                         "C-M-S-q"
-                         #'sedit-auto-prettify-sexp)
-             (keymap-set lisp-mode-shared-map
-                         "]"
-                         (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp))
-             (keymap-set lisp-interaction-mode-map
-                         "]"
-                         (re/balance-and-eval-sexp #'eval-print-last-sexp)))))
-#+END_SRC
-* IELM
-Rarely used, but nice to have when I want it.
-#+BEGIN_SRC emacs-lisp
-;; IELM
-(add-hook 'ielm-mode-hook
-         (lambda ()
-           (keymap-set inferior-emacs-lisp-mode-map
-                       "C-l"
-                       #'comint-clear-buffer)
-           (let ((eval-function #'ielm-send-input))
-             (keymap-set inferior-emacs-lisp-mode-map
-                         ")"
-                         (re/send-on-close-paren eval-function))
-             (keymap-set inferior-emacs-lisp-mode-map
-                         "]"
-                         (re/balance-and-eval-sexp eval-function)))))
-#+END_SRC
-* Eshell
-#+BEGIN_SRC emacs-lisp
-;; Eshell
-(keymap-global-set "C-c e" #'eshell)
-
-(defun eshell-quit-or-delete-char (arg)
-  "Delete char if at one, quit eshell if on empty prompt.
-Stolen from https://depp.brause.cc/dotemacs"
-  (interactive "p")
-  (if (and (eolp) (looking-back eshell-prompt-regexp 0 t))
-      (eshell-life-is-too-much)
-    (delete-char arg)))
-
-(add-hook 'eshell-mode-hook
-         (lambda ()
-           (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char)
-           (let ((eval-function #'eshell-send-input))
-             (keymap-set eshell-mode-map
-                         ")"
-                         (re/send-on-close-paren eval-function))
-             (keymap-set eshell-mode-map
-                         "]"
-                         (re/balance-and-eval-sexp eval-function)))))
-#+END_SRC
-* C-mode
-#+BEGIN_SRC emacs-lisp
-;;; C-mode
-(dolist (mode-maps '(("\\.keymap\\'" . c-mode) ("\\.dtsi\\'" . c-mode)))
-  (add-to-list 'auto-mode-alist mode-maps t))
-
-(defun re/c-lineup-arglist-tabs-only (ignored)
-  "Line up argument lists by tabs, not spaces.
- Stolen from https://kernel.org/doc/html/v4.10/process/coding-style.html"
-  (let* ((anchor (c-langelem-pos c-syntactic-element))
-        (column (c-langelem-2nd-pos c-syntactic-element))
-        (offset (- (1+ column) anchor))
-        (steps (floor offset c-basic-offset)))
-    (* (max steps 1) c-basic-offset)))
-
-(add-hook 'c-mode-common-hook
-         (lambda ()
-           (c-add-style "linux-tabs-only"
-                        '("linux" (c-offsets-alist
-                                   (arglist-cont-nonempty
-                                    c-lineup-gcc-asm-reg
-                                    re/c-lineup-arglist-tabs-only))))))
-
-(add-hook 'c-mode-hook
-         (lambda ()
-           (setq c-backspace-function 'backward-delete-char)
-           (c-set-style "linux-tabs-only")))
-#+END_SRC
-* Auto-Revert
-#+BEGIN_SRC emacs-lisp
-;; Auto-Revert
-(global-auto-revert-mode t)
-(setq global-auto-revert-non-file-buffers t)
-#+END_SRC
-* Crash Handliŋ
-#+BEGIN_SRC emacs-lisp
-;; Crash handliŋ
-(setq attempt-stack-overflow-recovery nil
-      attempt-orderly-shutdown-on-fatal-signal nil)
-#+END_SRC
-* Abbrev-mode and skeletons
-#+BEGIN_SRC emacs-lisp
-;; Abbrev-mode and Skeletons
-(define-skeleton workorder-link
-  "part of a link to a workorder, just enter the number."
-  ""
-  "https://eservice.r717.net/index.php/PLC_workorders/store/"
-  _ -)
-
-(define-skeleton skel-org-block
-  "Add a source block to an org file."
-  ""
-  "#+BEGIN_SRC"
-  \n
-  _ -
-  \n
-  "#+END_SRC")
-
-(define-skeleton skel-org-block-elisp
-  "Add an elisp source block to an org file."
-  ""
-  "#+BEGIN_SRC emacs-lisp"
-  \n
-  _ -
-  \n
-  "#+END_SRC")
-
-(setq save-abbrevs 'silently)
-
-(dolist (hook '(org-mode-hook howm-mode-hook))
-  (add-hook hook #'abbrev-mode))
-#+END_SRC
-* Customization Framework
-Disable it by making it save to a temp file (stolen from prot)
-#+BEGIN_SRC emacs-lisp
-(setq custom-file (make-temp-file "emacs-custom-"))
-#+END_SRC
-* Footer
-#+BEGIN_SRC emacs-lisp
-;;; config.el ends here
-#+END_SRC
diff --git a/config.org b/config.org
new file mode 100644 (file)
index 0000000..3b1a4bc
--- /dev/null
@@ -0,0 +1,1362 @@
+#+TITLE: Emacs literate config
+#+STARTUP: noindent
+#+PROPERTY: header-args emacs-lisp :tangle yes
+
+* Header
+#+BEGIN_SRC emacs-lisp
+;;; config.el --- Emacs Configuration  -*- lexical-binding: t; -*-
+
+;; This file is not part of GNU emacs
+
+;;; Code:
+
+#+END_SRC
+* Load libraries
+Libraries Not from the package manager
+#+BEGIN_SRC emacs-lisp
+  (dolist (path '("sedit-mouse/" "themes/" "re/"))
+      (add-to-list 'load-path (concat user-emacs-directory path)))
+
+  (dolist (file '(pass-alike eng-paper-theme sedit-mouse))
+       (require file))
+#+END_SRC
+* OS specific stuff
+#+BEGIN_SRC emacs-lisp
+  (setq w32-recognize-altgr 'nil)
+
+  (unless (equal system-type 'windows-nt)
+    (require 're-mu4e)
+    (setq trash-directory "~/Trash/")
+    (defun doas ()
+      "Use TRAMP to reopen the current buffer as root using doas."
+      (interactive)
+      (when buffer-file-name
+       (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))
+    (defun sudo ()
+      "Use TRAMP to reopen the current buffer as root using sudo."
+      (interactive)
+      (when buffer-file-name
+       (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))))
+
+#+END_SRC
+* Add melpa, and reduce the declarations by setting defaults
+#+BEGIN_SRC emacs-lisp
+(require 'package)
+
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+
+(setq use-package-always-ensure t
+      use-package-always-defer t)
+#+END_SRC
+* Corfu
+#+BEGIN_SRC emacs-lisp
+(use-package corfu
+  :demand
+  t
+  :custom
+  (corfu-auto t)
+  (corfu-auto-delay 0)
+  (corfu-auto-prefix 1)
+  :config
+  (global-corfu-mode))
+
+(use-package corfu-popupinfo
+  :ensure
+  nil ; part of corfu
+  :after
+  corfu
+  :hook
+  (corfu-mode . corfu-popupinfo-mode)
+  :custom
+  (corfu-popupinfo-delay '(1.0 . 0.01)) ; start after one second, fast refresh once on
+  (corfu-popupinfo-hide nil)
+  :config
+  (corfu-popupinfo-mode))
+#+END_SRC
+* Expand Region
+#+BEGIN_SRC emacs-lisp
+(use-package expand-region
+  :bind
+  (("C-=" . er/expand-region)))
+#+END_SRC
+* Aggressive Indent
+#+BEGIN_SRC emacs-lisp
+(use-package aggressive-indent)
+#+END_SRC
+* Magit
+No longer needed, since I defer by default.
+* Page Break Lines
+Needs to be demanded so I don't have to manually load it
+#+BEGIN_SRC emacs-lisp
+(use-package page-break-lines
+  :demand
+  t
+  :config
+  (global-page-break-lines-mode))
+#+END_SRC
+* AucTeX and pdftools
+Make AucTeX use pdftools, prompt for master file, synctex, etc.  Be sure to run =pdf-tools-install= before first use.
+#+BEGIN_SRC emacs-lisp
+(use-package pdf-tools)
+
+(use-package auctex
+  :config
+  (setq-default TeX-master nil)
+  (add-to-list 'TeX-view-program-selection '(output-pdf "PDF Tools"))
+  (setq TeX-auto-save t
+       TeX-parse-self t
+       TeX-PDF-mode t
+       TeX-source-correlate-start-server t)
+  (add-hook 'TeX-after-compilation-finished-functions
+           #'TeX-revert-document-buffer))
+#+END_SRC
+* CSV Mode
+#+BEGIN_SRC emacs-lisp
+(use-package csv-mode
+  :config
+  (add-hook 'csv-mode-hook 'csv-align-mode))
+#+END_SRC
+* Markdown Mode
+Make markdown act more like org when I'm forced to use it
+#+BEGIN_SRC emacs-lisp
+(use-package markdown-mode
+  :config
+  (setq markdown-special-ctrl-a/e t)
+  :bind
+  (:map markdown-mode-map
+       ("M-<right>" . markdown-demote)
+       ("M-<left>" . markdown-promote)
+       ("M-<up>" . markdown-move-up)
+       ("M-<down>" . markdown-move-down)
+       ("C-M-u" . markdown-up-heading)
+       ("C-M-b" . markdown-outline-previous-same-level)
+       ("C-M-f" . markdown-outline-next-same-level)
+       ("C-M-p" . markdown-outline-previous)
+       ("C-M-n" . markdown-outline-next)))
+
+(use-package edit-indirect :after 'markdown-mode)
+#+END_SRC
+* Sly
+#+BEGIN_SRC emacs-lisp
+  (defun re/sly-repl-new-frame (&optional arg)
+    "Start a SLY repl in a new frame."
+    (interactive "P")
+    (re/open-with-new-frame "SLY" #'sly))
+
+  (defun re/sly-quit-current-lisp ()
+    "Quit the current lisp repl connection without prompting."
+    (interactive)
+    (sly-quit-lisp nil nil))
+
+  (defun re/sly-connect-stump (&optional arg)
+    "Connect to my typical stumpwm instance."
+    (interactive "P")
+    (sly-connect "localhost" 4004))
+
+  (use-package sly
+    :config
+    (setq inferior-lisp-program "sbcl"
+       sly-net-coding-system 'utf-8-unix
+       sly-command-switch-to-existing-lisp 'always)
+    (let ((core (expand-file-name "~/sbcl.core-for-sly")))
+      (when (file-exists-p core)
+       (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core))))))
+    :bind
+    (:map sly-mrepl-mode-map
+       (")" . (lambda () (interactive) (re/send-on-close-paren #'sly-mrepl-return)))
+       ("]" . (lambda () (interactive) (re/balance-and-eval-sexp #'sly-mrepl-return)))
+       ("C-c q" . re/sly-quit-current-lisp)))
+#+END_SRC
+** Eldoc settings
+Sly really doesn't play well with elodc in the minibuffer, so here are some settings to make it better.
+#+BEGIN_SRC emacs-lisp
+(add-to-list 'display-buffer-alist
+            '("^\\*eldoc" display-buffer-in-direction
+              (direction . 'down)
+              (window-height . 4)))
+(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer
+(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed
+#+END_SRC
+* Geiser
+#+BEGIN_SRC emacs-lisp
+  (use-package geiser
+    :config
+    (if (equal system-type 'windows-nt)
+       (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))
+      (setq geiser-chicken-binary "csi -:c"))
+    (setq scheme-program-name geiser-chicken-binary
+       geiser-active-implementations '(chicken))
+    (add-hook 'scheme-mode-hook 'geiser-mode)
+    :bind
+    (:map geiser-repl-mode-map
+       (")" . (lambda () (interactive) (re/send-on-close-paren #'geiser-repl-maybe-send)))
+       ("]" . (lambda () (interactive) (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))))
+
+  (use-package geiser-chicken :after 'geiser)
+#+END_SRC
+* Forth
+** TODO Try out this mode for gforth
+#+BEGIN_SRC emacs-lisp
+(use-package forth-mode)
+#+END_SRC
+* ORG
+** Load in the package and set bindings
+#+BEGIN_SRC emacs-lisp
+  (use-package org
+    :config
+    (require 'org-mouse)
+    :bind
+    (("C-c l" . org-store-link)
+     ("C-c a" . org-agenda)
+     ("C-c c" . org-capture)
+     ("C-c b" . org-switchb)
+     ("<f10>" . org-clock-out)
+     ("<f2>" . org-clock-goto)
+     :map org-mode-map
+     ("M-<right>" . org-shiftmetaright)
+     ("M-<left>" . org-shiftmetaleft)
+     ("M-S-<right>" . org-metaright)
+     ("M-S-<left>" . org-metaleft)
+     ("C-M-h" . org-mark-subtree)
+     ("C-M-u" . org-up-element)
+     ("C-M-d" . org-down-element)
+     ("C-M-b" . org-backward-heading-same-level)
+     ("C-M-f" . org-forward-heading-same-level)
+     ("C-M-p" . org-previous-visible-heading)
+     ("C-M-n" . org-next-visible-heading)
+     ("<f9>" . org-clock-in)))
+
+  (use-package org-transclusion
+    :after
+    org
+    :bind
+    (("C-c t" . org-transclusion-mode)))
+#+END_SRC
+** Configuration
+*** General options
+#+BEGIN_SRC emacs-lisp
+  (with-eval-after-load 'org-mode (add-to-list 'org-export-backends 'md))
+
+  (setq org-startup-indented nil
+       org-indent-indentation-per-level 1
+       org-startup-folded 'fold
+       org-startup-with-inline-images t
+       org-cycle-inline-images-display t
+       org-cycle-separator-lines 0
+       org-blank-before-new-entry '((heading) (plain-list-item . auto))
+       org-M-RET-may-split-line nil
+       org-treat-S-cursor-todo-selection-as-state-change nil
+       org-treat-insert-todo-heading-as-state-change nil
+       org-table-export-default-format "orgtbl-to-csv"
+       org-list-allow-alphabetical t
+       org-fold-catch-invisible-edits 'show-and-error
+       org-ellipsis "↴"
+       org-tags-column 0
+       org-reverse-note-order t
+       org-enforce-todo-dependencies t
+       org-enforce-todo-checkbox-dependencies t
+       org-fontify-done-headline nil
+       org-fontify-todo-headline nil
+       org-goto-interface 'outline-path-completion
+       org-outline-path-complete-in-steps nil
+       org-goto-auto-isearch nil
+       org-special-ctrl-a/e t
+       org-special-ctrl-k t
+       org-return-follows-link t
+       org-yank-adjusted-subtrees t
+       org-src-window-setup 'current-window
+       org-src-preserve-indentation t)
+#+END_SRC
+*** Time Clocking
+#+BEGIN_SRC emacs-lisp
+(org-clock-persistence-insinuate)
+(setq org-clock-history-length 10
+      org-clock-in-resume t
+      org-clock-out-remove-zero-time-clocks t
+      org-clock-persist t
+      org-clock-persist-query-resume nil
+      org-clock-report-include-clocking-task t
+      org-time-stamp-rounding-minutes '(1 1))
+#+END_SRC
+*** Agenda and Capture
+#+BEGIN_SRC emacs-lisp
+(add-hook 'org-agenda-mode-hook #'hl-line-mode)
+
+(setq org-agenda-files (append '("~/org/")
+                        (file-expand-wildcards "~/projects/*/"))
+      org-refile-targets '((nil :maxlevel . 9)
+                          (org-agenda-files :maxlevel . 9))
+      org-refile-use-outline-path 'file
+      org-refile-allow-creating-parent-nodes 'confirm
+      org-tag-alist '(("call" . ?c)
+                     ("email" . ?e)
+                     ("errand" . ?r)
+                     ("jobpc" . ?j)
+                     ("license" . ?l)
+                     ("meeting" . ?m)
+                     ("open" . ?o))
+      org-tags-exclude-from-inheritance '("open")
+      org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)")
+                         (sequence "MEETING(m)" "|" "MET(M)"))
+      org-todo-keyword-faces '(("WAITING" :foreground "#e85400" :weight bold)
+                              ("MEETING" :foreground "#315e9a" :weight bold))
+      org-agenda-restore-windows-after-quit t
+      org-agenda-start-on-weekday nil
+      org-agenda-compact-blocks t
+      org-agenda-span 'day
+      org-deadline-warning-days 30
+      org-agenda-window-setup 'current-window
+      org-agenda-time-grid '((daily today remove-match)
+                            (600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900)
+                            " ――――― "
+                            "")
+      org-agenda-tags-column 50
+      org-agenda-skip-additional-timestamps-same-entry t
+      org-agenda-skip-deadline-if-done t
+      org-agenda-skip-scheduled-if-done t
+      org-agenda-prefix-format '((agenda . "  %?-12t% s")
+                                (todo . "  ")
+                                (tags . "  ")
+                                (search . "  "))
+      org-agenda-scheduled-leaders '("BOOKED: " "Booked %2d d. ago: ")
+      org-agenda-deadline-leaders '("DEADLINE: " "In %3d d.: " "%2d d. ago: ")
+      org-read-date-prefer-future 'time
+      org-agenda-custom-commands '(("f" "Maybe Someday" tags "someday" ((org-agenda-overriding-header "SOMEDAY:")))
+                                  ("i" "Inbox" tags "inbox" ((org-agenda-overriding-header "INBOX:")))
+                                  ("l" "Licenses" tags "license" ((org-agenda-overriding-header "LICENSES:")))
+                                  ("n" "Next Actions" tags-todo "-recurring/TODO" ((org-agenda-overriding-header "NEXT:")))
+                                  ("p" "JobPCs" tags "jobpc" ((org-agenda-overriding-header "JOB PCS:")))
+                                  ("u" "Undertakings" tags "open" ((org-agenda-overriding-header "UNDERTAKINGS:")))
+                                  ("w" "Waiting" todo "WAITING" ((org-agenda-overriding-header "WAITING:")))
+                                  ("o" "Overview" ((agenda "")
+                                                   (tags "inbox" ((org-agenda-overriding-header "\nINBOX:")))
+                                                   (tags-todo "-recurring/TODO" ((org-agenda-overriding-header "\nNEXT:")
+                                                                                 (org-agenda-max-entries 10)))
+                                                   (tags "open" ((org-agenda-overriding-header "\nUNDERTAKINGS:")))
+                                                   (todo "WAITING" ((org-agenda-overriding-header "\nWAITING:"))))))
+      org-agenda-start-with-log-mode t
+      org-agenda-log-mode-items '(closed clock state)
+      org-log-done 'time
+      org-log-into-drawer nil
+      org-log-state-notes-insert-after-drawers t
+      org-log-state-notes-into-drawer nil
+      org-capture-templates '(("i" "Inbox" entry
+                              (file "gtd.org")
+                              "* %^{Description} :inbox:\n%U\n%?"
+                              :prepend t
+                              :clock-in t
+                              :clock-resume t)
+                             ("m" "Meeting" entry
+                              (file "gtd.org")
+                              "* MEETING %^{Description} :meeting:\n%^{Scheduled:}T\n%?"
+                              :prepend t
+                              :clock-in t
+                              :clock-resume t)
+                             ("p" "Phone Call" entry
+                              (file "gtd.org")
+                              "* %^{Description} :call:\n%U\n%?"
+                              :prepend t
+                              :clock-in t
+                              :clock-resume t)))
+#+END_SRC
+*** IDs
+#+BEGIN_SRC emacs-lisp
+(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
+      org-id-method 'ts
+      org-clone-delete-id t
+      org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
+                                           org-attach-id-uuid-folder-format))
+
+(defun re/org-auto-generate-ids-in-file ()
+  "Add ID properties to all headlines in the current
+ file which do not already have one."
+  (interactive)
+  (org-map-entries 'org-id-get-create))
+
+(defun re/org-save-all ()
+  "Save all `org-agenda-files' without user confirmation."
+  (interactive)
+  (message "Saving all org-agenda-files buffers...")
+  (save-some-buffers t
+                    (lambda ()
+                      (when (member (buffer-file-name) org-agenda-files) t)))
+  (message "Saving all org-agenda-files buffers... done"))
+
+(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))
+#+END_SRC
+*** Archiving
+#+BEGIN_SRC emacs-lisp
+(defun re/org-archive-all ()
+  "Archive all tasks marked `DONE' in agenda files"
+  (interactive)
+  (message "Archiving all completed tasks in org-agenda-files...")
+  (org-map-entries (lambda ()
+                    (org-archive-subtree)
+                    (setq org-map-continue-from (org-element-property
+                                                 :begin
+                                                 (org-element-at-point))))
+                  "/DONE"
+                  'agenda)
+  (message "Archiving all completed tasks in org-agenda-files... done"))
+
+(setq org-archive-location (concat "~/org/old.org_keep::datetree/")
+      org-agenda-text-search-extra-files '(agenda-archives))
+
+(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))
+#+END_SRC
+* HOWM
+On-again, off-again relationship with this one
+** Load package and add bindings
+#+BEGIN_SRC emacs-lisp
+  (use-package howm
+    :bind
+    (("<f6>" . howm-menu)
+     ("S-<f6>" . re/howm-menu-new-frame)
+     :map howm-mode-map
+     ("C-c , k" . re/howm-create-keyword)
+     ("C-c , =" . howm-narrow-to-memo)))
+#+END_SRC
+** Config
+*** General settings
+#+BEGIN_SRC emacs-lisp
+(setq howm-template '("= %title%cursor #inbox\n%date %file\n\n"
+                     "= %title%cursor #meeting\n%date %file\n\nAttendees: \n"
+                     "= @%title%cursor\n%date %file\n\n")
+      howm-keyword-file "~/howm/.howm-keys"
+      howm-history-file "~/howm/.howm-history"
+      howm-menu-file "~/.emacs.d/0000-00-00-000000.txt"
+      howm-file-name-format "%Y%m%dT%H%M%S.txt"
+      howm-keyword-case-fold-search t
+      howm-remember-insertion-format "%s"
+      howm-menu-todo-num 10)
+
+(defun re/howm-menu-new-frame (&optional arg)
+  "Show the howm menu in a new frame"
+  (interactive "P")
+  (re/open-with-new-frame "HOWM" #'howm-menu))
+
+(defun re/howm-create-keyword ()
+  "Reads a keyword from the minibuffer and appends it to the keywords file."
+  (interactive)
+  (append-to-file (concat (read-string "New Keyword: ")
+                         "\n")
+                 nil
+                 howm-keyword-file
+                 "\n"))
+#+END_SRC
+*** Menu config
+#+BEGIN_SRC emacs-lisp
+;; add entries in howm-menu (press enter on the text)
+(defun re/howm-menu-legend ()
+  (cl-labels ((p (text face) (propertize text 'font-lock-face face)))
+    (concat (format "Top %s" howm-menu-todo-num)
+           " "
+           (p "!Deadline" howm-reminder-deadline-face)
+           "/"
+           (p "+ToDo" howm-reminder-todo-face)
+           "/"
+           (p "@Schedule" howm-reminder-schedule-face)
+           "/"
+           (p "~Defer" howm-reminder-defer-face)
+           "/"
+           (p "-Reminder" howm-reminder-normal-face)
+           " Entries:")))
+
+(with-eval-after-load 'howm
+  (dolist (aldr-additions '(("\\[Mtg\\]" (lambda (&optional dummy) (howm-create 2)))
+                           ("\\[Person\\]" (lambda (&optional dummy) (howm-create 3)))))
+    (add-to-list 'action-lock-default-rules aldr-additions t))
+  (add-to-list 'howm-menu-allow 're/howm-menu-legend)
+  ;; add coloring for custom "waiting" state
+  (add-to-list 'howm-reminder-font-lock-keywords
+              `(,(howm-reminder-regexp "[w]") (0 howm-reminder-defer-face prepend))
+              t))
+
+(dolist (hooks '(after-save-hook howm-mode-hook))
+  (add-hook hooks 'howm-mode-set-buffer-name))
+#+END_SRC
+
+* Trashed
+Shows the trash file as a dired buffer
+#+BEGIN_SRC emacs-lisp
+(use-package trashed
+  :config
+  (setq trashed-action-confirmer 'y-or-n-p
+       trashed-use-header-line t
+       trashed-sort-key '("Date deleted" . t)
+       trashed-date-format "%Y-%m-%d %H:%M:%S"))
+#+END_SRC
+* Editing
+** UNIX/vi-like bindings
+=C-h=, =C-w=, =C-u=, et. al to work as I expect.  Some functions get re-bound when these take over a default.
+#+BEGIN_SRC emacs-lisp
+  (defun re/open-line-below (n)
+    "Creates a new empty line below the current line and moves to it."
+    (interactive "*p")
+    (end-of-line)
+    (open-line n)
+    (next-line 1)
+    (indent-for-tab-command))
+
+  (keymap-global-set "C-o" #'re/open-line-below)
+
+  (defun re/open-line-above (n)
+    "Creates a new empty line above the current line."
+    (interactive "*p")
+    (beginning-of-line)
+    (open-line n)
+    (indent-for-tab-command))
+
+  (keymap-global-set "M-o" #'re/open-line-above)
+
+  (defun re/kill-bword-or-region (&optional arg)
+    "Kill region if active, otherwise kill back one word."
+    (interactive "p")
+    (if (use-region-p)
+       (kill-region (region-beginning) (region-end))
+      (backward-kill-word arg)))
+
+  (keymap-global-set "C-w" #'re/kill-bword-or-region)
+  (keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards
+  (keymap-global-set "C-S-U" #'universal-argument)
+  (keymap-set key-translation-map "C-h" "<DEL>") ; Rather F1 for help, also C-S-H works
+  (keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way
+#+END_SRC
+** Commenting and defun-level bindings
+#+BEGIN_SRC emacs-lisp
+  (defun re/comment-dwim (&optional arg)
+    "Comment region if active, otherwise comment line.
+  Stolen from https://depp.brause.cc/dotemacs"
+    (interactive "P")
+    (if (use-region-p)
+       (comment-or-uncomment-region (region-beginning) (region-end))
+      (comment-line arg)))
+
+  (keymap-global-set "M-;" #'re/comment-dwim)
+
+  (defun re/comment-defun (&optional arg)
+    "Mark a defun and comment it out.
+  Return to initial position after.  Arg works on `mark-defun'."
+    (interactive "P")
+    (save-excursion (mark-defun arg)
+                   (comment-region (region-beginning) (region-end))))
+
+  (keymap-global-set "C-M-;" #'re/comment-defun)
+
+  (defun re/kill-defun (&optional arg)
+    "Mark a defun and kill it.
+  Arg works on `mark-defun'."
+    (interactive "P")
+    (mark-defun arg)
+    (kill-region (region-beginning) (region-end)))
+
+  (keymap-global-set "C-M-S-K" #'re/kill-defun)
+#+END_SRC
+
+** Misc QOL bindings
+#+BEGIN_SRC emacs-lisp
+(keymap-global-set "<insert>" nil) ; I keep toggliŋ overwrite-mode haply
+(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes
+(keymap-global-set "C-S-K" #'kill-whole-line)
+(keymap-global-set "C-S-d" #'delete-pair)
+(keymap-global-set "C-z" #'zap-up-to-char)
+(keymap-global-set "C-c s" #'sort-lines)
+(keymap-global-set "<remap> <capitalize-word>" #'capitalize-dwim) ; M-c
+(keymap-global-set "<remap> <downcase-word>" #'downcase-dwim) ; M-l
+(keymap-global-set "<remap> <upcase-word>" #'upcase-dwim) ; M-u
+#+END_SRC
+* Tabs
+I want *TABS*, not spaces, dammit.  Globally overwrite the tab key to insert the tab character.  This makes it so that many things (completion) will have to be triggered with =C-i= instead, but I don't think it's necessarily bad to have things like that on a control combo instead of overloading the tab key at the expense of being able to actually insert tabs.
+#+BEGIN_SRC emacs-lisp
+;; Tabs
+(setq-default indent-tabs-mode t
+             tab-width 8
+             backward-delete-char-untabify-method nil)
+
+(advice-add 'indent-to :around
+           (lambda (orig-fun column &rest args)
+             (when indent-tabs-mode
+               (setq column (* tab-width (round column tab-width))))
+             (apply orig-fun column args)))
+
+(dolist (indent-level '(c-basic-offset cperl-indent-level LaTeX-indent-level))
+  (defvaralias indent-level 'tab-width))
+
+(defun Tab (width)
+  "Give me a function analagous to the Acme `Tab' command"
+  (interactive)
+  (setq-local tab-width width))
+
+(keymap-global-set "<tab>" (lambda () (interactive) (insert "\t")))
+#+END_SRC
+* Buffer dealiŋ
+#+BEGIN_SRC emacs-lisp
+;; Buffer dealiŋ
+(setq-default indicate-empty-lines t
+             truncate-lines t
+             fill-column 78)
+
+(dolist (hook '(text-mode-hook LaTeX-mode-hook))
+  (add-hook hook #'visual-line-mode))
+
+(blink-cursor-mode -1)
+(delete-selection-mode t)
+
+(setq delete-by-moving-to-trash t
+      delete-pair-blink-delay 0
+      use-short-answers t
+      use-file-dialog nil
+      echo-keystrokes 0.1
+      eldoc-idle-delay 0
+      read-buffer-completion-ignore-case t
+      history-delete-duplicates t
+      disabled-command-function nil
+      save-interprogram-paste-before-kill t
+      confirm-kill-processes nil)
+
+(keymap-global-set "C-x M-f" #'find-file-at-point)
+(keymap-global-set "C-x C-b" #'buffer-menu)
+(keymap-global-set "C-x M-b" #'buffer-menu-other-window)
+(keymap-global-set "C-x k" #'kill-current-buffer)
+(keymap-global-set "C-x K" #'kill-buffer)
+#+END_SRC
+* Recentering and page-by-page navigation
+#+BEGIN_SRC emacs-lisp
+(setq recenter-positions '(2 middle -3))
+
+(defun re/recenter-advice (&rest _)
+  "Recenter to page start."
+  (when (called-interactively-p 'any) (recenter 2)))
+
+(dolist (binding '(backward-page forward-page))
+  (advice-add binding :after #'re/recenter-advice))
+
+(keymap-global-set "C-x C-n" #'forward-page)
+(keymap-global-set "C-x C-p" #'backward-page)
+(keymap-global-set "<next>" #'forward-page)
+(keymap-global-set "<prior>" #'backward-page)
+#+END_SRC
+* Macro to open something in its own named frame
+Start a repl in a new frame, open dired in a new frame, etc. etc.
+#+BEGIN_SRC
+(defmacro re/open-with-new-frame (frname function)
+  "Run the function in its own named frame."
+  `(progn
+     (select-frame (make-frame '((name . ,(eval frname)))))
+     (call-interactively ,function)))
+#+END_SRC
+* Motion
+#+BEGIN_SRC emacs-lisp
+;; Motion
+(defun re/scratch-only ()
+  "Bring up the scratch buffer as the only visible buffer."
+  (interactive)
+  (scratch-buffer)
+  (delete-other-windows))
+
+(keymap-global-set "<f5>" #'scratch-buffer)
+(keymap-global-set "S-<f5>" #'re/scratch-only)
+
+(defun re/other-window-or-split-window (&optional window)
+  "Go to other window or split sensibly."
+  (interactive)
+  (if (= (count-windows) 1)
+      (funcall split-window-preferred-function window)
+    (other-window 1)))
+
+(keymap-global-set "C-M-o" #'re/other-window-or-split-window)
+
+(defun re/smart-beginning-of-line ()
+  "Move point to first non-whitespace character or `beginning-of-visual-line'.
+If point was already at that position, call `back-to-indentation'.
+Called a third time, move point back to `beginning-of-line'.
+If in org-mode, call `org-beginning-of-line' first."
+  (interactive "^")
+  (let ((oldpos (point)))
+    (if (equal major-mode 'org-mode)
+       (org-beginning-of-line)
+      (progn
+       (when visual-line-mode (beginning-of-visual-line 1))
+       (skip-syntax-forward " " (line-end-position))
+       (backward-prefix-chars)))
+    (and (= oldpos (point))
+        (let ((newpos (point)))
+          (back-to-indentation)
+          (and (= newpos (point)) (beginning-of-line))))))
+
+(keymap-global-set "<remap> <move-beginning-of-line>" #'re/smart-beginning-of-line)
+(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line)
+
+(defun re/smart-end-of-line ()
+  "Move point to the end of the visual line.
+ If point was already at that position, call `move-end-of-line'.
+If in org-mode, call `org-end-of-line' first."
+  (interactive "^")
+  (let ((oldpos (point)))
+    (if (equal major-mode 'org-mode)
+       (org-end-of-line)
+      (when visual-line-mode
+       (end-of-visual-line 1)))
+    (and (= oldpos (point)) (move-end-of-line nil))))
+
+(keymap-global-set "<remap> <move-end-of-line>" #'re/smart-end-of-line)
+(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line)
+
+(defun re/goto-line ()
+  "Show line numbers before going to line, then hide them again."
+  (interactive)
+  (display-line-numbers-mode 1)
+  (call-interactively 'goto-line)
+  (display-line-numbers-mode -1))
+
+(keymap-global-set "<remap> <goto-line>" #'re/goto-line)
+(keymap-global-set "<home>" #'beginning-of-buffer)
+(keymap-global-set "<end>" #'end-of-buffer)
+(keymap-global-set "C-." #'next-buffer)
+(keymap-global-set "C-," #'previous-buffer)
+(keymap-global-set "C-<tab>" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers
+(keymap-global-set "<mouse-4>" #'previous-buffer) ; Back button
+(keymap-global-set "<mouse-5>" #'next-buffer) ; Forward button
+;; Disable M-mouse for window manager bindings
+(keymap-global-unset "M-<down-mouse-1>")
+(keymap-global-unset "M-<drag-mouse-1>")
+(keymap-global-unset "M-<mouse-1>")
+(keymap-global-unset "M-<mouse-2>")
+(keymap-global-unset "M-<mouse-3>")
+#+END_SRC
+* Search
+#+BEGIN_SRC emacs-lisp
+;; Search
+(defun re/add-region-to-search-ring ()
+  (when (use-region-p)
+    (add-to-history 'search-ring
+                   (buffer-substring (region-beginning) (region-end)))
+    (deactivate-mark)))
+
+(defun re/isearch-forward-use-region ()
+  "Search text in region if active, otherwise normal forward search."
+  (interactive)
+  (re/add-region-to-search-ring)
+  (isearch-forward))
+
+(keymap-global-set "C-s" #'re/isearch-forward-use-region)
+
+(defun re/isearch-backward-use-region ()
+  "Search text in region if active, otherwise normal backward search."
+  (interactive)
+  (re/add-region-to-search-ring)
+  (isearch-backward))
+
+(keymap-global-set "C-r" #'re/isearch-backward-use-region)
+
+(defun re/exchange-point-and-mark-maybe-activate (arg)
+  "Call `exchange-point-and-mark' but don't activate the region.
+Stolen from https://www.masteringemacs.org/article/fixing-mark-commands-transient-mark-mode"
+  (interactive "P")
+  (exchange-point-and-mark (if (and transient-mark-mode (not mark-active))
+                              (not arg)
+                            arg)))
+
+(keymap-global-set "<remap> <exchange-point-and-mark>" #'re/exchange-point-and-mark-maybe-activate)
+
+(keymap-global-set "M-s ." #'isearch-forward-thing-at-point)
+(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point)
+(keymap-global-set "M-%" #'replace-regexp)
+(keymap-global-set "C-%" #'replace-string)
+(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff)
+(keymap-global-set "C-S-S" #'isearch-forward-regexp)
+(keymap-global-set "C-S-R" #'isearch-backward-regexp)
+#+END_SRC
+* Recent Files/Buffers
+#+BEGIN_SRC emacs-lisp
+;; Recent Files/Buffers
+(midnight-mode t)
+(setq clean-buffer-list-delay-general 1)
+(dolist (never-re '("\\` \\*tramp/.*\\'"
+                   "\\` \\*eshell.*\\'"))
+  (add-to-list 'clean-buffer-list-kill-never-regexps never-re))
+(save-place-mode 1)
+(recentf-mode 1)
+#+END_SRC
+* File Handling
+#+BEGIN_SRC emacs-lisp
+;; File Handling
+(defun re/rename-current-buffer-file nil
+  "Renames the current buffer and the file it is visiting."
+  (interactive)
+  (let ((name (buffer-name))
+       (filename (buffer-file-name)))
+    (if (not (and filename (file-exists-p filename)))
+       (error "Buffer '%s' is not visiting a file!" name)
+      (let ((new-name (read-file-name "New name: " filename)))
+       (if (get-buffer new-name)
+           (error "A buffer named '%s' already exists!" new-name)
+         (rename-file filename new-name 1)
+         (rename-buffer new-name)
+         (set-visited-file-name new-name)
+         (set-buffer-modified-p nil)
+         (message "File '%s' successfully renamed to '%s'"
+                  name
+                  (file-name-nondirectory new-name)))))))
+
+(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file)
+
+(defun re/get-line-from-file (file-path line-number)
+  "Return the specified LINE-NUMBER from FILE-PATH as a string.
+Start from bottom if given a negative line number."
+  (with-temp-buffer
+    (insert-file-contents file-path)
+    (if (< line-number 0)
+       (progn
+         (goto-char (point-max))
+         (forward-line line-number))
+      (progn
+       (goto-char (point-min))
+       (forward-line (1- line-number))))
+    (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+
+(defun re/get-file-modified-time (filepath)
+  (interactive)
+  (format-time-string "%Y-%m-%d-%H%M"
+                     (file-attribute-modification-time (file-attributes filepath))))
+
+(defun re/filename-inject-mod-time (filepath)
+  (interactive)
+  (concat (file-name-sans-extension filepath)
+         "_"
+         (re/get-file-modified-time filepath)
+         (file-name-extension filepath t)))
+
+(defun re/copy-with-mod-time (&optional filepath)
+  (interactive)
+  (let ((filepath (if (eq major-mode 'dired-mode)
+                     (dired-get-filename t)
+                   (when (null filepath)
+                     (read-file-name "File to copy with datestring: "
+                                     default-directory
+                                     nil
+                                     t
+                                     nil)))))
+    (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t)))
+#+END_SRC
+* Dired
+#+BEGIN_SRC emacs-lisp
+;; Dired
+(defun re/dired-display-direction ()
+  "In dired mode, visit the file at the cursor in the right/below/left/above window."
+  (interactive)
+  (let* ((file-or-dir (dired-get-file-for-visit)) ;; get the file at cursor
+        (buffer (find-file-noselect file-or-dir))) ;; load the file into a buffer
+    (let ((window ;; figure out the window to use
+          (cond ((get-buffer-window buffer (selected-frame)))
+                ((window-in-direction 'right)) ;; try window in each direction
+                ((window-in-direction 'below)) ;; and default to right
+                ((window-in-direction 'left))  ;; if no window found.
+                ((window-in-direction 'above))
+                (t (split-window (selected-window) nil 'right)))))
+      (window--display-buffer buffer window 'window nil)
+      window)))
+
+(defun re/dired-new-frame ()
+  "Open dired in a new frame."
+  (interactive)
+  (re/open-with-new-frame "DIRED"
+                         #'(lambda () (interactive) (dired default-directory))))
+
+(keymap-global-set "<f8>" #'re/dired-new-frame)
+
+(defun re/dired-find-marked-files ()
+  "Open all marked files from `dired'."
+  (interactive)
+  (mapc #'find-file (reverse (dired-get-marked-files))))
+
+(defun re/dired-sort ()
+  "Change sort order of dired dir."
+  (interactive)
+  (let ((smenu '(("name" . "-Ahl")
+                ("mdate" . "-Ahlt")
+                ("adate" . "-Ahltu")
+                ("size" . "-AhlS")
+                ("dir" . "-Ahl --group-directories-first")))
+       ssortBy)
+    (setq ssortBy (completing-read "Sort by (default name):"
+                                  smenu
+                                  nil
+                                  t
+                                  nil
+                                  nil
+                                  (caar smenu)))
+    (dired-sort-other (cdr (assoc ssortBy smenu)))))
+
+(defun re/open-file-external (file)
+  "Open a file in an external program."
+  (interactive)
+  (let ((process-connection-type nil))
+    (cond ((eq system-type 'windows-nt)
+          (w32-shell-execute "open"
+                             (replace-regexp-in-string "/" "\\\\" file t t)))
+         ((eq system-type 'gnu/linux)
+          (start-process "" nil "xdg-open" file))
+         (t (error "Unable to automatically open this file")))))
+
+(defun re/dired-open-externally ()
+  "Open the file at point in an external program."
+  (interactive)
+  (re/open-file-external (dired-get-filename)))
+
+(defun re/dired-open-marked-externally ()
+  "Open all marked files from `dired' in an external program."
+  (interactive)
+  (mapc #'re/open-file-external (reverse (dired-get-marked-files))))
+
+(setq dired-listing-switches "-Ahl"
+      dired-vc-rename-file t
+      dired-auto-revert-buffer t
+      dired-hide-details-hide-symlink-targets nil
+      dired-kill-when-opening-new-dired-buffer t)
+
+(add-hook 'dired-mode-hook
+         (lambda ()
+           (progn
+             (keymap-set dired-mode-map
+                         "o"
+                         #'re/dired-display-direction)
+             ;; Rename r,R+M(mv), chmod M>c, compress-to c>z
+             (keymap-set dired-mode-map
+                         "z"
+                         #'dired-do-compress-to)
+             (keymap-set dired-mode-map
+                         "c"
+                         #'dired-do-chmod)
+             (keymap-set dired-mode-map
+                         "r"
+                         #'dired-do-rename)
+             (keymap-set dired-mode-map
+                         "M"
+                         #'dired-do-rename)
+             ;; My add-on defuns
+             (keymap-set dired-mode-map
+                         "s"
+                         #'re/dired-sort)
+             (keymap-set dired-mode-map
+                         "F"
+                         #'re/dired-find-marked-files)
+             (keymap-set dired-mode-map
+                         "M-C"
+                         #'re/copy-with-mod-time)
+             (keymap-set dired-mode-map
+                         "b"
+                         #'re/dired-open-externally)
+             (keymap-set dired-mode-map
+                         "B"
+                         #'re/dired-open-marked-externally)
+             (dired-hide-details-mode t)
+             (hl-line-mode))))
+#+END_SRC
+* Bookmarks
+#+BEGIN_SRC emacs-lisp
+;; Bookmarks
+(setq bookmark-save-flag 1)
+(keymap-global-set "<f7>" #'recentf-open-files)
+(keymap-global-set "C-x r B" #'bookmark-jump-other-window)
+#+END_SRC
+* GUI
+#+BEGIN_SRC emacs-lisp
+;; GUI Settings
+(load-theme 'eng-paper t)
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+(set-scroll-bar-mode (if (eq system-type 'windows-nt) nil 'left))
+
+(setq frame-title-format "%b"
+      mouse-prefer-closest-glyph t
+      mouse-1-click-follows-link nil
+      focus-follows-mouse t
+      mouse-autoselect-window -0.25)
+
+(setq-default cursor-type 'hbar
+             cursor-in-non-selected-windows nil
+             mode-line-format
+             '("%e"
+               (:eval (propertize "  "
+                                  'face
+                                  (when (buffer-modified-p)
+                                      'mode-line-highlight)))
+               " "
+               (:propertize (buffer-file-name "%f" "%b")
+                            face
+                            mode-line)
+               (vc-mode vc-mode)
+               mode-line-format-right-align
+               (:eval (number-to-string (line-number-at-pos (point-max))))
+               "L @ %I%n %l,%C "))
+
+(setq prettify-symbols-alist '(("lambda" . 955)
+                              ("delta" . 120517)
+                              ("epsilon" . 120518)
+                              ("->" . 8594)
+                              ("<=" . 8804)
+                              (">=" . 8805)))
+
+(global-prettify-symbols-mode t)
+#+END_SRC
+* Parens
+#+BEGIN_SRC emacs-lisp
+;; Parens (must be after loading the theme)
+(setq show-paren-delay 0
+      show-paren-style 'expression)
+
+(setq electric-pair-pairs '((?\" . ?\")
+                           (?\‘ . ?\’)
+                           (?\“ . ?\”)
+                           (?\{ . ?\})
+                           (?\< . ?\>)))
+#+END_SRC
+* Help
+#+BEGIN_SRC emacs-lisp
+;; Help
+(setq apropos-do-all t)
+#+END_SRC
+* UTF-8
+#+BEGIN_SRC emacs-lisp
+;; UTF-8
+(set-charset-priority 'unicode)
+(prefer-coding-system 'utf-8-unix)
+(set-language-environment 'utf-8)
+(set-default-coding-systems 'utf-8)
+(set-keyboard-coding-system 'utf-8-unix)
+(set-terminal-coding-system 'utf-8-unix)
+#+END_SRC
+* Cleanup on write
+#+BEGIN_SRC emacs-lisp
+(defun re/flush-extra-lines ()
+  "Change all groups of blank lines to 1 blank line."
+  (interactive)
+  (save-excursion (mark-whole-buffer)
+                 (replace-regexp "^\n+"
+                                 "\n"
+                                 nil
+                                 (region-beginning)
+                                 (region-end))))
+
+(setq require-final-newline t)
+(add-hook 'before-save-hook #'re/flush-extra-lines)
+(add-hook 'before-save-hook #'whitespace-cleanup)
+(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
+#+END_SRC
+* Control
+#+BEGIN_SRC emacs-lisp
+;; Control
+(defun re/kill-emacs ()
+  "Save all open files and kill emacs."
+  (interactive)
+  (save-some-buffers t)
+  (kill-emacs))
+
+(keymap-global-set "C-x M-c" #'re/kill-emacs)
+
+(defun re/restart-emacs ()
+  "Save all open files and restart emacs."
+  (interactive)
+  (save-some-buffers t)
+  (kill-emacs nil t))
+
+(keymap-global-set "C-x M-r" #'re/restart-emacs)
+
+(defun re/keyboard-quit ()
+  "Smarter version of `keyboard-quit'.
+Close the minibuffer if not focused when hit.
+Stolen from emacsredux.com."
+  (interactive)
+  (if (active-minibuffer-window)
+      (if (minibufferp)
+         (minibuffer-keyboard-quit)
+       (abort-recursive-edit))
+    (keyboard-quit)))
+
+(keymap-global-set "<remap> <keyboard-quit>" #'re/keyboard-quit) ; Make C-g better
+(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask
+(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files
+#+END_SRC
+* Version-control mode
+#+BEGIN_SRC emacs-lisp
+;; Versioning and Backups
+(defun re/vc-clone ()
+  "Interactively clone with vc-mode.
+Prompt for url and local dir."
+  (interactive)
+  (let* ((url (read-string "Repository URL: "))
+        (dir (read-string "Local Dir: " (file-name-base url))))
+    (vc-git-clone url dir nil)))
+
+(keymap-global-set "C-x v C" #'re/vc-clone)
+
+(defun re/vc-show-branches (&optional arg)
+  "Display all Git branches in a separate buffer.
+Remotes as well when arg."
+  (interactive "P")
+  (let ((default-directory (if (boundp 'vc-dir-directory)
+                              vc-dir-directory
+                            default-directory)))
+    (vc-git-command "*git-branches*"
+                   nil
+                   nil
+                   "branch"
+                   "--verbose"
+                   (when arg "--remotes"))
+    (pop-to-buffer "*git-branches*")
+    (goto-char (point-min))
+    (special-mode)))
+
+(keymap-global-set "C-x v b b" #'re/vc-show-branches)
+
+(defun re/vc-fetch (&optional arg)
+  "Interactively fetch with vc-mode.
+Allows separate fetch in addition to pull.  Only care about git.
+With arg, ask for remote, otherwise fetch all."
+  (interactive "P")
+  (let* ((default-directory (if (boundp 'vc-dir-directory)
+                               vc-dir-directory
+                             default-directory)))
+    (vc-git-command "*vc-fetch*"
+                   nil
+                   nil
+                   "fetch"
+                   (if arg
+                       (read-string "Fetch From: " "origin")
+                     "--all")
+                   "--verbose")
+    (pop-to-buffer "*vc-fetch*")
+    (goto-char (point-min))
+    (special-mode)))
+
+(keymap-global-set "C-x v f" #'re/vc-fetch)
+
+(setq vc-git-root-log-format
+      `("%d %h %ai %an: %s"
+       ;; The first shy group matches the characters drawn by --graph.
+       ;; We use numbered groups because `log-view-message-re' wants the
+       ;; revision number to be group 1.
+       ,(concat "^\\(?:[*/\\|]+\\)\\(?:[*/\\| ]+\\)?"
+                "\\(?2: ([^)]+) \\)?\\(?1:[0-9a-z]+\\) "
+                "\\(?4:[0-9]\\{4\\}-[0-9-]\\{4\\}[0-9\s+:-]\\{16\\}\\) "
+                "\\(?3:.*?\\):")
+       ((1 'log-view-message)
+        (2 'change-log-list nil lax)
+        (3 'change-log-name)
+        (4 'change-log-date))))
+
+(add-hook 'vc-dir-mode-hook
+         (lambda ()
+           (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches)
+           (keymap-set vc-dir-mode-map "f" #'re/vc-fetch)))
+
+(setq vc-make-backup-files nil
+      vc-handled-backends '(Git)
+      vc-git-diff-switches '("--patch-with-stat" "--histogram")
+      vc-git-log-switches '("--oneline" "--all" "--graph")
+      vc-git-log-edit-summary-target-len 50
+      vc-git-log-edit-summary-max-len 70
+      vc-find-revision-no-save t)
+#+END_SRC
+* Backups
+#+BEGIN_SRC emacs-lisp
+
+(setq backup-directory-alist `((".*" . "~/emacs-backups/"))
+      backup-by-copying t
+      delete-old-versions t
+      kept-new-versions 5
+      kept-old-versions 5)
+#+END_SRC
+* Any Lisp Repl
+#+BEGIN_SRC emacs-lisp
+;; Any Lisp Repl
+(defmacro re/send-on-close-paren (executor)
+  "Generalizes sending an execute on close paren.
+ Interactively call `executor'.  For `executor', use whatever
+ function is called by `<RET>' in the applicable REPL.  For a
+ non-repl, use `newline' or similar."
+  `(lambda (&optional arg)
+     (interactive "p")
+     (insert-char 41 arg)
+     (call-interactively ,executor)))
+
+(defun re/sexp-drop-paren-p ()
+  "Returns t if sexp needs fewer parens to balance."
+  (< (car (syntax-ppss)) 0))
+
+(defun re/sexp-need-paren-p ()
+  "Returns t if sexp needs more parens to balance."
+  (> (car (syntax-ppss)) 0))
+
+(defun re/sexp-unbalanced-count ()
+  "Returns distance from balanced sexp."
+  (abs (car (syntax-ppss))))
+
+(defun re/balance-sexp ()
+  "Balance the sexp before point.
+Either delete, move forward, or add as many ')' as needed."
+  (let ((distance (re/sexp-unbalanced-count)))
+    (cond ((re/sexp-need-paren-p)
+          (if (looking-at ")")
+              (progn
+                (forward-char)
+                (re/balance-sexp))
+            (insert-char 41 distance)))
+         ((re/sexp-drop-paren-p)
+          (backward-delete-char distance)))))
+
+(defmacro re/balance-and-eval-sexp (executor)
+  "Balance the sexp before point, then call `executor'.
+Call `re/balance-sexp', then interactively call `executor'.  Bind
+this to ']' for the interlisp experience.  For `executor', use
+whatever function is called by `<RET>' in the applicable REPL.
+For a non-repl, use `newline' or similar."
+  `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor)))
+
+(defvar *re/lisp-mode-hooks*
+  '(emacs-lisp-mode-hook
+    lisp-mode-hook
+    sly-mode-hook
+    scheme-mode-hook
+    geiser-mode-hook
+    lisp-interaction-mode-hook))
+
+(dolist (hook *re/lisp-mode-hooks*)
+  (add-hook hook
+           (lambda ()
+             (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1))
+             (sedit-mouse-mode 1)
+             (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region)
+             (keymap-set lisp-mode-shared-map
+                         "C-M-S-q"
+                         #'sedit-auto-prettify-sexp)
+             (keymap-set lisp-mode-shared-map
+                         "]"
+                         (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp))
+             (keymap-set lisp-interaction-mode-map
+                         "]"
+                         (re/balance-and-eval-sexp #'eval-print-last-sexp)))))
+#+END_SRC
+* IELM
+Rarely used, but nice to have when I want it.
+#+BEGIN_SRC emacs-lisp
+;; IELM
+(add-hook 'ielm-mode-hook
+         (lambda ()
+           (keymap-set inferior-emacs-lisp-mode-map
+                       "C-l"
+                       #'comint-clear-buffer)
+           (let ((eval-function #'ielm-send-input))
+             (keymap-set inferior-emacs-lisp-mode-map
+                         ")"
+                         (re/send-on-close-paren eval-function))
+             (keymap-set inferior-emacs-lisp-mode-map
+                         "]"
+                         (re/balance-and-eval-sexp eval-function)))))
+#+END_SRC
+* Eshell
+#+BEGIN_SRC emacs-lisp
+;; Eshell
+(keymap-global-set "C-c e" #'eshell)
+
+(defun eshell-quit-or-delete-char (arg)
+  "Delete char if at one, quit eshell if on empty prompt.
+Stolen from https://depp.brause.cc/dotemacs"
+  (interactive "p")
+  (if (and (eolp) (looking-back eshell-prompt-regexp 0 t))
+      (eshell-life-is-too-much)
+    (delete-char arg)))
+
+(add-hook 'eshell-mode-hook
+         (lambda ()
+           (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char)
+           (let ((eval-function #'eshell-send-input))
+             (keymap-set eshell-mode-map
+                         ")"
+                         (re/send-on-close-paren eval-function))
+             (keymap-set eshell-mode-map
+                         "]"
+                         (re/balance-and-eval-sexp eval-function)))))
+#+END_SRC
+* C-mode
+#+BEGIN_SRC emacs-lisp
+;;; C-mode
+(dolist (mode-maps '(("\\.keymap\\'" . c-mode) ("\\.dtsi\\'" . c-mode)))
+  (add-to-list 'auto-mode-alist mode-maps t))
+
+(defun re/c-lineup-arglist-tabs-only (ignored)
+  "Line up argument lists by tabs, not spaces.
+ Stolen from https://kernel.org/doc/html/v4.10/process/coding-style.html"
+  (let* ((anchor (c-langelem-pos c-syntactic-element))
+        (column (c-langelem-2nd-pos c-syntactic-element))
+        (offset (- (1+ column) anchor))
+        (steps (floor offset c-basic-offset)))
+    (* (max steps 1) c-basic-offset)))
+
+(add-hook 'c-mode-common-hook
+         (lambda ()
+           (c-add-style "linux-tabs-only"
+                        '("linux" (c-offsets-alist
+                                   (arglist-cont-nonempty
+                                    c-lineup-gcc-asm-reg
+                                    re/c-lineup-arglist-tabs-only))))))
+
+(add-hook 'c-mode-hook
+         (lambda ()
+           (setq c-backspace-function 'backward-delete-char)
+           (c-set-style "linux-tabs-only")))
+#+END_SRC
+* Auto-Revert
+#+BEGIN_SRC emacs-lisp
+;; Auto-Revert
+(global-auto-revert-mode t)
+(setq global-auto-revert-non-file-buffers t)
+#+END_SRC
+* Crash Handliŋ
+#+BEGIN_SRC emacs-lisp
+;; Crash handliŋ
+(setq attempt-stack-overflow-recovery nil
+      attempt-orderly-shutdown-on-fatal-signal nil)
+#+END_SRC
+* Abbrev-mode and skeletons
+#+BEGIN_SRC emacs-lisp
+;; Abbrev-mode and Skeletons
+(define-skeleton workorder-link
+  "part of a link to a workorder, just enter the number."
+  ""
+  "https://eservice.r717.net/index.php/PLC_workorders/store/"
+  _ -)
+
+(define-skeleton skel-org-block
+  "Add a source block to an org file."
+  ""
+  "#+BEGIN_SRC"
+  \n
+  _ -
+  \n
+  "#+END_SRC")
+
+(define-skeleton skel-org-block-elisp
+  "Add an elisp source block to an org file."
+  ""
+  "#+BEGIN_SRC emacs-lisp"
+  \n
+  _ -
+  \n
+  "#+END_SRC")
+
+(setq save-abbrevs 'silently)
+
+(dolist (hook '(org-mode-hook howm-mode-hook))
+  (add-hook hook #'abbrev-mode))
+#+END_SRC
+* Customization Framework
+Disable it by making it save to a temp file (stolen from prot)
+#+BEGIN_SRC emacs-lisp
+(setq custom-file (make-temp-file "emacs-custom-"))
+#+END_SRC
+* Footer
+#+BEGIN_SRC emacs-lisp
+;;; config.el ends here
+#+END_SRC
diff --git a/init.el b/init.el
index 237b52895d200900c5bb0a2cd5cfdbc6a183ef0c..0b4d6404320a024f5d76cc0e1a168685d84012ef 100644 (file)
--- a/init.el
+++ b/init.el
@@ -4,11 +4,6 @@
 
 ;;; Code:
 
-(let ((org-file "~/.emacs.d/README.org")
-      (el-file  "~/.emacs.d/config.el"))
-  (when (file-newer-than-file-p org-file el-file)
-    (require 'ob-tangle)
-    (org-babel-tangle-file org-file el-file))
-  (load-file el-file))
+(org-babel-load-file "~/.emacs.d/config.org")
 
 ;;; init.el ends here