]> git.earman.xyz Git - emacsinit.git/commitdiff
Move away from literate config
authorrush <rearman@r717.net>
Tue, 30 Jun 2026 15:55:19 +0000 (11:55 -0400)
committerrush <rearman@r717.net>
Tue, 30 Jun 2026 17:22:29 +0000 (13:22 -0400)
Tangle config.org into init.el, update comment levels, add page-breaks

config.org [deleted file]
init.el

diff --git a/config.org b/config.org
deleted file mode 100644 (file)
index 99c2328..0000000
+++ /dev/null
@@ -1,1424 +0,0 @@
-#+TITLE: Emacs literate config\r
-#+PROPERTY: header-args :comments org :tangle yes\r
-\r
-* Header\r
-Set up the correct lexical binding to avoid screaming compiler\r
-#+BEGIN_SRC emacs-lisp :comments no\r
-;;; config.el --- Emacs Configuration  -*- lexical-binding: t; -*-\r
-#+END_SRC\r
-* OS specific stuff\r
-#+BEGIN_SRC emacs-lisp\r
-(setq w32-recognize-altgr 'nil)\r
-\r
-(unless (equal system-type 'windows-nt)\r
-  (setq trash-directory "~/Trash/")\r
-  (defun doas ()\r
-    "Use TRAMP to reopen the current buffer as root using doas."\r
-    (interactive)\r
-    (when buffer-file-name\r
-      (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))\r
-  (defun sudo ()\r
-    "Use TRAMP to reopen the current buffer as root using sudo."\r
-    (interactive)\r
-    (when buffer-file-name\r
-      (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))))\r
-#+END_SRC\r
-* Packages\r
-** Add melpa, initialize\r
-#+BEGIN_SRC emacs-lisp\r
-(require 'package)\r
-\r
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)\r
-(package-initialize)\r
-#+END_SRC\r
-** Install all packages that are not included\r
-#+BEGIN_SRC emacs-lisp\r
-(defvar *re/packages*\r
-  '(corfu\r
-    expand-region\r
-    page-break-lines\r
-    pdf-tools\r
-    auctex\r
-    csv-mode\r
-    markdown-mode\r
-    edit-indirect\r
-    sly\r
-    geiser\r
-    geiser-chicken\r
-    forth-mode\r
-    trashed\r
-    org-transclusion\r
-    vc-jj\r
-    minions))\r
-\r
-(dolist (pkg *re/packages*)\r
-  (unless (package-installed-p pkg)\r
-    (package-refresh-contents)\r
-    (package-install pkg)))\r
-#+END_SRC\r
-** Corfu\r
-#+BEGIN_SRC emacs-lisp\r
-(require 'corfu)\r
-\r
-(setq corfu-auto t\r
-      corfu-auto-delay 0\r
-      corfu-auto-prefix 1)\r
-\r
-(add-hook 'corfu-mode-hook #'corfu-popupinfo-mode)\r
-\r
-(setq corfu-popupinfo-delay '(1.0 . 0.01) ; start after one second, fast refresh once on\r
-      corfu-popupinfo-hide nil)\r
-\r
-(global-corfu-mode)\r
-#+END_SRC\r
-** Expand Region\r
-#+BEGIN_SRC emacs-lisp\r
-(require 'expand-region)\r
-\r
-(keymap-global-set "C-=" #'er/expand-region)\r
-#+END_SRC\r
-** Page Break Lines\r
-#+BEGIN_SRC emacs-lisp\r
-(require 'page-break-lines)\r
-(global-page-break-lines-mode)\r
-#+END_SRC\r
-** PDFtools\r
-Be sure to run =pdf-tools-install= before first run\r
-#+BEGIN_SRC emacs-lisp\r
-(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-tools-install))\r
-\r
-(setq-default pdf-view-display-size 'fit-page)\r
-#+END_SRC\r
-** Auctex\r
-#+BEGIN_SRC emacs-lisp\r
-(setq-default TeX-master nil)\r
-\r
-(setq TeX-auto-save t\r
-      TeX-parse-self t\r
-      TeX-PDF-mode t\r
-      TeX-view-program-selection '((output-pdf "PDF Tools"))\r
-      TeX-source-correlate-start-server t)\r
-\r
-(add-hook 'TeX-after-compilation-finished-functions\r
-         #'TeX-revert-document-buffer)\r
-#+END_SRC\r
-** CSV Mode\r
-#+BEGIN_SRC emacs-lisp\r
-(add-hook 'csv-mode-hook 'csv-align-mode)\r
-#+END_SRC\r
-** Markdown Mode\r
-Make markdown act more like org when I'm forced to use it\r
-#+BEGIN_SRC emacs-lisp\r
-(setq markdown-special-ctrl-a/e t)\r
-\r
-(with-eval-after-load 'markdown-mode\r
-    (keymap-set markdown-mode-map "M-<right>" #'markdown-demote)\r
-    (keymap-set markdown-mode-map "M-<left>" #'markdown-promote)\r
-    (keymap-set markdown-mode-map "M-<up>" #'markdown-move-up)\r
-    (keymap-set markdown-mode-map "M-<down>" #'markdown-move-down)\r
-    (keymap-set markdown-mode-map "C-M-u" #'markdown-up-heading)\r
-    (keymap-set markdown-mode-map "C-M-b" #'markdown-outline-previous-same-level)\r
-    (keymap-set markdown-mode-map "C-M-f" #'markdown-outline-next-same-level)\r
-    (keymap-set markdown-mode-map "C-M-p" #'markdown-outline-previous)\r
-    (keymap-set markdown-mode-map "C-M-n" #'markdown-outline-next))\r
-#+END_SRC\r
-** Sly\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/sly-repl-new-frame (&optional arg)\r
-  "Start a SLY repl in a new frame."\r
-  (interactive "P")\r
-  (re/open-with-new-frame "SLY" #'sly))\r
-\r
-(defun re/sly-quit-current-lisp ()\r
-  "Quit the current lisp repl connection without prompting."\r
-  (interactive)\r
-  (sly-quit-lisp nil nil))\r
-\r
-(defun re/sly-connect-stump (&optional arg)\r
-  "Connect to my typical stumpwm instance."\r
-  (interactive "P")\r
-  (sly-connect "localhost" 4004))\r
-\r
-(setq inferior-lisp-program "sbcl"\r
-      sly-net-coding-system 'utf-8-unix\r
-      sly-command-switch-to-existing-lisp 'always)\r
-\r
-(let ((core (expand-file-name "~/sbcl.core-for-sly")))\r
-  (when (file-exists-p core)\r
-    (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core))))))\r
-\r
-(with-eval-after-load 'sly-mrepl\r
-  (keymap-set sly-mrepl-mode-map ")" (re/send-on-close-paren #'sly-mrepl-return))\r
-  (keymap-set sly-mrepl-mode-map "]" (re/balance-and-eval-sexp #'sly-mrepl-return))\r
-  (keymap-set sly-mrepl-mode-map "C-c q" #'re/sly-quit-current-lisp))\r
-#+END_SRC\r
-*** Eldoc settings\r
-Sly really doesn't play well with elodc in the minibuffer, so here are some settings to make it better.\r
-#+BEGIN_SRC emacs-lisp\r
-(add-to-list 'display-buffer-alist\r
-            '("^\\*eldoc" display-buffer-in-direction\r
-              (direction . 'down)\r
-              (window-height . 4)))\r
-(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer\r
-(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed\r
-#+END_SRC\r
-** Geiser\r
-#+BEGIN_SRC emacs-lisp\r
-(if (equal system-type 'windows-nt)\r
-    (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))\r
-  (setq geiser-chicken-binary "csi -:c"))\r
-\r
-(setq scheme-program-name geiser-chicken-binary\r
-      geiser-active-implementations '(chicken))\r
-\r
-(add-hook 'scheme-mode-hook 'geiser-mode)\r
-\r
-(with-eval-after-load 'geiser-repl\r
-    (keymap-set geiser-repl-mode-map ")" (re/send-on-close-paren #'geiser-repl-maybe-send))\r
-    (keymap-set geiser-repl-mode-map "]" (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))\r
-#+END_SRC\r
-** ORG\r
-*** Set bindings, things that have to happen after loading\r
-#+BEGIN_SRC emacs-lisp\r
-(with-eval-after-load 'org\r
-    (require 'org-mouse)\r
-    (add-to-list 'org-export-backends 'md)\r
-    (keymap-set org-mode-map "C-M-h" #'org-mark-subtree)\r
-    (keymap-set org-mode-map "C-M-u" #'org-up-element)\r
-    (keymap-set org-mode-map "C-M-d" #'org-down-element)\r
-    (keymap-set org-mode-map "C-M-b" #'org-backward-heading-same-level)\r
-    (keymap-set org-mode-map "C-M-f" #'org-forward-heading-same-level)\r
-    (keymap-set org-mode-map "C-M-p" #'org-previous-visible-heading)\r
-    (keymap-set org-mode-map "C-M-n" #'org-next-visible-heading)\r
-    (keymap-set org-mode-map "C-c t" #'org-transclusion-mode))\r
-\r
-(keymap-global-set "C-c l" #'org-store-link)\r
-(keymap-global-set "C-c a" #'org-agenda)\r
-(keymap-global-set "C-c c" #'org-capture)\r
-#+END_SRC\r
-*** General options\r
-#+BEGIN_SRC emacs-lisp\r
-(setq org-M-RET-may-split-line nil\r
-      org-cycle-inline-images-display t\r
-      org-cycle-separator-lines -1\r
-      org-ellipsis "->"\r
-      org-enforce-todo-checkbox-dependencies t\r
-      org-enforce-todo-dependencies t\r
-      org-goto-interface 'outline-path-completion\r
-      org-outline-path-complete-in-steps nil\r
-      org-src-fontify-natively nil\r
-      org-return-follows-link t\r
-      org-reverse-note-order t\r
-      org-special-ctrl-a/e t\r
-      org-special-ctrl-k t\r
-      org-src-preserve-indentation t\r
-      org-startup-folded 'fold\r
-      org-tags-column 0\r
-      org-yank-adjusted-subtrees t\r
-      org-refile-use-outline-path 'file\r
-      org-refile-allow-creating-parent-nodes 'confirm)\r
-#+END_SRC\r
-**** Testing without these setq options\r
-#+BEGIN_SRC emacs-lisp :tangle no\r
-      org-fontify-done-headline nil\r
-      org-goto-auto-isearch nil\r
-      org-list-allow-alphabetical t\r
-      org-src-window-setup 'current-window)\r
-#+END_SRC\r
-*** Time Clocking\r
-#+BEGIN_SRC emacs-lisp :tangle no\r
-(org-clock-persistence-insinuate)\r
-(setq org-clock-in-resume t\r
-      org-clock-out-remove-zero-time-clocks t\r
-      org-clock-persist t\r
-      org-clock-report-include-clocking-task t\r
-      org-time-stamp-rounding-minutes '(1 1))\r
-#+END_SRC\r
-*** Agenda and Capture\r
-**** Agenda settings\r
-#+BEGIN_SRC emacs-lisp\r
-  (setq org-agenda-files (append '("~/org/")\r
-                              (file-expand-wildcards "~/projects/*/"))\r
-       org-refile-targets '((nil :maxlevel . 9)\r
-                          (org-agenda-files :maxlevel . 9))\r
-       org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)"))\r
-       org-todo-keyword-faces '(("WAITING" :foreground "#e85400" :weight bold)) ; alert orange\r
-       org-agenda-prefix-format '((agenda . "          %?-12t%? s")\r
-                                (todo . " ")\r
-                                (tags . " ")\r
-                                (search . " "))\r
-       org-agenda-start-on-weekday nil\r
-       org-read-date-prefer-future 'time\r
-       org-log-done 'time\r
-       org-log-redeadline 'time\r
-       org-log-reschedule 'time\r
-       org-log-state-notes-insert-after-drawers t\r
-       org-agenda-window-setup 'current-window)\r
-#+END_SRC\r
-***** Testing without these options\r
-#+BEGIN_SRC emacs-lisp :tangle no\r
-      org-tag-alist '((:startgroup)\r
-                     ("call" . ?c)\r
-                     ("net" . ?n)\r
-                     (:endgroup)\r
-                     (:startgroup)\r
-                     ("home" . ?h)\r
-                     ("office" . ?o)\r
-                     ("errand" . ?e)\r
-                     ("vps" . ?v)\r
-                     (:endgroup))\r
-      org-agenda-span 'day\r
-      org-agenda-restore-windows-after-quit t\r
-      org-agenda-time-grid '((daily today require-timed)\r
-                            (800 1000 1200 1400 1600 1800 2000)\r
-                            " -----"\r
-                            "")\r
-      org-agenda-scheduled-leaders '("Booked: " "Booked %dd. ago: ")\r
-      org-agenda-deadline-leaders '("Deadline: " "In %dd.: " "Died %dd. ago: ")\r
-      org-agenda-start-with-log-mode t\r
-      org-agenda-log-mode-items '(closed clock state))\r
-#+END_SRC\r
-**** Stuck Projects\r
-#+BEGIN_SRC emacs-lisp\r
-(setq org-stuck-projects '("CATEGORY=\"undertakings\"+LEVEL=1/-DONE-GIVEN-BELAYED" ("TODO" "WAITING") nil ""))\r
-#+END_SRC\r
-**** Custom Agendas\r
-#+BEGIN_SRC emacs-lisp\r
-  (defvar *re/org-agenda-inbox*\r
-    '(tags "CATEGORY=\"inbox\"" ((org-agenda-overriding-header ""))))\r
-\r
-  (defvar *re/org-agenda-todo*\r
-    '(tags-todo "-recurring/TODO" ((org-agenda-overriding-header ""))))\r
-\r
-  (defvar *re/org-agenda-undertakings*\r
-    '(tags "CATEGORY=\"undertakings\"+LEVEL=1" ((org-agenda-overriding-header ""))))\r
-\r
-  (defvar *re/org-agenda-waiting*\r
-    '(todo "WAITING" ((org-agenda-overriding-header ""))))\r
-\r
-(defvar *re/org-agenda-done*\r
-  '(tags "-recurring+LEVEL=1/DONE|BELAYED|GIVEN"))\r
-\r
-  (setq org-agenda-custom-commands `(("i" "Inbox" ,@*re/org-agenda-inbox*)\r
-                                          ("n" "Next Actions" ,@*re/org-agenda-todo*)\r
-                                          ("u" "Undertakings" ,@*re/org-agenda-undertakings*)\r
-                                          ("w" "Waiting" ,@*re/org-agenda-waiting*)\r
-                                          ("d" "Done" ,@*re/org-agenda-done*)))\r
-#+END_SRC\r
-**** Capture Templates\r
-#+BEGIN_SRC emacs-lisp\r
-  (setq org-capture-templates '(("i" "Inbox" entry\r
-                              (file "inbox.org")\r
-                              "* %^{Description}\n%U\n%?"\r
-                              :prepend t)\r
-                             ("n" "Next Action" entry\r
-                              (file "next.org")\r
-                              "* TODO %^{Description}\nTaken: %T\n%?"\r
-                              :prepend t)\r
-                             ("u" "Undertaking" entry\r
-                              (file "undertakings.org")\r
-                              "* %^{Description} [/]\nTaken: %T\n%?"\r
-                              :prepend t)\r
-                             ("m" "Meeting" entry\r
-                              (file "meetings.org")\r
-                              "* %^{Description}\n%^{Scheduled:}T\n%?"\r
-                              :prepend t)\r
-                             ("p" "Phone Call" entry\r
-                              (file "inbox.org")\r
-                              "* %^{Description} :call:\n%T\n%?"\r
-                              :prepend t)\r
-                             ("t" "Note" entry\r
-                              (file "notes.org")\r
-                              "* %^{Description}\n%U\n%?"\r
-                              :prepend t)))\r
-#+END_SRC\r
-*** IDs\r
-#+BEGIN_SRC emacs-lisp\r
-(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id\r
-      org-id-method 'ts\r
-      org-clone-delete-id t\r
-      org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format\r
-                                           org-attach-id-uuid-folder-format))\r
-\r
-(defun re/org-save-all ()\r
-  "Save all `org-agenda-files' without user confirmation."\r
-  (interactive)\r
-  (message "Saving all org-agenda-files buffers...")\r
-  (save-some-buffers t\r
-                    (lambda ()\r
-                      (when (member (buffer-file-name) org-agenda-files) t)))\r
-  (message "Saving all org-agenda-files buffers... done"))\r
-\r
-(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))\r
-#+END_SRC\r
-*** Archiving\r
-#+BEGIN_SRC emacs-lisp\r
-(setq org-archive-location (concat "~/org/old.org_keep::datetree/")\r
-      org-agenda-text-search-extra-files '(agenda-archives))\r
-\r
-(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))\r
-#+END_SRC\r
-*** Converting markdown to org\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/markdown-to-org-region (start end)\r
-  "Convert Markdown formatted text in region (START, END) to Org.\r
-This command requires that pandoc (man page `pandoc(1)') be\r
-installed."\r
-  (interactive "r")\r
-  (shell-command-on-region\r
-   start end\r
-   "pandoc -f markdown -t org --wrap=preserve" t t))\r
-#+END_SRC\r
-*** Converting org to markdown\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/org-to-markdown-region (start end)\r
-  "Convert Org formatted text in region (START, END) to Markdown.\r
-This command requires that pandoc (man page `pandoc(1)') be\r
-installed."\r
-  (interactive "r")\r
-  (shell-command-on-region\r
-   start end\r
-   "pandoc -f org -t markdown --wrap=preserve" t t))\r
-#+END_SRC\r
-** Trashed\r
-Shows the trash file as a dired buffer\r
-#+BEGIN_SRC emacs-lisp\r
-(setq trashed-action-confirmer 'y-or-n-p\r
-       trashed-use-header-line t\r
-       trashed-sort-key '("Date deleted" . t)\r
-       trashed-date-format "%Y-%m-%d %H:%M:%S")\r
-#+END_SRC\r
-** Use mu4e on my home pcs\r
-#+BEGIN_SRC emacs-lisp\r
-(when (eq system-type 'gnu/linux)\r
-  (with-eval-after-load 'mu4e\r
-    (setq mail-user-agent 'message-user-agent\r
-         message-send-mail-function 'smtpmail-send-it\r
-         message-citation-line-format "Quoth %f :\n"\r
-         smtpmail-default-smtp-server "mail.earman.xyz"\r
-         smtpmail-smtp-server "mail.earman.xyz"\r
-         smtpmail-smtp-service 587\r
-         smtpmail-stream-type 'starttls\r
-         smtpmail-local-domain "earman.xyz"\r
-         smtpmail-queue-mail nil\r
-         smtpmail-queue-dir "~/mail/Outbox/cur"\r
-         user-mail-address "iv@earman.xyz"\r
-         user-full-name "Rush N. Earman IV"\r
-         message-signature "Rush Earman IV, PE"\r
-         message-kill-buffer-on-exit t\r
-         mu4e-get-mail-command "mbsync -a"\r
-         mu4e-update-interval (* 10 60)\r
-         mu4e-change-filenames-when-moving t\r
-         mu4e-use-fancy-chars t\r
-         mu4e-attachment-dir "~/downloads"\r
-         mu4e-compose-reply-to-address "iv@earman.xyz"\r
-         mu4e-maildir "~/mail"\r
-         mu4e-drafts-folder "/Drafts"\r
-         mu4e-sent-folder "/Sent"\r
-         mu4e-trash-folder "/Trash"\r
-         mu4e-maildir-shortcuts '((:maildir "/Inbox" :key ?i)\r
-                                  (:maildir "/Sent" :key ?s)\r
-                                  (:maildir "/Trash" :key ?t)\r
-                                  (:maildir "/Drafts" :key ?d)))))\r
-#+END_SRC\r
-* Load libraries\r
-Libraries Not from the package manager\r
-#+BEGIN_SRC emacs-lisp\r
-(dolist (path '("sedit-mouse/" "themes/"))\r
-  (add-to-list 'load-path (concat user-emacs-directory path)))\r
-\r
-(dolist (file '(eng-paper-theme sedit-mouse))\r
-  (require file))\r
-#+END_SRC\r
-* UNIX/vi-like bindings\r
-=C-h=, =C-w=, =C-u=, et. al to work as I expect (like acme).  Some functions get re-bound when these take over a default.\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/open-line-below (n)\r
-  "Creates a new empty line below the current line and moves to it."\r
-  (interactive "*p")\r
-  (end-of-line)\r
-  (open-line n)\r
-  (next-line 1)\r
-  (indent-for-tab-command))\r
-\r
-(keymap-global-set "C-o" #'re/open-line-below)\r
-\r
-(defun re/open-line-above (n)\r
-  "Creates a new empty line above the current line."\r
-  (interactive "*p")\r
-  (beginning-of-line)\r
-  (open-line n)\r
-  (indent-for-tab-command))\r
-\r
-(keymap-global-set "M-o" #'re/open-line-above)\r
-\r
-(defun re/kill-bword-or-region (&optional arg)\r
-  "Kill region if active, otherwise kill back one word."\r
-  (interactive "p")\r
-  (if (use-region-p)\r
-      (kill-region (region-beginning) (region-end))\r
-    (backward-kill-word arg)))\r
-\r
-(keymap-global-set "C-w" #'re/kill-bword-or-region)\r
-(keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards\r
-(keymap-global-set "C-S-U" #'universal-argument)\r
-(keymap-set key-translation-map "C-h" "<DEL>") ; Rather F1 for help, also C-S-H works\r
-(keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way\r
-(keymap-global-set "<home>" #'beginning-of-buffer)\r
-(keymap-global-set "<end>" #'end-of-buffer)\r
-#+END_SRC\r
-* Commenting and defun-level bindings\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/comment-dwim (&optional arg)\r
-  "Comment region if active, otherwise comment line.\r
-  Stolen from https://depp.brause.cc/dotemacs"\r
-  (interactive "P")\r
-  (if (use-region-p)\r
-      (comment-or-uncomment-region (region-beginning) (region-end))\r
-    (comment-line arg)))\r
-\r
-(keymap-global-set "M-;" #'re/comment-dwim)\r
-\r
-(defun re/comment-defun (&optional arg)\r
-  "Mark a defun and comment it out.\r
-  Return to initial position after.  Arg works on `mark-defun'."\r
-  (interactive "P")\r
-  (save-excursion (mark-defun arg)\r
-                 (comment-region (region-beginning) (region-end))))\r
-\r
-(keymap-global-set "C-M-;" #'re/comment-defun)\r
-\r
-(defun re/kill-defun (&optional arg)\r
-  "Mark a defun and kill it.\r
-  Arg works on `mark-defun'."\r
-  (interactive "P")\r
-  (mark-defun arg)\r
-  (kill-region (region-beginning) (region-end)))\r
-\r
-(keymap-global-set "C-M-S-K" #'re/kill-defun)\r
-#+END_SRC\r
-* Misc QOL bindings\r
-#+BEGIN_SRC emacs-lisp\r
-(keymap-global-set "<insert>" nil) ; I keep toggliƋ overwrite-mode haply\r
-(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes\r
-(keymap-global-set "C-S-K" #'kill-whole-line)\r
-(keymap-global-set "C-S-d" #'delete-pair)\r
-(keymap-global-set "C-z" #'zap-up-to-char)\r
-(keymap-global-set "C-c s" #'sort-lines)\r
-(keymap-global-set "<remap> <capitalize-word>" #'capitalize-dwim) ; M-c\r
-(keymap-global-set "<remap> <downcase-word>" #'downcase-dwim) ; M-l\r
-(keymap-global-set "<remap> <upcase-word>" #'upcase-dwim) ; M-u\r
-#+END_SRC\r
-* Tabs\r
-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.\r
-#+BEGIN_SRC emacs-lisp\r
-;; Tabs\r
-(setq-default indent-tabs-mode t\r
-             tab-width 8\r
-             backward-delete-char-untabify-method nil)\r
-\r
-(advice-add 'indent-to :around\r
-           (lambda (orig-fun column &rest args)\r
-             (when indent-tabs-mode\r
-               (setq column (* tab-width (round column tab-width))))\r
-             (apply orig-fun column args)))\r
-\r
-(dolist (indent-level '(c-basic-offset cperl-indent-level LaTeX-indent-level))\r
-  (defvaralias indent-level 'tab-width))\r
-\r
-(defun Tab (width)\r
-  "Give me a function analagous to the Acme `Tab' command"\r
-  (interactive)\r
-  (setq-local tab-width width))\r
-\r
-(keymap-global-set "<tab>" (lambda () (interactive) (insert "\t")))\r
-#+END_SRC\r
-* Buffer dealiƋ\r
-#+BEGIN_SRC emacs-lisp\r
-(setq-default indicate-empty-lines t\r
-             truncate-lines t\r
-             fill-column 78)\r
-\r
-(dolist (hook '(text-mode-hook LaTeX-mode-hook))\r
-  (add-hook hook #'visual-line-mode))\r
-\r
-(blink-cursor-mode -1)\r
-(delete-selection-mode t)\r
-\r
-(setq delete-by-moving-to-trash t\r
-      delete-pair-blink-delay 0\r
-      use-short-answers t\r
-      use-file-dialog nil\r
-      echo-keystrokes 0.1\r
-      eldoc-idle-delay 0\r
-      read-buffer-completion-ignore-case t\r
-      history-delete-duplicates t\r
-      disabled-command-function nil\r
-      save-interprogram-paste-before-kill t\r
-      confirm-kill-processes nil)\r
-\r
-(keymap-global-set "C-x M-f" #'find-file-at-point)\r
-(keymap-global-set "C-x C-b" #'buffer-menu)\r
-(keymap-global-set "C-x M-b" #'buffer-menu-other-window)\r
-(keymap-global-set "C-x k" #'kill-current-buffer)\r
-(keymap-global-set "C-x K" #'kill-buffer)\r
-#+END_SRC\r
-* Recentering and page-by-page navigation\r
-#+BEGIN_SRC emacs-lisp\r
-(setq recenter-positions '(2 middle -3))\r
-\r
-(defun re/recenter-advice (&rest _)\r
-  "Recenter to page start."\r
-  (when (called-interactively-p 'any) (recenter 2)))\r
-\r
-(dolist (binding '(backward-page forward-page))\r
-  (advice-add binding :after #'re/recenter-advice))\r
-\r
-(keymap-global-set "C-x C-n" #'forward-page)\r
-(keymap-global-set "C-x C-p" #'backward-page)\r
-(keymap-global-set "<next>" #'forward-page)\r
-(keymap-global-set "<prior>" #'backward-page)\r
-#+END_SRC\r
-* Macro to open something in its own named frame\r
-Start a repl in a new frame, open dired in a new frame, etc. etc.\r
-#+BEGIN_SRC emacs-lisp\r
-(defmacro re/open-with-new-frame (frname function)\r
-  "Run the function in its own named frame."\r
-  `(progn\r
-     (select-frame (make-frame '((name . ,(eval frname)))))\r
-     (call-interactively ,function)))\r
-#+END_SRC\r
-* Scratch buffer easy access\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/scratch-only ()\r
-  "Bring up the scratch buffer as the only visible buffer."\r
-  (interactive)\r
-  (scratch-buffer)\r
-  (delete-other-windows))\r
-\r
-(keymap-global-set "<f5>" #'scratch-buffer)\r
-(keymap-global-set "S-<f5>" #'re/scratch-only)\r
-#+END_SRC\r
-* Switch or split window\r
-Game changer.  Auto choose how to split, or just switch to the next, all on the same binding.  Ripped from an early version of the lem editor.\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/other-window-or-split-window (&optional window)\r
-  "Go to other window or split sensibly."\r
-  (interactive)\r
-  (if (= (count-windows) 1)\r
-      (funcall split-window-preferred-function window)\r
-    (other-window 1)))\r
-\r
-(keymap-global-set "C-M-o" #'re/other-window-or-split-window)\r
-#+END_SRC\r
-* Smart End/Beginning of line\r
-Similar to what org does, and indeed calls the org function if in org-mode\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/smart-beginning-of-line ()\r
-  "Move point to first non-whitespace character or `beginning-of-visual-line'.\r
-If point was already at that position, call `back-to-indentation'.\r
-Called a third time, move point back to `beginning-of-line'.\r
-If in org-mode, call `org-beginning-of-line' first."\r
-  (interactive "^")\r
-  (let ((oldpos (point)))\r
-    (if (equal major-mode 'org-mode)\r
-       (org-beginning-of-line)\r
-      (progn\r
-       (when visual-line-mode (beginning-of-visual-line 1))\r
-       (skip-syntax-forward " " (line-end-position))\r
-       (backward-prefix-chars)))\r
-    (and (= oldpos (point))\r
-        (let ((newpos (point)))\r
-          (back-to-indentation)\r
-          (and (= newpos (point)) (beginning-of-line))))))\r
-\r
-(keymap-global-set "<remap> <move-beginning-of-line>" #'re/smart-beginning-of-line)\r
-(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line)\r
-\r
-(defun re/smart-end-of-line ()\r
-  "Move point to the end of the visual line.\r
- If point was already at that position, call `move-end-of-line'.\r
-If in org-mode, call `org-end-of-line' first."\r
-  (interactive "^")\r
-  (let ((oldpos (point)))\r
-    (if (equal major-mode 'org-mode)\r
-       (org-end-of-line)\r
-      (when visual-line-mode\r
-       (end-of-visual-line 1)))\r
-    (and (= oldpos (point)) (move-end-of-line nil))))\r
-\r
-(keymap-global-set "<remap> <move-end-of-line>" #'re/smart-end-of-line)\r
-(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line)\r
-#+END_SRC\r
-* Goto line with numbers\r
-I only care about line numbers when I want to jump, so only show them then\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/goto-line ()\r
-  "Show line numbers before going to line, then hide them again."\r
-  (interactive)\r
-  (display-line-numbers-mode 1)\r
-  (call-interactively 'goto-line)\r
-  (display-line-numbers-mode -1))\r
-\r
-(keymap-global-set "<remap> <goto-line>" #'re/goto-line)\r
-#+END_SRC\r
-* Switching between buffers\r
-#+BEGIN_SRC emacs-lisp\r
-(keymap-global-set "C-." #'next-buffer)\r
-(keymap-global-set "C-," #'previous-buffer)\r
-(keymap-global-set "C-<tab>" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers\r
-(keymap-global-set "<mouse-4>" #'previous-buffer) ; Back button\r
-(keymap-global-set "<mouse-5>" #'next-buffer) ; Forward button\r
-#+END_SRC\r
-* Disable M-mouse for window manager bindings\r
-#+BEGIN_SRC emacs-lisp\r
-(keymap-global-unset "M-<down-mouse-1>")\r
-(keymap-global-unset "M-<drag-mouse-1>")\r
-(keymap-global-unset "M-<mouse-1>")\r
-(keymap-global-unset "M-<mouse-2>")\r
-(keymap-global-unset "M-<mouse-3>")\r
-#+END_SRC\r
-* Search\r
-#+BEGIN_SRC emacs-lisp\r
-;; Search\r
-(defun re/add-region-to-search-ring ()\r
-  (when (use-region-p)\r
-    (add-to-history 'search-ring\r
-                   (buffer-substring (region-beginning) (region-end)))\r
-    (deactivate-mark)))\r
-\r
-(defun re/isearch-forward-use-region ()\r
-  "Search text in region if active, otherwise normal forward search."\r
-  (interactive)\r
-  (re/add-region-to-search-ring)\r
-  (isearch-forward))\r
-\r
-(keymap-global-set "C-s" #'re/isearch-forward-use-region)\r
-\r
-(defun re/isearch-backward-use-region ()\r
-  "Search text in region if active, otherwise normal backward search."\r
-  (interactive)\r
-  (re/add-region-to-search-ring)\r
-  (isearch-backward))\r
-\r
-(keymap-global-set "C-r" #'re/isearch-backward-use-region)\r
-\r
-(defun re/exchange-point-and-mark-maybe-activate (arg)\r
-  "Call `exchange-point-and-mark' but don't activate the region.\r
-Stolen from https://www.masteringemacs.org/article/fixing-mark-commands-transient-mark-mode"\r
-  (interactive "P")\r
-  (exchange-point-and-mark (if (and transient-mark-mode (not mark-active))\r
-                              (not arg)\r
-                            arg)))\r
-\r
-(keymap-global-set "<remap> <exchange-point-and-mark>" #'re/exchange-point-and-mark-maybe-activate)\r
-\r
-(keymap-global-set "M-s ." #'isearch-forward-thing-at-point)\r
-(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point)\r
-(keymap-global-set "M-%" #'replace-regexp)\r
-(keymap-global-set "C-%" #'replace-string)\r
-(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff)\r
-(keymap-global-set "C-S-S" #'isearch-forward-regexp)\r
-(keymap-global-set "C-S-R" #'isearch-backward-regexp)\r
-#+END_SRC\r
-* Recent Files/Buffers\r
-#+BEGIN_SRC emacs-lisp\r
-(midnight-mode t)\r
-(setq clean-buffer-list-delay-general 1)\r
-(dolist (never-re '("\\` \\*tramp/.*\\'"\r
-                   "\\` \\*eshell.*\\'"))\r
-  (add-to-list 'clean-buffer-list-kill-never-regexps never-re))\r
-(save-place-mode 1)\r
-(recentf-mode 1)\r
-#+END_SRC\r
-* File Handling\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/rename-current-buffer-file nil\r
-  "Renames the current buffer and the file it is visiting."\r
-  (interactive)\r
-  (let ((name (buffer-name))\r
-       (filename (buffer-file-name)))\r
-    (if (not (and filename (file-exists-p filename)))\r
-       (error "Buffer '%s' is not visiting a file!" name)\r
-      (let ((new-name (read-file-name "New name: " filename)))\r
-       (if (get-buffer new-name)\r
-           (error "A buffer named '%s' already exists!" new-name)\r
-         (rename-file filename new-name 1)\r
-         (rename-buffer new-name)\r
-         (set-visited-file-name new-name)\r
-         (set-buffer-modified-p nil)\r
-         (message "File '%s' successfully renamed to '%s'"\r
-                  name\r
-                  (file-name-nondirectory new-name)))))))\r
-\r
-(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file)\r
-\r
-(defun re/get-file-modified-time (filepath)\r
-  (interactive)\r
-  (format-time-string "%Y-%m-%d-%H%M"\r
-                     (file-attribute-modification-time (file-attributes filepath))))\r
-\r
-(defun re/filename-inject-mod-time (filepath)\r
-  (interactive)\r
-  (concat (file-name-sans-extension filepath)\r
-         "_"\r
-         (re/get-file-modified-time filepath)\r
-         (file-name-extension filepath t)))\r
-\r
-(defun re/copy-with-mod-time (&optional filepath)\r
-  (interactive)\r
-  (let ((filepath (if (eq major-mode 'dired-mode)\r
-                     (dired-get-filename t)\r
-                   (when (null filepath)\r
-                     (read-file-name "File to copy with datestring: "\r
-                                     default-directory\r
-                                     nil\r
-                                     t\r
-                                     nil)))))\r
-    (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t)))\r
-#+END_SRC\r
-* Dired\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/dired-display-direction ()\r
-  "In dired mode, visit the file at the cursor in the right/below/left/above window."\r
-  (interactive)\r
-  (let* ((file-or-dir (dired-get-file-for-visit)) ;; get the file at cursor\r
-        (buffer (find-file-noselect file-or-dir))) ;; load the file into a buffer\r
-    (let ((window ;; figure out the window to use\r
-          (cond ((get-buffer-window buffer (selected-frame)))\r
-                ((window-in-direction 'right)) ;; try window in each direction\r
-                ((window-in-direction 'below)) ;; and default to right\r
-                ((window-in-direction 'left))  ;; if no window found.\r
-                ((window-in-direction 'above))\r
-                (t (split-window-sensibly (selected-window))))))\r
-      (window--display-buffer buffer window 'window nil)\r
-      window)))\r
-\r
-(defun re/dired-new-frame ()\r
-  "Open dired in a new frame."\r
-  (interactive)\r
-  (re/open-with-new-frame "DIRED"\r
-                         #'(lambda () (interactive) (dired default-directory))))\r
-\r
-(keymap-global-set "<f8>" #'re/dired-new-frame)\r
-\r
-(defun re/dired-find-marked-files ()\r
-  "Open all marked files from `dired'."\r
-  (interactive)\r
-  (mapc #'find-file (reverse (dired-get-marked-files))))\r
-\r
-(defun re/dired-sort ()\r
-  "Change sort order of dired dir."\r
-  (interactive)\r
-  (let ((smenu '(("name" . "-Ahl")\r
-                ("mdate" . "-Ahlt")\r
-                ("adate" . "-Ahltu")\r
-                ("size" . "-AhlS")\r
-                ("dir" . "-Ahl --group-directories-first")))\r
-       ssortBy)\r
-    (setq ssortBy (completing-read "Sort by (default name):"\r
-                                  smenu\r
-                                  nil\r
-                                  t\r
-                                  nil\r
-                                  nil\r
-                                  (caar smenu)))\r
-    (dired-sort-other (cdr (assoc ssortBy smenu)))))\r
-\r
-(defun re/open-file-external (file)\r
-  "Open a file in an external program."\r
-  (interactive)\r
-  (let ((process-connection-type nil))\r
-    (cond ((eq system-type 'windows-nt)\r
-          (w32-shell-execute "open"\r
-                             (replace-regexp-in-string "/" "\\\\" file t t)))\r
-         ((eq system-type 'gnu/linux)\r
-          (start-process "" nil "xdg-open" file))\r
-         (t (error "Unable to automatically open this file")))))\r
-\r
-(defun re/dired-open-externally ()\r
-  "Open the file at point in an external program."\r
-  (interactive)\r
-  (re/open-file-external (dired-get-filename)))\r
-\r
-(defun re/dired-open-marked-externally ()\r
-  "Open all marked files from `dired' in an external program."\r
-  (interactive)\r
-  (mapc #'re/open-file-external (reverse (dired-get-marked-files))))\r
-\r
-(setq dired-listing-switches "-Ahl"\r
-      dired-vc-rename-file t\r
-      dired-auto-revert-buffer t\r
-      dired-hide-details-hide-symlink-targets nil\r
-      dired-kill-when-opening-new-dired-buffer t)\r
-\r
-(add-hook 'dired-mode-hook\r
-         (lambda ()\r
-           (keymap-set dired-mode-map "o" #'re/dired-display-direction)\r
-           (keymap-set dired-mode-map "z" #'dired-do-compress-to)\r
-           (keymap-set dired-mode-map "c" #'dired-do-chmod)\r
-           (keymap-set dired-mode-map "r" #'dired-do-rename)\r
-           (keymap-set dired-mode-map "M" #'dired-do-rename)\r
-           (keymap-set dired-mode-map "s" #'re/dired-sort)\r
-           (keymap-set dired-mode-map "F" #'re/dired-find-marked-files)\r
-           (keymap-set dired-mode-map "M-C" #'re/copy-with-mod-time)\r
-           (keymap-set dired-mode-map "b" #'re/dired-open-externally)\r
-           (keymap-set dired-mode-map "B" #'re/dired-open-marked-externally)\r
-           (dired-hide-details-mode t)\r
-           (hl-line-mode)))\r
-#+END_SRC\r
-* Bookmarks\r
-#+BEGIN_SRC emacs-lisp\r
-(setq bookmark-save-flag 1)\r
-(keymap-global-set "<f7>" #'recentf-open-files)\r
-(keymap-global-set "C-x r B" #'bookmark-jump-other-window)\r
-#+END_SRC\r
-* GUI\r
-#+BEGIN_SRC emacs-lisp\r
-(load-theme 'eng-paper t)\r
-\r
-(if (equal system-type 'android)\r
-    (progn\r
-      (setq touch-screen-display-keyboard t)\r
-      (set-frame-parameter nil 'tool-bar-position 'bottom)\r
-      (define-key key-translation-map\r
-                 (kbd "<volume-up>")\r
-                 (kbd "C-i"))\r
-      (define-key key-translation-map\r
-                 (kbd "<volume-down>")\r
-                 'event-apply-meta-modifier)\r
-      (modifier-bar-mode 1)\r
-      (tool-bar-mode 1))\r
-  (progn\r
-    (menu-bar-mode -1)\r
-    (tool-bar-mode -1)))\r
-(set-scroll-bar-mode (if (eq system-type 'windows-nt) nil 'left))\r
-\r
-(setq frame-title-format "%b"\r
-      mouse-prefer-closest-glyph t\r
-      mouse-1-click-follows-link nil\r
-      focus-follows-mouse t\r
-      mouse-autoselect-window -0.25)\r
-\r
-(setq-default cursor-type 'hbar\r
-             cursor-in-non-selected-windows nil)\r
-#+END_SRC\r
-** Modeline\r
-*** Minions\r
-Remove all minor modes from the mode-line, and show /all/ of them in the minor mode menu.  Must come before the modeline customization to ensure =minions-mode-line-modes= is defined.\r
-#+BEGIN_SRC emacs-lisp\r
-(require 'minions)\r
-(minions-mode)\r
-\r
-(setq minions-mode-line-lighter "+")\r
-#+END_SRC\r
-*** Format\r
-#+BEGIN_SRC emacs-lisp\r
-(setq-default mode-line-format '(" "\r
-                                (:eval (propertize "%b"\r
-                                                   'face\r
-                                                   (when (buffer-modified-p)\r
-                                                     'mode-line-highlight)))\r
-                                " "\r
-                                mode-line-remote\r
-                                "  "\r
-                                minions-mode-line-modes\r
-                                (vc-mode vc-mode)\r
-                                mode-line-format-right-align\r
-                                (:eval (number-to-string (line-number-at-pos (point-max))))\r
-                                "L/%Ib (%l,%C) "))\r
-#+END_SRC\r
-** Pretty Symbols\r
-#+BEGIN_SRC emacs-lisp\r
-(setq prettify-symbols-alist '(("lambda" . 955)\r
-                              ("delta" . 120517)\r
-                              ("epsilon" . 120518)\r
-                              ("->" . 8594)\r
-                              ("<=" . 8804)\r
-                              (">=" . 8805)))\r
-\r
-(global-prettify-symbols-mode t)\r
-#+END_SRC\r
-* Parens\r
-Must be set after loading any theme\r
-#+BEGIN_SRC emacs-lisp\r
-(setq show-paren-delay 0\r
-      show-paren-style 'expression)\r
-\r
-(setq electric-pair-pairs '((?\" . ?\")\r
-                           (?\‘ . ?\’)\r
-                           (?\“ . ?\”)\r
-                           (?\{ . ?\})\r
-                           (?\< . ?\>)))\r
-#+END_SRC\r
-* Help\r
-#+BEGIN_SRC emacs-lisp\r
-(setq apropos-do-all t)\r
-#+END_SRC\r
-* UTF-8\r
-#+BEGIN_SRC emacs-lisp\r
-(prefer-coding-system 'utf-8-unix)\r
-(set-language-environment 'utf-8)\r
-#+END_SRC\r
-* Cleanup on write\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/flush-extra-lines ()\r
-  "Change all groups of blank lines to 1 blank line."\r
-  (interactive)\r
-  (save-excursion\r
-    (replace-regexp "^\n+"\r
-                   "\n"\r
-                   nil\r
-                   (point-min)\r
-                   (point-max))))\r
-\r
-(setq require-final-newline t)\r
-(add-hook 'before-save-hook #'re/flush-extra-lines)\r
-(add-hook 'before-save-hook #'whitespace-cleanup)\r
-(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)\r
-#+END_SRC\r
-* Pass-alike\r
-** Password generation\r
-#+BEGIN_SRC emacs-lisp\r
-(defconst *alphanumerics*\r
-  (mapcar #'char-to-string\r
-         (append (number-sequence ?a ?z)\r
-                 (number-sequence ?A ?Z)\r
-                 (number-sequence ?0 ?9)))\r
-  "List of strings of the upper/lower-case English alphabet, and the single-digit numbers.")\r
-\r
-(defconst *special-characters*\r
-  '("!" "?" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "."\r
-    "/" ":" ";" "<" "=" ">" "?" "@" "[" "]" "^" "_" "{"\r
-    "|" "}" "~")\r
-  "List of strings containing the special visible characters excluding \\ and \" .")\r
-\r
-(defun pw-get-char (&optional no-special-chars)\r
-  "Select a single character at random to be used in a password.\r
-If `no-special-chars' is t, use only alpha-numeric characters."\r
-  (let ((selected-charset (append *alphanumerics*\r
-                                 (when (null no-special-chars)\r
-                                   ,*special-characters*))))\r
-    (elt selected-charset (random (length selected-charset)))))\r
-\r
-(defun pw-get-chars (password-length &optional no-special-chars)\r
-  "Generate a list of characters as strings to be made into a password.\r
-If `no-special-chars' is t, use only alpha-numeric characters."\r
-  (append (list (pw-get-char no-special-chars))\r
-         (when (> password-length 1)\r
-           (pw-get-chars (- password-length 1) no-special-chars))))\r
-\r
-(defun generate-password (password-length &optional no-special-chars)\r
-  "Combine a list of randomly-selected characters into a single string of length given.\r
-calls `pw-get-chars'.  If `no-special-chars' is `t', use only alpha-numeric characters."\r
-  (apply #'concat (pw-get-chars password-length no-special-chars)))\r
-\r
-(defun insert-generated-password (&optional password-length)\r
-  "Insert a generated password into the current buffer.\r
-Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'."\r
-  (interactive "p")\r
-  (let ((len (if (or (null password-length) (= 1 (abs password-length)))\r
-                16\r
-              (abs password-length)))\r
-       (no-special-p (and (numberp password-length) (< password-length 0))))\r
-    (insert (generate-password len no-special-p))))\r
-#+END_SRC\r
-** Get a password from a pass(1) entry\r
-Assume the password is on the first line.\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/get-line-from-file (file-path line-number)\r
-  "Return the specified LINE-NUMBER from FILE-PATH as a string.\r
-Start from bottom if given a negative line number."\r
-  (with-temp-buffer\r
-    (insert-file-contents file-path)\r
-    (if (< line-number 0)\r
-       (progn\r
-         (goto-char (point-max))\r
-         (forward-line line-number))\r
-      (progn\r
-       (goto-char (point-min))\r
-       (forward-line (1- line-number))))\r
-    (buffer-substring-no-properties (line-beginning-position) (line-end-position))))\r
-\r
-(defun get-password (&optional filename)\r
-  "Return a password given a file where it is stored.\r
-Assumes same structure as `pass(1)'."\r
-  (re/get-line-from-file (keyfile-string filename) 1))\r
-\r
-(defun password-to-clipboard (&optional filename)\r
-  "Copy the returned password to the clipboard."\r
-  (interactive)\r
-  (kill-new (get-password filename)))\r
-#+END_SRC\r
-** TOTP\r
-Generate TOTP tokens, generate the codes, put them on the clipboard.  Assumes the format of pass(1), where the TOTP token is the last line in the file.\r
-#+BEGIN_SRC emacs-lisp\r
-(dolist (requirement '(bindat gnutls hexl auth-source))\r
-  (require requirement))\r
-\r
-(defun totp--hex-decode-string (string)\r
-  "Hex-decode STRING and return the result as a unibyte string."\r
-  (apply #'unibyte-string\r
-        (seq-map (lambda (s) (hexl-htoi (aref s 0) (aref s 1)))\r
-                 (seq-partition string 2))))\r
-\r
-(defun totp (string &optional time digits)\r
-  "Return a TOTP token using the secret hex STRING and current time.\r
-TIME is used as counter value instead of current time, if non-nil.\r
-DIGITS is the number of pin digits and defaults to 6."\r
-  (let* ((key-bytes (totp--hex-decode-string (upcase string)))\r
-        (counter (truncate (/ (or time (time-to-seconds)) 30)))\r
-        (digits (or digits 6))\r
-        (format-string (format "%%0%dd" digits))\r
-        ;; we have to manually split the 64 bit number (u64 not supported in Emacs 27.2)\r
-        (counter-bytes (bindat-pack  '((:high u32) (:low u32))\r
-                                     `((:high . ,(ash counter -32)) (:low . ,(logand counter #xffffffff)))))\r
-        (mac (gnutls-hash-mac 'SHA1 key-bytes counter-bytes))\r
-        (offset (logand (bindat-get-field (bindat-unpack '((:offset u8)) mac 19) :offset) #xf)))\r
-    (format format-string\r
-           (mod\r
-            (logand (bindat-get-field (bindat-unpack '((:totp-pin u32)) mac  offset) :totp-pin)\r
-                    #x7fffffff)\r
-            (expt 10 digits)))))\r
-\r
-(defconst base32-alphabet\r
-  (let ((tbl (make-char-table nil)))\r
-    (dolist (mapping '(("A" . 0) ("B" . 1) ("C" . 2) ("D" . 3)\r
-                      ("E" . 4) ("F" . 5) ("G" . 6)\r
-                      ("H" . 7) ("I" . 8) ("J" . 9) ("K" . 10)\r
-                      ("L" . 11) ("M" . 12) ("N" . 13)\r
-                      ("O" . 14) ("P" . 15) ("Q" . 16) ("R" . 17)\r
-                      ("S" . 18) ("T" . 19) ("U" . 20)\r
-                      ("V" . 21) ("W" . 22) ("X" . 23) ("Y" . 24)\r
-                      ("Z" . 25) ("2" . 26) ("3" . 27)\r
-                      ("4" . 28) ("5" . 29) ("6" . 30) ("7" . 31)))\r
-      (aset tbl (string-to-char (car mapping)) (cdr mapping)))\r
-    tbl)\r
-  "Base-32 mapping table, as defined in RFC 4648.")\r
-\r
-(defun base32-hex-decode (string)\r
-  "The cheats' version of base-32 decode.\r
-\r
-This is not a 100% faithful implementation of RFC 4648. The\r
-concept of encoding partial quanta is not implemented fully.\r
-\r
-No attempt is made to pad the output either as that is not\r
-required for HMAC-TOTP."\r
-  (unless (mod (length string) 8)\r
-    (error "Padding is incorrect"))\r
-  (setq string (upcase string))\r
-  (let ((trimmed-array (append (string-trim-right string "=+") nil)))\r
-    (format "%X" (seq-reduce\r
-                 (lambda (acc char) (+ (ash acc 5) (aref base32-alphabet char)))\r
-                 trimmed-array 0))))\r
-\r
-(defun keyfile-string (filename)\r
-  "Return a string which is the filepath to a `pass(1)' file."\r
-  (let ((directory "~/.password-store/"))\r
-    (if (null filename)\r
-       (read-file-name "Select a password: " directory nil t nil)\r
-      (concat directory\r
-             (if (stringp filename)\r
-                 filename\r
-               (symbol-name filename))\r
-             ".gpg"))))\r
-\r
-(defun get-totp (&optional filename)\r
-  "Generate a totp code given a file with the secret hex string.\r
-If no filename given, prompt for one.\r
-Assumes the file has the string by itself on the last line of the file,\r
-similar to what pass-otp does, but without the full uri.\r
-Also assumes the file is in `~/.password-store' and has the `.gpg' extension."\r
-  (totp (base32-hex-decode (re/get-line-from-file (keyfile-string filename) -1))))\r
-\r
-(defun otp-to-clipboard (&optional filename)\r
-  "Copy the returned totp code to the clipboard."\r
-  (interactive)\r
-  (kill-new (get-totp filename)))\r
-#+END_SRC\r
-* Control\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/kill-emacs ()\r
-  "Save all open files and kill emacs."\r
-  (interactive)\r
-  (save-some-buffers t)\r
-  (kill-emacs))\r
-\r
-(keymap-global-set "C-x M-c" #'re/kill-emacs)\r
-\r
-(defun re/restart-emacs ()\r
-  "Save all open files and restart emacs."\r
-  (interactive)\r
-  (save-some-buffers t)\r
-  (kill-emacs nil t))\r
-\r
-(keymap-global-set "C-x M-r" #'re/restart-emacs)\r
-\r
-(defun re/keyboard-quit ()\r
-  "Smarter version of `keyboard-quit'.\r
-Close the minibuffer if not focused when hit.\r
-Stolen from emacsredux.com."\r
-  (interactive)\r
-  (if (active-minibuffer-window)\r
-      (if (minibufferp)\r
-         (minibuffer-keyboard-quit)\r
-       (abort-recursive-edit))\r
-    (keyboard-quit)))\r
-\r
-(keymap-global-set "<remap> <keyboard-quit>" #'re/keyboard-quit) ; Make C-g better\r
-(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask\r
-(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files\r
-#+END_SRC\r
-* Version-control mode\r
-#+BEGIN_SRC emacs-lisp\r
-(defun re/vc-clone ()\r
-  "Interactively clone with vc-mode.\r
-Prompt for url and local dir."\r
-  (interactive)\r
-  (let* ((url (read-string "Repository URL: "))\r
-        (dir (read-string "Local Dir: " (file-name-base url))))\r
-    (vc-git-clone url dir nil)))\r
-\r
-(keymap-global-set "C-x v C" #'re/vc-clone)\r
-\r
-(defun re/vc-show-branches (&optional arg)\r
-  "Display all Git branches in a separate buffer.\r
-Remotes as well when arg."\r
-  (interactive "P")\r
-  (let ((default-directory (if (boundp 'vc-dir-directory)\r
-                              vc-dir-directory\r
-                            default-directory)))\r
-    (vc-git-command "*git-branches*"\r
-                   nil\r
-                   nil\r
-                   "branch"\r
-                   "--verbose"\r
-                   (when arg "--remotes"))\r
-    (pop-to-buffer "*git-branches*")\r
-    (goto-char (point-min))\r
-    (special-mode)))\r
-\r
-(keymap-global-set "C-x v b b" #'re/vc-show-branches)\r
-\r
-(defun re/vc-fetch (&optional arg)\r
-  "Interactively fetch with vc-mode.\r
-Allows separate fetch in addition to pull.  Only care about git.\r
-With arg, ask for remote, otherwise fetch all."\r
-  (interactive "P")\r
-  (let* ((default-directory (if (boundp 'vc-dir-directory)\r
-                               vc-dir-directory\r
-                             default-directory)))\r
-    (vc-git-command "*vc-fetch*"\r
-                   nil\r
-                   nil\r
-                   "fetch"\r
-                   (if arg\r
-                       (read-string "Fetch From: " "origin")\r
-                     "--all")\r
-                   "--verbose")\r
-    (pop-to-buffer "*vc-fetch*")\r
-    (goto-char (point-min))\r
-    (special-mode)))\r
-\r
-(keymap-global-set "C-x v f" #'re/vc-fetch)\r
-\r
-(add-hook 'vc-dir-mode-hook\r
-         (lambda ()\r
-           (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches)\r
-           (keymap-set vc-dir-mode-map "f" #'re/vc-fetch)\r
-           (keymap-set vc-dir-mode-map "k" #'vc-revert)))\r
-\r
-(setq vc-make-backup-files nil\r
-      vc-handled-backends '(jj Git)\r
-      vc-git-log-switches '("--oneline" "--graph" "--decorate" "--all")\r
-      vc-git-log-edit-summary-target-len 50\r
-      vc-find-revision-no-save t)\r
-#+END_SRC\r
-* Backups\r
-#+BEGIN_SRC emacs-lisp\r
-(setq backup-directory-alist `((".*" . "~/emacs-backups/"))\r
-      backup-by-copying t\r
-      delete-old-versions t\r
-      kept-new-versions 5\r
-      kept-old-versions 5)\r
-#+END_SRC\r
-* Any Lisp Repl\r
-#+BEGIN_SRC emacs-lisp\r
-(defmacro re/send-on-close-paren (executor)\r
-  "Generalizes sending an execute on close paren.\r
- Interactively call `executor'.  For `executor', use whatever\r
- function is called by `<RET>' in the applicable REPL.  For a\r
- non-repl, use `newline' or similar."\r
-  `(lambda (&optional arg)\r
-     (interactive "p")\r
-     (insert-char 41 arg)\r
-     (call-interactively ,executor)))\r
-\r
-(defun re/sexp-drop-paren-p ()\r
-  "Returns t if sexp needs fewer parens to balance."\r
-  (< (car (syntax-ppss)) 0))\r
-\r
-(defun re/sexp-need-paren-p ()\r
-  "Returns t if sexp needs more parens to balance."\r
-  (> (car (syntax-ppss)) 0))\r
-\r
-(defun re/sexp-unbalanced-count ()\r
-  "Returns distance from balanced sexp."\r
-  (abs (car (syntax-ppss))))\r
-\r
-(defun re/balance-sexp ()\r
-  "Balance the sexp before point.\r
-Either delete, move forward, or add as many ')' as needed."\r
-  (let ((distance (re/sexp-unbalanced-count)))\r
-    (cond ((re/sexp-need-paren-p)\r
-          (if (looking-at ")")\r
-              (progn\r
-                (forward-char)\r
-                (re/balance-sexp))\r
-            (insert-char 41 distance)))\r
-         ((re/sexp-drop-paren-p)\r
-          (backward-delete-char distance)))))\r
-\r
-(defmacro re/balance-and-eval-sexp (executor)\r
-  "Balance the sexp before point, then call `executor'.\r
-Call `re/balance-sexp', then interactively call `executor'.  Bind\r
-this to ']' for the interlisp experience.  For `executor', use\r
-whatever function is called by `<RET>' in the applicable REPL.\r
-For a non-repl, use `newline' or similar."\r
-  `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor)))\r
-\r
-(defvar *re/lisp-mode-hooks*\r
-  '(emacs-lisp-mode-hook\r
-    lisp-mode-hook\r
-    sly-mode-hook\r
-    scheme-mode-hook\r
-    geiser-mode-hook\r
-    lisp-interaction-mode-hook))\r
-\r
-(dolist (hook *re/lisp-mode-hooks*)\r
-  (add-hook hook\r
-           (lambda ()\r
-             (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1))\r
-             (sedit-mouse-mode 1)\r
-             (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region)\r
-             (keymap-set lisp-mode-shared-map\r
-                         "C-M-S-q"\r
-                         #'sedit-auto-prettify-sexp)\r
-             (keymap-set lisp-mode-shared-map\r
-                         "]"\r
-                         (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp))\r
-             (keymap-set lisp-interaction-mode-map\r
-                         "]"\r
-                         (re/balance-and-eval-sexp #'eval-print-last-sexp)))))\r
-#+END_SRC\r
-* IELM\r
-Rarely used, but nice to have when I want it.\r
-#+BEGIN_SRC emacs-lisp\r
-(add-hook 'ielm-mode-hook\r
-         (lambda ()\r
-           (keymap-set inferior-emacs-lisp-mode-map\r
-                       "C-l"\r
-                       #'comint-clear-buffer)\r
-           (let ((eval-function #'ielm-send-input))\r
-             (keymap-set inferior-emacs-lisp-mode-map\r
-                         ")"\r
-                         (re/send-on-close-paren eval-function))\r
-             (keymap-set inferior-emacs-lisp-mode-map\r
-                         "]"\r
-                         (re/balance-and-eval-sexp eval-function)))))\r
-#+END_SRC\r
-* Eshell\r
-#+BEGIN_SRC emacs-lisp\r
-(keymap-global-set "C-c e" #'eshell)\r
-\r
-(defun eshell-quit-or-delete-char (arg)\r
-  "Delete char if at one, quit eshell if on empty prompt.\r
-Stolen from https://depp.brause.cc/dotemacs"\r
-  (interactive "p")\r
-  (if (and (eolp) (looking-back eshell-prompt-regexp 0 t))\r
-      (eshell-life-is-too-much)\r
-    (delete-char arg)))\r
-\r
-(add-hook 'eshell-mode-hook\r
-         (lambda ()\r
-           (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char)\r
-           (let ((eval-function #'eshell-send-input))\r
-             (keymap-set eshell-mode-map\r
-                         ")"\r
-                         (re/send-on-close-paren eval-function))\r
-             (keymap-set eshell-mode-map\r
-                         "]"\r
-                         (re/balance-and-eval-sexp eval-function)))))\r
-#+END_SRC\r
-* C-mode\r
-#+BEGIN_SRC emacs-lisp\r
-(dolist (mode-maps '(("\\.keymap\\'" . c-mode) ("\\.dtsi\\'" . c-mode)))\r
-  (add-to-list 'auto-mode-alist mode-maps t))\r
-\r
-(defun re/c-lineup-arglist-tabs-only (ignored)\r
-  "Line up argument lists by tabs, not spaces.\r
- Stolen from https://kernel.org/doc/html/v4.10/process/coding-style.html"\r
-  (let* ((anchor (c-langelem-pos c-syntactic-element))\r
-        (column (c-langelem-2nd-pos c-syntactic-element))\r
-        (offset (- (1+ column) anchor))\r
-        (steps (floor offset c-basic-offset)))\r
-    (* (max steps 1) c-basic-offset)))\r
-\r
-(add-hook 'c-mode-common-hook\r
-         (lambda ()\r
-           (c-add-style "linux-tabs-only"\r
-                        '("linux" (c-offsets-alist\r
-                                   (arglist-cont-nonempty\r
-                                    c-lineup-gcc-asm-reg\r
-                                    re/c-lineup-arglist-tabs-only))))))\r
-\r
-(add-hook 'c-mode-hook\r
-         (lambda ()\r
-           (setq c-backspace-function 'backward-delete-char)\r
-           (c-set-style "linux-tabs-only")))\r
-#+END_SRC\r
-* Auto-Revert\r
-#+BEGIN_SRC emacs-lisp\r
-(global-auto-revert-mode)\r
-(setq global-auto-revert-non-file-buffers nil)\r
-#+END_SRC\r
-* Crash HandliƋ\r
-#+BEGIN_SRC emacs-lisp\r
-(setq attempt-stack-overflow-recovery nil\r
-      attempt-orderly-shutdown-on-fatal-signal nil)\r
-#+END_SRC\r
-* Abbrev-mode and skeletons\r
-#+BEGIN_SRC emacs-lisp\r
-(define-skeleton workorder-link\r
-  "part of a link to a workorder, just enter the number."\r
-  ""\r
-  "https://eservice.r717.net/index.php/PLC_workorders/store/"\r
-  _ -)\r
-\r
-(define-skeleton skel-org-block\r
-  "Add a source block to an org file."\r
-  ""\r
-  "#+BEGIN_SRC"\r
-  \n\r
-  _ -\r
-  \n\r
-  "#+END_SRC")\r
-\r
-(define-skeleton skel-org-block-elisp\r
-  "Add an elisp source block to an org file."\r
-  ""\r
-  "#+BEGIN_SRC emacs-lisp"\r
-  \n\r
-  _ -\r
-  \n\r
-  "#+END_SRC")\r
-\r
-(setq save-abbrevs 'silently)\r
-\r
-(add-hook 'org-mode-hook #'abbrev-mode)\r
-#+END_SRC\r
-* Customization Framework\r
-Disable it by making it save to a temp file (stolen from prot)\r
-#+BEGIN_SRC emacs-lisp\r
-(setq custom-file (make-temp-file "emacs-custom-"))\r
-#+END_SRC\r
diff --git a/init.el b/init.el
index 0b4d6404320a024f5d76cc0e1a168685d84012ef..0c968f9873527e2f6e49b013aee01fdf3f96e5f4 100644 (file)
--- a/init.el
+++ b/init.el
-;;; init.el --- Emacs Configuration  -*- lexical-binding: t; -*-
-
-;; This file is not part of GNU emacs
-
-;;; Code:
-
-(org-babel-load-file "~/.emacs.d/config.org")
-
-;;; init.el ends here
+;;;; init.el --- Emacs Configuration  -*- lexical-binding: t; -*-\r
+\r
+;;; OS specific stuff\r
+\r
+(setq w32-recognize-altgr 'nil)\r
+\r
+(unless (equal system-type 'windows-nt)\r
+  (setq trash-directory "~/Trash/")\r
+  (defun doas ()\r
+    "Use TRAMP to reopen the current buffer as root using doas."\r
+    (interactive)\r
+    (when buffer-file-name\r
+      (find-alternate-file (concat "/doas:root@localhost:" buffer-file-name))))\r
+  (defun sudo ()\r
+    "Use TRAMP to reopen the current buffer as root using sudo."\r
+    (interactive)\r
+    (when buffer-file-name\r
+      (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))))\r
+\f\r
+;;; PACKAGES\r
+;; Add melpa, initialize\r
+\r
+(require 'package)\r
+\r
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)\r
+(package-initialize)\r
+\r
+;; Install all packages that are not included\r
+\r
+(defvar *re/packages*\r
+  '(corfu\r
+    expand-region\r
+    page-break-lines\r
+    pdf-tools\r
+    auctex\r
+    csv-mode\r
+    markdown-mode\r
+    edit-indirect\r
+    sly\r
+    geiser\r
+    geiser-chicken\r
+    forth-mode\r
+    trashed\r
+    org-transclusion\r
+    vc-jj\r
+    minions)\r
+  "The list of packages I want to always install")\r
+\r
+(dolist (pkg *re/packages*)\r
+  (unless (package-installed-p pkg)\r
+    (package-refresh-contents)\r
+    (package-install pkg)))\r
+\f\r
+;; Corfu\r
+\r
+(require 'corfu)\r
+\r
+(setq corfu-auto t\r
+      corfu-auto-delay 0\r
+      corfu-auto-prefix 1)\r
+\r
+(add-hook 'corfu-mode-hook #'corfu-popupinfo-mode)\r
+\r
+(setq corfu-popupinfo-delay '(1.0 . 0.01) ; start after one second, fast refresh once on\r
+      corfu-popupinfo-hide nil)\r
+\r
+(global-corfu-mode)\r
+\f\r
+;; Expand Region\r
+\r
+(require 'expand-region)\r
+\r
+(keymap-global-set "C-=" #'er/expand-region)\r
+\f\r
+;; Page Break Lines\r
+\r
+(require 'page-break-lines)\r
+(global-page-break-lines-mode)\r
+\f\r
+;; PDFtools\r
+;; Be sure to run `pdf-tools-install' before first run\r
+\r
+(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-tools-install))\r
+\r
+(setq-default pdf-view-display-size 'fit-page)\r
+\r
+;; Auctex\r
+\r
+(setq-default TeX-master nil)\r
+\r
+(setq TeX-auto-save t\r
+      TeX-parse-self t\r
+      TeX-PDF-mode t\r
+      TeX-view-program-selection '((output-pdf "PDF Tools"))\r
+      TeX-source-correlate-start-server t)\r
+\r
+(add-hook 'TeX-after-compilation-finished-functions\r
+         #'TeX-revert-document-buffer)\r
+\f\r
+;; CSV Mode\r
+\r
+(add-hook 'csv-mode-hook 'csv-align-mode)\r
+\f\r
+;; Markdown Mode\r
+;; Make markdown act more like org when I'm forced to use it\r
+\r
+(setq markdown-special-ctrl-a/e t)\r
+\r
+(with-eval-after-load 'markdown-mode\r
+    (keymap-set markdown-mode-map "M-<right>" #'markdown-demote)\r
+    (keymap-set markdown-mode-map "M-<left>" #'markdown-promote)\r
+    (keymap-set markdown-mode-map "M-<up>" #'markdown-move-up)\r
+    (keymap-set markdown-mode-map "M-<down>" #'markdown-move-down)\r
+    (keymap-set markdown-mode-map "C-M-u" #'markdown-up-heading)\r
+    (keymap-set markdown-mode-map "C-M-b" #'markdown-outline-previous-same-level)\r
+    (keymap-set markdown-mode-map "C-M-f" #'markdown-outline-next-same-level)\r
+    (keymap-set markdown-mode-map "C-M-p" #'markdown-outline-previous)\r
+    (keymap-set markdown-mode-map "C-M-n" #'markdown-outline-next))\r
+\f\r
+;; Sly\r
+\r
+(defun re/sly-repl-new-frame (&optional arg)\r
+  "Start a SLY repl in a new frame."\r
+  (interactive "P")\r
+  (re/open-with-new-frame "SLY" #'sly))\r
+\r
+(defun re/sly-quit-current-lisp ()\r
+  "Quit the current lisp repl connection without prompting."\r
+  (interactive)\r
+  (sly-quit-lisp nil nil))\r
+\r
+(defun re/sly-connect-stump (&optional arg)\r
+  "Connect to my typical stumpwm instance."\r
+  (interactive "P")\r
+  (sly-connect "localhost" 4004))\r
+\r
+(setq inferior-lisp-program "sbcl"\r
+      sly-net-coding-system 'utf-8-unix\r
+      sly-command-switch-to-existing-lisp 'always)\r
+\r
+(let ((core (expand-file-name "~/sbcl.core-for-sly")))\r
+  (when (file-exists-p core)\r
+    (setq sly-lisp-implementations (list `(sbcl ("sbcl" "--core" ,core))))))\r
+\r
+(with-eval-after-load 'sly-mrepl\r
+  (keymap-set sly-mrepl-mode-map ")" (re/send-on-close-paren #'sly-mrepl-return))\r
+  (keymap-set sly-mrepl-mode-map "]" (re/balance-and-eval-sexp #'sly-mrepl-return))\r
+  (keymap-set sly-mrepl-mode-map "C-c q" #'re/sly-quit-current-lisp))\r
+\f\r
+;; Eldoc settings\r
+;; Sly really doesn't play well with elodc in the minibuffer,\r
+;; so here are some settings to make it better.\r
+\r
+(add-to-list 'display-buffer-alist\r
+            '("^\\*eldoc" display-buffer-in-direction\r
+              (direction . 'down)\r
+              (window-height . 4)))\r
+(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer\r
+(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed\r
+\f\r
+;; Geiser\r
+\r
+(if (equal system-type 'windows-nt)\r
+    (setq geiser-chicken-binary '("C:/tools/chicken/bin/csi.exe" "-:c"))\r
+  (setq geiser-chicken-binary "csi -:c"))\r
+\r
+(setq scheme-program-name geiser-chicken-binary\r
+      geiser-active-implementations '(chicken))\r
+\r
+(add-hook 'scheme-mode-hook 'geiser-mode)\r
+\r
+(with-eval-after-load 'geiser-repl\r
+    (keymap-set geiser-repl-mode-map ")" (re/send-on-close-paren #'geiser-repl-maybe-send))\r
+    (keymap-set geiser-repl-mode-map "]" (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))\r
+\r
+;; Set bindings, things that have to happen after loading\r
+\r
+(with-eval-after-load 'org\r
+    (require 'org-mouse)\r
+    (add-to-list 'org-export-backends 'md)\r
+    (keymap-set org-mode-map "C-M-h" #'org-mark-subtree)\r
+    (keymap-set org-mode-map "C-M-u" #'org-up-element)\r
+    (keymap-set org-mode-map "C-M-d" #'org-down-element)\r
+    (keymap-set org-mode-map "C-M-b" #'org-backward-heading-same-level)\r
+    (keymap-set org-mode-map "C-M-f" #'org-forward-heading-same-level)\r
+    (keymap-set org-mode-map "C-M-p" #'org-previous-visible-heading)\r
+    (keymap-set org-mode-map "C-M-n" #'org-next-visible-heading)\r
+    (keymap-set org-mode-map "C-c t" #'org-transclusion-mode))\r
+\r
+(keymap-global-set "C-c l" #'org-store-link)\r
+(keymap-global-set "C-c a" #'org-agenda)\r
+(keymap-global-set "C-c c" #'org-capture)\r
+\f\r
+;; Org-Mode\r
+;; General options\r
+\r
+(setq org-M-RET-may-split-line nil\r
+      org-cycle-inline-images-display t\r
+      org-cycle-separator-lines -1\r
+      org-ellipsis "->"\r
+      org-enforce-todo-checkbox-dependencies t\r
+      org-enforce-todo-dependencies t\r
+      org-goto-interface 'outline-path-completion\r
+      org-outline-path-complete-in-steps nil\r
+      org-src-fontify-natively nil\r
+      org-return-follows-link t\r
+      org-reverse-note-order t\r
+      org-special-ctrl-a/e t\r
+      org-special-ctrl-k t\r
+      org-src-preserve-indentation t\r
+      org-startup-folded 'fold\r
+      org-tags-column 0\r
+      org-yank-adjusted-subtrees t\r
+      org-refile-use-outline-path 'file\r
+      org-refile-allow-creating-parent-nodes 'confirm)\r
+\r
+;; Agenda settings\r
+\r
+  (setq org-agenda-files (append '("~/org/")\r
+                              (file-expand-wildcards "~/projects/*/"))\r
+       org-refile-targets '((nil :maxlevel . 9)\r
+                          (org-agenda-files :maxlevel . 9))\r
+       org-todo-keywords '((sequence "TODO(t)" "WAITING(w@)" "|" "DONE(d)" "BELAYED(b@)" "GIVEN(g@)"))\r
+       org-todo-keyword-faces '(("WAITING" :foreground "#e85400" :weight bold)) ; alert orange\r
+       org-agenda-prefix-format '((agenda . "          %?-12t%? s")\r
+                                (todo . " ")\r
+                                (tags . " ")\r
+                                (search . " "))\r
+       org-agenda-start-on-weekday nil\r
+       org-read-date-prefer-future 'time\r
+       org-log-done 'time\r
+       org-log-redeadline 'time\r
+       org-log-reschedule 'time\r
+       org-log-state-notes-insert-after-drawers t\r
+       org-agenda-window-setup 'current-window)\r
+\r
+;; Stuck Projects\r
+\r
+(setq org-stuck-projects '("CATEGORY=\"undertakings\"+LEVEL=1/-DONE-GIVEN-BELAYED" ("TODO" "WAITING") nil ""))\r
+\r
+;; Custom Agendas\r
+\r
+  (defvar *re/org-agenda-inbox*\r
+    '(tags "CATEGORY=\"inbox\"" ((org-agenda-overriding-header ""))))\r
+\r
+  (defvar *re/org-agenda-todo*\r
+    '(tags-todo "-recurring/TODO" ((org-agenda-overriding-header ""))))\r
+\r
+  (defvar *re/org-agenda-undertakings*\r
+    '(tags "CATEGORY=\"undertakings\"+LEVEL=1" ((org-agenda-overriding-header ""))))\r
+\r
+  (defvar *re/org-agenda-waiting*\r
+    '(todo "WAITING" ((org-agenda-overriding-header ""))))\r
+\r
+(defvar *re/org-agenda-done*\r
+  '(tags "-recurring+LEVEL=1/DONE|BELAYED|GIVEN"))\r
+\r
+  (setq org-agenda-custom-commands `(("i" "Inbox" ,@*re/org-agenda-inbox*)\r
+                                          ("n" "Next Actions" ,@*re/org-agenda-todo*)\r
+                                          ("u" "Undertakings" ,@*re/org-agenda-undertakings*)\r
+                                          ("w" "Waiting" ,@*re/org-agenda-waiting*)\r
+                                          ("d" "Done" ,@*re/org-agenda-done*)))\r
+\r
+;; Capture Templates\r
+\r
+  (setq org-capture-templates '(("i" "Inbox" entry\r
+                              (file "inbox.org")\r
+                              "* %^{Description}\n%U\n%?"\r
+                              :prepend t)\r
+                             ("n" "Next Action" entry\r
+                              (file "next.org")\r
+                              "* TODO %^{Description}\nTaken: %T\n%?"\r
+                              :prepend t)\r
+                             ("u" "Undertaking" entry\r
+                              (file "undertakings.org")\r
+                              "* %^{Description} [/]\nTaken: %T\n%?"\r
+                              :prepend t)\r
+                             ("m" "Meeting" entry\r
+                              (file "meetings.org")\r
+                              "* %^{Description}\n%^{Scheduled:}T\n%?"\r
+                              :prepend t)\r
+                             ("p" "Phone Call" entry\r
+                              (file "inbox.org")\r
+                              "* %^{Description} :call:\n%T\n%?"\r
+                              :prepend t)\r
+                             ("t" "Note" entry\r
+                              (file "notes.org")\r
+                              "* %^{Description}\n%U\n%?"\r
+                              :prepend t)))\r
+\r
+;; IDs\r
+\r
+(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id\r
+      org-id-method 'ts\r
+      org-clone-delete-id t\r
+      org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format\r
+                                           org-attach-id-uuid-folder-format))\r
+\r
+(defun re/org-save-all ()\r
+  "Save all `org-agenda-files' without user confirmation."\r
+  (interactive)\r
+  (message "Saving all org-agenda-files buffers...")\r
+  (save-some-buffers t\r
+                    (lambda ()\r
+                      (when (member (buffer-file-name) org-agenda-files) t)))\r
+  (message "Saving all org-agenda-files buffers... done"))\r
+\r
+(advice-add 'org-refile :after (lambda (&rest _) (re/org-save-all)))\r
+\r
+;; Archiving\r
+\r
+(setq org-archive-location (concat "~/org/old.org_keep::datetree/")\r
+      org-agenda-text-search-extra-files '(agenda-archives))\r
+\r
+(add-to-list 'auto-mode-alist '("\\.org_keep\\'" . org-mode))\r
+\r
+;; Converting markdown to org\r
+\r
+(defun re/markdown-to-org-region (start end)\r
+  "Convert Markdown formatted text in region (START, END) to Org.\r
+This command requires that pandoc (man page `pandoc(1)') be\r
+installed."\r
+  (interactive "r")\r
+  (shell-command-on-region\r
+   start end\r
+   "pandoc -f markdown -t org --wrap=preserve" t t))\r
+\r
+;; Converting org to markdown\r
+\r
+(defun re/org-to-markdown-region (start end)\r
+  "Convert Org formatted text in region (START, END) to Markdown.\r
+This command requires that pandoc (man page `pandoc(1)') be\r
+installed."\r
+  (interactive "r")\r
+  (shell-command-on-region\r
+   start end\r
+   "pandoc -f org -t markdown --wrap=preserve" t t))\r
+\f\r
+;; Trashed\r
+;; Shows the trash file as a dired buffer\r
+\r
+(setq trashed-action-confirmer 'y-or-n-p\r
+       trashed-use-header-line t\r
+       trashed-sort-key '("Date deleted" . t)\r
+       trashed-date-format "%Y-%m-%d %H:%M:%S")\r
+\f\r
+;; Use mu4e on my home pcs\r
+\r
+(when (eq system-type 'gnu/linux)\r
+  (with-eval-after-load 'mu4e\r
+    (setq mail-user-agent 'message-user-agent\r
+         message-send-mail-function 'smtpmail-send-it\r
+         message-citation-line-format "Quoth %f :\n"\r
+         smtpmail-default-smtp-server "mail.earman.xyz"\r
+         smtpmail-smtp-server "mail.earman.xyz"\r
+         smtpmail-smtp-service 587\r
+         smtpmail-stream-type 'starttls\r
+         smtpmail-local-domain "earman.xyz"\r
+         smtpmail-queue-mail nil\r
+         smtpmail-queue-dir "~/mail/Outbox/cur"\r
+         user-mail-address "iv@earman.xyz"\r
+         user-full-name "Rush N. Earman IV"\r
+         message-signature "Rush Earman IV, PE"\r
+         message-kill-buffer-on-exit t\r
+         mu4e-get-mail-command "mbsync -a"\r
+         mu4e-update-interval (* 10 60)\r
+         mu4e-change-filenames-when-moving t\r
+         mu4e-use-fancy-chars t\r
+         mu4e-attachment-dir "~/downloads"\r
+         mu4e-compose-reply-to-address "iv@earman.xyz"\r
+         mu4e-maildir "~/mail"\r
+         mu4e-drafts-folder "/Drafts"\r
+         mu4e-sent-folder "/Sent"\r
+         mu4e-trash-folder "/Trash"\r
+         mu4e-maildir-shortcuts '((:maildir "/Inbox" :key ?i)\r
+                                  (:maildir "/Sent" :key ?s)\r
+                                  (:maildir "/Trash" :key ?t)\r
+                                  (:maildir "/Drafts" :key ?d)))))\r
+\f\r
+;;; Load libraries Not from the package manager\r
+\r
+(dolist (path '("sedit-mouse/" "themes/"))\r
+  (add-to-list 'load-path (concat user-emacs-directory path)))\r
+\r
+(dolist (file '(eng-paper-theme sedit-mouse))\r
+  (require file))\r
+\f\r
+;;; UNIX/vi-like bindings\r
+;; =C-h=, =C-w=, =C-u=, et. al to work as I expect (like acme).\r
+;; Some functions get re-bound when these take over a default.\r
+\r
+(defun re/open-line-below (n)\r
+  "Creates a new empty line below the current line and moves to it."\r
+  (interactive "*p")\r
+  (end-of-line)\r
+  (open-line n)\r
+  (next-line 1)\r
+  (indent-for-tab-command))\r
+\r
+(keymap-global-set "C-o" #'re/open-line-below)\r
+\r
+(defun re/open-line-above (n)\r
+  "Creates a new empty line above the current line."\r
+  (interactive "*p")\r
+  (beginning-of-line)\r
+  (open-line n)\r
+  (indent-for-tab-command))\r
+\r
+(keymap-global-set "M-o" #'re/open-line-above)\r
+\r
+(defun re/kill-bword-or-region (&optional arg)\r
+  "Kill region if active, otherwise kill back one word."\r
+  (interactive "p")\r
+  (if (use-region-p)\r
+      (kill-region (region-beginning) (region-end))\r
+    (backward-kill-word arg)))\r
+\r
+(keymap-global-set "C-w" #'re/kill-bword-or-region)\r
+(keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards\r
+(keymap-global-set "C-S-U" #'universal-argument)\r
+(keymap-set key-translation-map "C-h" "<DEL>") ; Rather F1 for help, also C-S-H works\r
+(keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way\r
+(keymap-global-set "<home>" #'beginning-of-buffer)\r
+(keymap-global-set "<end>" #'end-of-buffer)\r
+\f\r
+;;; Commenting and defun-level bindings\r
+\r
+(defun re/comment-dwim (&optional arg)\r
+  "Comment region if active, otherwise comment line.\r
+  Stolen from https://depp.brause.cc/dotemacs"\r
+  (interactive "P")\r
+  (if (use-region-p)\r
+      (comment-or-uncomment-region (region-beginning) (region-end))\r
+    (comment-line arg)))\r
+\r
+(keymap-global-set "M-;" #'re/comment-dwim)\r
+\r
+(defun re/comment-defun (&optional arg)\r
+  "Mark a defun and comment it out.\r
+  Return to initial position after.  Arg works on `mark-defun'."\r
+  (interactive "P")\r
+  (save-excursion (mark-defun arg)\r
+                 (comment-region (region-beginning) (region-end))))\r
+\r
+(keymap-global-set "C-M-;" #'re/comment-defun)\r
+\r
+(defun re/kill-defun (&optional arg)\r
+  "Mark a defun and kill it.\r
+  Arg works on `mark-defun'."\r
+  (interactive "P")\r
+  (mark-defun arg)\r
+  (kill-region (region-beginning) (region-end)))\r
+\r
+(keymap-global-set "C-M-S-K" #'re/kill-defun)\r
+\f\r
+;;; Misc QOL bindings\r
+\r
+(keymap-global-set "<insert>" nil) ; I keep toggliƋ overwrite-mode haply\r
+(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes\r
+(keymap-global-set "C-S-K" #'kill-whole-line)\r
+(keymap-global-set "C-S-d" #'delete-pair)\r
+(keymap-global-set "C-z" #'zap-up-to-char)\r
+(keymap-global-set "C-c s" #'sort-lines)\r
+(keymap-global-set "<remap> <capitalize-word>" #'capitalize-dwim) ; M-c\r
+(keymap-global-set "<remap> <downcase-word>" #'downcase-dwim) ; M-l\r
+(keymap-global-set "<remap> <upcase-word>" #'upcase-dwim) ; M-u\r
+\f\r
+;;; Tabs\r
+;; I want *TABS*, not spaces, dammit.  Globally overwrite the tab key to\r
+;; insert the tab character.  This makes it so that many things (completion)\r
+;; will have to be triggered with =C-i= instead, but I don't think it's\r
+;; necessarily bad to have things like that on a control combo instead of\r
+;; overloading the tab key at the expense of being able to actually insert\r
+;; tabs.\r
+\r
+(setq-default indent-tabs-mode t\r
+             tab-width 8\r
+             backward-delete-char-untabify-method nil)\r
+\r
+(advice-add 'indent-to :around\r
+           (lambda (orig-fun column &rest args)\r
+             (when indent-tabs-mode\r
+               (setq column (* tab-width (round column tab-width))))\r
+             (apply orig-fun column args)))\r
+\r
+(dolist (indent-level '(c-basic-offset cperl-indent-level LaTeX-indent-level))\r
+  (defvaralias indent-level 'tab-width))\r
+\r
+(defun Tab (width)\r
+  "Give me a function analagous to the Acme `Tab' command"\r
+  (interactive)\r
+  (setq-local tab-width width))\r
+\r
+(keymap-global-set "<tab>" (lambda () (interactive) (insert "\t")))\r
+\f\r
+;;; Buffer dealiƋ\r
+\r
+(setq-default indicate-empty-lines t\r
+             truncate-lines t\r
+             fill-column 78)\r
+\r
+(dolist (hook '(text-mode-hook LaTeX-mode-hook))\r
+  (add-hook hook #'visual-line-mode))\r
+\r
+(blink-cursor-mode -1)\r
+(delete-selection-mode t)\r
+\r
+(setq delete-by-moving-to-trash t\r
+      delete-pair-blink-delay 0\r
+      use-short-answers t\r
+      use-file-dialog nil\r
+      echo-keystrokes 0.1\r
+      eldoc-idle-delay 0\r
+      read-buffer-completion-ignore-case t\r
+      history-delete-duplicates t\r
+      disabled-command-function nil\r
+      save-interprogram-paste-before-kill t\r
+      confirm-kill-processes nil)\r
+\r
+(keymap-global-set "C-x M-f" #'find-file-at-point)\r
+(keymap-global-set "C-x C-b" #'buffer-menu)\r
+(keymap-global-set "C-x M-b" #'buffer-menu-other-window)\r
+(keymap-global-set "C-x k" #'kill-current-buffer)\r
+(keymap-global-set "C-x K" #'kill-buffer)\r
+\f\r
+;;; Recentering and page-by-page navigation\r
+\r
+(setq recenter-positions '(2 middle -3))\r
+\r
+(defun re/recenter-advice (&rest _)\r
+  "Recenter to page start."\r
+  (when (called-interactively-p 'any) (recenter 2)))\r
+\r
+(dolist (binding '(backward-page forward-page))\r
+  (advice-add binding :after #'re/recenter-advice))\r
+\r
+(keymap-global-set "C-x C-n" #'forward-page)\r
+(keymap-global-set "C-x C-p" #'backward-page)\r
+(keymap-global-set "<next>" #'forward-page)\r
+(keymap-global-set "<prior>" #'backward-page)\r
+\f\r
+;;; Macro to open something in its own named frame\r
+;; Start a repl in a new frame, open dired in a new frame, etc. etc.\r
+\r
+(defmacro re/open-with-new-frame (frname function)\r
+  "Run the function in its own named frame."\r
+  `(progn\r
+     (select-frame (make-frame '((name . ,(eval frname)))))\r
+     (call-interactively ,function)))\r
+\f\r
+;;; Scratch buffer easy access\r
+\r
+(defun re/scratch-only ()\r
+  "Bring up the scratch buffer as the only visible buffer."\r
+  (interactive)\r
+  (scratch-buffer)\r
+  (delete-other-windows))\r
+\r
+(keymap-global-set "<f5>" #'scratch-buffer)\r
+(keymap-global-set "S-<f5>" #'re/scratch-only)\r
+\f\r
+;;; Switch or split window\r
+;; Game changer.  Auto choose how to split, or just switch to the next, all on\r
+;; the same binding.  Ripped from an early version of the lem editor.\r
+\r
+(defun re/other-window-or-split-window (&optional window)\r
+  "Go to other window or split sensibly."\r
+  (interactive)\r
+  (if (= (count-windows) 1)\r
+      (funcall split-window-preferred-function window)\r
+    (other-window 1)))\r
+\r
+(keymap-global-set "C-M-o" #'re/other-window-or-split-window)\r
+\f\r
+;;; Smart End/Beginning of line\r
+;; Similar to what org does, and indeed calls the org function if in org-mode\r
+\r
+(defun re/smart-beginning-of-line ()\r
+  "Move point to first non-whitespace character or `beginning-of-visual-line'.\r
+If point was already at that position, call `back-to-indentation'.\r
+Called a third time, move point back to `beginning-of-line'.\r
+If in org-mode, call `org-beginning-of-line' first."\r
+  (interactive "^")\r
+  (let ((oldpos (point)))\r
+    (if (equal major-mode 'org-mode)\r
+       (org-beginning-of-line)\r
+      (progn\r
+       (when visual-line-mode (beginning-of-visual-line 1))\r
+       (skip-syntax-forward " " (line-end-position))\r
+       (backward-prefix-chars)))\r
+    (and (= oldpos (point))\r
+        (let ((newpos (point)))\r
+          (back-to-indentation)\r
+          (and (= newpos (point)) (beginning-of-line))))))\r
+\r
+(keymap-global-set "<remap> <move-beginning-of-line>" #'re/smart-beginning-of-line)\r
+(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line)\r
+\r
+(defun re/smart-end-of-line ()\r
+  "Move point to the end of the visual line.\r
+ If point was already at that position, call `move-end-of-line'.\r
+If in org-mode, call `org-end-of-line' first."\r
+  (interactive "^")\r
+  (let ((oldpos (point)))\r
+    (if (equal major-mode 'org-mode)\r
+       (org-end-of-line)\r
+      (when visual-line-mode\r
+       (end-of-visual-line 1)))\r
+    (and (= oldpos (point)) (move-end-of-line nil))))\r
+\r
+(keymap-global-set "<remap> <move-end-of-line>" #'re/smart-end-of-line)\r
+(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line)\r
+\f\r
+;;; Goto line with numbers\r
+;; I only care about line numbers when I want to jump, so only show them then\r
+\r
+(defun re/goto-line ()\r
+  "Show line numbers before going to line, then hide them again."\r
+  (interactive)\r
+  (display-line-numbers-mode 1)\r
+  (call-interactively 'goto-line)\r
+  (display-line-numbers-mode -1))\r
+\r
+(keymap-global-set "<remap> <goto-line>" #'re/goto-line)\r
+\f\r
+;;; Switching between buffers\r
+\r
+(keymap-global-set "C-." #'next-buffer)\r
+(keymap-global-set "C-," #'previous-buffer)\r
+(keymap-global-set "C-<tab>" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers\r
+(keymap-global-set "<mouse-4>" #'previous-buffer) ; Back button\r
+(keymap-global-set "<mouse-5>" #'next-buffer) ; Forward button\r
+\f\r
+;;; Disable M-mouse for window manager bindings\r
+\r
+(keymap-global-unset "M-<down-mouse-1>")\r
+(keymap-global-unset "M-<drag-mouse-1>")\r
+(keymap-global-unset "M-<mouse-1>")\r
+(keymap-global-unset "M-<mouse-2>")\r
+(keymap-global-unset "M-<mouse-3>")\r
+\f\r
+;;; Search\r
+(defun re/add-region-to-search-ring ()\r
+  (when (use-region-p)\r
+    (add-to-history 'search-ring\r
+                   (buffer-substring (region-beginning) (region-end)))\r
+    (deactivate-mark)))\r
+\r
+(defun re/isearch-forward-use-region ()\r
+  "Search text in region if active, otherwise normal forward search."\r
+  (interactive)\r
+  (re/add-region-to-search-ring)\r
+  (isearch-forward))\r
+\r
+(keymap-global-set "C-s" #'re/isearch-forward-use-region)\r
+\r
+(defun re/isearch-backward-use-region ()\r
+  "Search text in region if active, otherwise normal backward search."\r
+  (interactive)\r
+  (re/add-region-to-search-ring)\r
+  (isearch-backward))\r
+\r
+(keymap-global-set "C-r" #'re/isearch-backward-use-region)\r
+\r
+(keymap-global-set "M-s ." #'isearch-forward-thing-at-point)\r
+(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point)\r
+(keymap-global-set "M-%" #'replace-regexp)\r
+(keymap-global-set "C-%" #'replace-string)\r
+(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff)\r
+(keymap-global-set "C-S-S" #'isearch-forward-regexp)\r
+(keymap-global-set "C-S-R" #'isearch-backward-regexp)\r
+\f\r
+;;; Recent Files/Buffers\r
+\r
+(midnight-mode t)\r
+(setq clean-buffer-list-delay-general 1)\r
+(dolist (never-re '("\\` \\*tramp/.*\\'"\r
+                   "\\` \\*eshell.*\\'"))\r
+  (add-to-list 'clean-buffer-list-kill-never-regexps never-re))\r
+(save-place-mode 1)\r
+(recentf-mode 1)\r
+\f\r
+;;; File Handling\r
+;; Rename visited file\r
+\r
+(defun re/rename-current-buffer-file nil\r
+  "Renames the current buffer and the file it is visiting."\r
+  (interactive)\r
+  (let ((name (buffer-name))\r
+       (filename (buffer-file-name)))\r
+    (if (not (and filename (file-exists-p filename)))\r
+       (error "Buffer '%s' is not visiting a file!" name)\r
+      (let ((new-name (read-file-name "New name: " filename)))\r
+       (if (get-buffer new-name)\r
+           (error "A buffer named '%s' already exists!" new-name)\r
+         (rename-file filename new-name 1)\r
+         (rename-buffer new-name)\r
+         (set-visited-file-name new-name)\r
+         (set-buffer-modified-p nil)\r
+         (message "File '%s' successfully renamed to '%s'"\r
+                  name\r
+                  (file-name-nondirectory new-name)))))))\r
+\r
+(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file)\r
+\r
+;; Copy file with datestamp appended\r
+\r
+(defun re/get-file-modified-time (filepath)\r
+  (interactive)\r
+  (format-time-string "%Y-%m-%d-%H%M"\r
+                     (file-attribute-modification-time (file-attributes filepath))))\r
+\r
+(defun re/filename-inject-mod-time (filepath)\r
+  (interactive)\r
+  (concat (file-name-sans-extension filepath)\r
+         "_"\r
+         (re/get-file-modified-time filepath)\r
+         (file-name-extension filepath t)))\r
+\r
+(defun re/copy-with-mod-time (&optional filepath)\r
+  (interactive)\r
+  (let ((filepath (if (eq major-mode 'dired-mode)\r
+                     (dired-get-filename t)\r
+                   (when (null filepath)\r
+                     (read-file-name "File to copy with datestring: "\r
+                                     default-directory\r
+                                     nil\r
+                                     t\r
+                                     nil)))))\r
+    (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t)))\r
+\f\r
+;;; Dired\r
+;; General Settings\r
+\r
+(setq dired-listing-switches "-Ahl"\r
+      dired-vc-rename-file t\r
+      dired-auto-revert-buffer t\r
+      dired-hide-details-hide-symlink-targets nil\r
+      dired-kill-when-opening-new-dired-buffer t)\r
+\r
+;; Open file next to dir buffer\r
+\r
+(defun re/dired-display-direction ()\r
+  "In dired mode, visit the file at the cursor in the right/below/left/above window."\r
+  (interactive)\r
+  (let* ((file-or-dir (dired-get-file-for-visit)) ;; get the file at cursor\r
+        (buffer (find-file-noselect file-or-dir))) ;; load the file into a buffer\r
+    (let ((window ;; figure out the window to use\r
+          (cond ((get-buffer-window buffer (selected-frame)))\r
+                ((window-in-direction 'right)) ;; try window in each direction\r
+                ((window-in-direction 'below)) ;; and default to right\r
+                ((window-in-direction 'left))  ;; if no window found.\r
+                ((window-in-direction 'above))\r
+                (t (split-window-sensibly (selected-window))))))\r
+      (window--display-buffer buffer window 'window nil)\r
+      window)))\r
+;; Open in new frame\r
+\r
+(defun re/dired-new-frame ()\r
+  "Open dired in a new frame."\r
+  (interactive)\r
+  (re/open-with-new-frame "DIRED"\r
+                         #'(lambda () (interactive) (dired default-directory))))\r
+;; Multiple Files\r
+\r
+(keymap-global-set "<f8>" #'re/dired-new-frame)\r
+\r
+(defun re/dired-find-marked-files ()\r
+  "Open all marked files from `dired'."\r
+  (interactive)\r
+  (mapc #'find-file (reverse (dired-get-marked-files))))\r
+;; Open file in external program\r
+\r
+(defun re/dired-sort ()\r
+  "Change sort order of dired dir."\r
+  (interactive)\r
+  (let ((smenu '(("name" . "-Ahl")\r
+                ("mdate" . "-Ahlt")\r
+                ("adate" . "-Ahltu")\r
+                ("size" . "-AhlS")\r
+                ("dir" . "-Ahl --group-directories-first")))\r
+       ssortBy)\r
+    (setq ssortBy (completing-read "Sort by (default name):"\r
+                                  smenu\r
+                                  nil\r
+                                  t\r
+                                  nil\r
+                                  nil\r
+                                  (caar smenu)))\r
+    (dired-sort-other (cdr (assoc ssortBy smenu)))))\r
+;; From dired\r
+\r
+(defun re/open-file-external (file)\r
+  "Open a file in an external program."\r
+  (interactive)\r
+  (let ((process-connection-type nil))\r
+    (cond ((eq system-type 'windows-nt)\r
+          (w32-shell-execute "open"\r
+                             (replace-regexp-in-string "/" "\\\\" file t t)))\r
+         ((eq system-type 'gnu/linux)\r
+          (start-process "" nil "xdg-open" file))\r
+         (t (error "Unable to automatically open this file")))))\r
+;; Multiple files\r
+\r
+(defun re/dired-open-externally ()\r
+  "Open the file at point in an external program."\r
+  (interactive)\r
+  (re/open-file-external (dired-get-filename)))\r
+\r
+(defun re/dired-open-marked-externally ()\r
+  "Open all marked files from `dired' in an external program."\r
+  (interactive)\r
+  (mapc #'re/open-file-external (reverse (dired-get-marked-files))))\r
+\r
+(add-hook 'dired-mode-hook\r
+         (lambda ()\r
+           (keymap-set dired-mode-map "o" #'re/dired-display-direction)\r
+           (keymap-set dired-mode-map "z" #'dired-do-compress-to)\r
+           (keymap-set dired-mode-map "c" #'dired-do-chmod)\r
+           (keymap-set dired-mode-map "r" #'dired-do-rename)\r
+           (keymap-set dired-mode-map "M" #'dired-do-rename)\r
+           (keymap-set dired-mode-map "s" #'re/dired-sort)\r
+           (keymap-set dired-mode-map "F" #'re/dired-find-marked-files)\r
+           (keymap-set dired-mode-map "M-C" #'re/copy-with-mod-time)\r
+           (keymap-set dired-mode-map "b" #'re/dired-open-externally)\r
+           (keymap-set dired-mode-map "B" #'re/dired-open-marked-externally)\r
+           (dired-hide-details-mode t)\r
+           (hl-line-mode)))\r
+\f\r
+;;; Bookmarks\r
+\r
+(setq bookmark-save-flag 1)\r
+(keymap-global-set "<f7>" #'recentf-open-files)\r
+(keymap-global-set "C-x r B" #'bookmark-jump-other-window)\r
+\f\r
+;;; GUI\r
+\r
+(load-theme 'eng-paper t)\r
+\r
+(if (equal system-type 'android)\r
+    (progn\r
+      (setq touch-screen-display-keyboard t)\r
+      (set-frame-parameter nil 'tool-bar-position 'bottom)\r
+      (modifier-bar-mode 1)\r
+      (tool-bar-mode 1)\r
+      (define-key key-translation-map\r
+                 (kbd "<volume-up>")\r
+                 (kbd "C-i"))\r
+      (define-key key-translation-map\r
+                 (kbd "<volume-down>")\r
+                 'event-apply-meta-modifier))\r
+  (progn\r
+    (menu-bar-mode -1)\r
+    (tool-bar-mode -1)))\r
+(set-scroll-bar-mode (if (eq system-type 'windows-nt) nil 'left))\r
+\r
+(setq frame-title-format "%b"\r
+      mouse-prefer-closest-glyph t\r
+      mouse-1-click-follows-link nil\r
+      focus-follows-mouse t\r
+      mouse-autoselect-window -0.25)\r
+\r
+(setq-default cursor-type 'hbar\r
+             cursor-in-non-selected-windows nil)\r
+\f\r
+;;; Mode Line\r
+;; Remove all minor modes from the mode-line, and show /all/ of them in the\r
+;; minor mode menu.  Must come before the modeline customization to ensure\r
+;; =minions-mode-line-modes= is defined.\r
+\r
+(require 'minions)\r
+(minions-mode)\r
+\r
+(setq minions-mode-line-lighter "+")\r
+\r
+;; Format\r
+\r
+(setq-default mode-line-format '(" "\r
+                                (:eval (propertize "%b"\r
+                                                   'face\r
+                                                   (when (buffer-modified-p)\r
+                                                     'mode-line-highlight)))\r
+                                " "\r
+                                mode-line-remote\r
+                                "  "\r
+                                minions-mode-line-modes\r
+                                (vc-mode vc-mode)\r
+                                mode-line-format-right-align\r
+                                (:eval (number-to-string (line-number-at-pos (point-max))))\r
+                                "L/%Ib (%l,%C) "))\r
+\f\r
+;;; Pretty Symbols\r
+\r
+(setq prettify-symbols-alist '(("lambda" . 955)\r
+                              ("delta" . 120517)\r
+                              ("epsilon" . 120518)\r
+                              ("->" . 8594)\r
+                              ("<=" . 8804)\r
+                              (">=" . 8805)))\r
+\r
+(global-prettify-symbols-mode t)\r
+\f\r
+;;; Parens\r
+;; Must be set after loading any theme\r
+\r
+(setq show-paren-delay 0\r
+      show-paren-style 'expression)\r
+\r
+(setq electric-pair-pairs '((?\" . ?\")\r
+                           (?\‘ . ?\’)\r
+                           (?\“ . ?\”)\r
+                           (?\{ . ?\})\r
+                           (?\< . ?\>)))\r
+\f\r
+;;; Help\r
+\r
+(setq apropos-do-all t)\r
+\f\r
+;;; UTF-8\r
+\r
+(prefer-coding-system 'utf-8-unix)\r
+(set-language-environment 'utf-8)\r
+\f\r
+;;; Cleanup on write\r
+\r
+(defun re/flush-extra-lines ()\r
+  "Change all groups of blank lines to 1 blank line."\r
+  (interactive)\r
+  (save-excursion\r
+    (replace-regexp "^\n+"\r
+                   "\n"\r
+                   nil\r
+                   (point-min)\r
+                   (point-max))))\r
+\r
+(setq require-final-newline t)\r
+(add-hook 'before-save-hook #'re/flush-extra-lines)\r
+(add-hook 'before-save-hook #'whitespace-cleanup)\r
+(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)\r
+\f\r
+;;; Password generation\r
+\r
+(defconst *alphanumerics*\r
+  (mapcar #'char-to-string\r
+         (append (number-sequence ?a ?z)\r
+                 (number-sequence ?A ?Z)\r
+                 (number-sequence ?0 ?9)))\r
+  "List of strings of the upper/lower-case English alphabet, and the single-digit numbers.")\r
+\r
+(defconst *special-characters*\r
+  '("!" "?" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "."\r
+    "/" ":" ";" "<" "=" ">" "?" "@" "[" "]" "^" "_" "{"\r
+    "|" "}" "~")\r
+  "List of strings containing the special visible characters excluding \\ and \" .")\r
+\r
+(defun pw-get-char (&optional no-special-chars)\r
+  "Select a single character at random to be used in a password.\r
+If `no-special-chars' is t, use only alpha-numeric characters."\r
+  (let ((selected-charset (append *alphanumerics*\r
+                                 (when (null no-special-chars)\r
+                                   *special-characters*))))\r
+    (elt selected-charset (random (length selected-charset)))))\r
+\r
+(defun pw-get-chars (password-length &optional no-special-chars)\r
+  "Generate a list of characters as strings to be made into a password.\r
+If `no-special-chars' is t, use only alpha-numeric characters."\r
+  (append (list (pw-get-char no-special-chars))\r
+         (when (> password-length 1)\r
+           (pw-get-chars (- password-length 1) no-special-chars))))\r
+\r
+(defun generate-password (password-length &optional no-special-chars)\r
+  "Combine a list of randomly-selected characters into a single string of length given.\r
+calls `pw-get-chars'.  If `no-special-chars' is `t', use only alpha-numeric characters."\r
+  (apply #'concat (pw-get-chars password-length no-special-chars)))\r
+\r
+(defun insert-generated-password (&optional password-length)\r
+  "Insert a generated password into the current buffer.\r
+Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'."\r
+  (interactive "p")\r
+  (let ((len (if (or (null password-length) (= 1 (abs password-length)))\r
+                16\r
+              (abs password-length)))\r
+       (no-special-p (and (numberp password-length) (< password-length 0))))\r
+    (insert (generate-password len no-special-p))))\r
+\r
+;; Get a password from a pass(1) entry\r
+;; Assume the password is on the first line.\r
+\r
+(defun re/get-line-from-file (file-path line-number)\r
+  "Return the specified LINE-NUMBER from FILE-PATH as a string.\r
+Start from bottom if given a negative line number."\r
+  (with-temp-buffer\r
+    (insert-file-contents file-path)\r
+    (if (< line-number 0)\r
+       (progn\r
+         (goto-char (point-max))\r
+         (forward-line line-number))\r
+      (progn\r
+       (goto-char (point-min))\r
+       (forward-line (1- line-number))))\r
+    (buffer-substring-no-properties (line-beginning-position) (line-end-position))))\r
+\r
+(defun get-password (&optional filename)\r
+  "Return a password given a file where it is stored.\r
+Assumes same structure as `pass(1)'."\r
+  (re/get-line-from-file (keyfile-string filename) 1))\r
+\r
+(defun password-to-clipboard (&optional filename)\r
+  "Copy the returned password to the clipboard."\r
+  (interactive)\r
+  (kill-new (get-password filename)))\r
+\f\r
+;;; TOTP\r
+;; Generate TOTP tokens, generate the codes, put them on the clipboard.\r
+;; Assumes the format of pass(1), where the TOTP token is the last line in the\r
+;; file.\r
+\r
+(dolist (requirement '(bindat gnutls hexl auth-source))\r
+  (require requirement))\r
+\r
+(defun totp--hex-decode-string (string)\r
+  "Hex-decode STRING and return the result as a unibyte string."\r
+  (apply #'unibyte-string\r
+        (seq-map (lambda (s) (hexl-htoi (aref s 0) (aref s 1)))\r
+                 (seq-partition string 2))))\r
+\r
+(defun totp (string &optional time digits)\r
+  "Return a TOTP token using the secret hex STRING and current time.\r
+TIME is used as counter value instead of current time, if non-nil.\r
+DIGITS is the number of pin digits and defaults to 6."\r
+  (let* ((key-bytes (totp--hex-decode-string (upcase string)))\r
+        (counter (truncate (/ (or time (time-to-seconds)) 30)))\r
+        (digits (or digits 6))\r
+        (format-string (format "%%0%dd" digits))\r
+        ;; we have to manually split the 64 bit number (u64 not supported in Emacs 27.2)\r
+        (counter-bytes (bindat-pack  '((:high u32) (:low u32))\r
+                                     `((:high . ,(ash counter -32)) (:low . ,(logand counter #xffffffff)))))\r
+        (mac (gnutls-hash-mac 'SHA1 key-bytes counter-bytes))\r
+        (offset (logand (bindat-get-field (bindat-unpack '((:offset u8)) mac 19) :offset) #xf)))\r
+    (format format-string\r
+           (mod\r
+            (logand (bindat-get-field (bindat-unpack '((:totp-pin u32)) mac  offset) :totp-pin)\r
+                    #x7fffffff)\r
+            (expt 10 digits)))))\r
+\r
+(defconst base32-alphabet\r
+  (let ((tbl (make-char-table nil)))\r
+    (dolist (mapping '(("A" . 0) ("B" . 1) ("C" . 2) ("D" . 3)\r
+                      ("E" . 4) ("F" . 5) ("G" . 6)\r
+                      ("H" . 7) ("I" . 8) ("J" . 9) ("K" . 10)\r
+                      ("L" . 11) ("M" . 12) ("N" . 13)\r
+                      ("O" . 14) ("P" . 15) ("Q" . 16) ("R" . 17)\r
+                      ("S" . 18) ("T" . 19) ("U" . 20)\r
+                      ("V" . 21) ("W" . 22) ("X" . 23) ("Y" . 24)\r
+                      ("Z" . 25) ("2" . 26) ("3" . 27)\r
+                      ("4" . 28) ("5" . 29) ("6" . 30) ("7" . 31)))\r
+      (aset tbl (string-to-char (car mapping)) (cdr mapping)))\r
+    tbl)\r
+  "Base-32 mapping table, as defined in RFC 4648.")\r
+\r
+(defun base32-hex-decode (string)\r
+  "The cheats' version of base-32 decode.\r
+\r
+This is not a 100% faithful implementation of RFC 4648. The\r
+concept of encoding partial quanta is not implemented fully.\r
+\r
+No attempt is made to pad the output either as that is not\r
+required for HMAC-TOTP."\r
+  (unless (mod (length string) 8)\r
+    (error "Padding is incorrect"))\r
+  (setq string (upcase string))\r
+  (let ((trimmed-array (append (string-trim-right string "=+") nil)))\r
+    (format "%X" (seq-reduce\r
+                 (lambda (acc char) (+ (ash acc 5) (aref base32-alphabet char)))\r
+                 trimmed-array 0))))\r
+\r
+(defun keyfile-string (filename)\r
+  "Return a string which is the filepath to a `pass(1)' file."\r
+  (let ((directory "~/.password-store/"))\r
+    (if (null filename)\r
+       (read-file-name "Select a password: " directory nil t nil)\r
+      (concat directory\r
+             (if (stringp filename)\r
+                 filename\r
+               (symbol-name filename))\r
+             ".gpg"))))\r
+\r
+(defun get-totp (&optional filename)\r
+  "Generate a totp code given a file with the secret hex string.\r
+If no filename given, prompt for one.\r
+Assumes the file has the string by itself on the last line of the file,\r
+similar to what pass-otp does, but without the full uri.\r
+Also assumes the file is in `~/.password-store' and has the `.gpg' extension."\r
+  (totp (base32-hex-decode (re/get-line-from-file (keyfile-string filename) -1))))\r
+\r
+(defun otp-to-clipboard (&optional filename)\r
+  "Copy the returned totp code to the clipboard."\r
+  (interactive)\r
+  (kill-new (get-totp filename)))\r
+\f\r
+;;; Emacs Control\r
+\r
+(defun re/kill-emacs ()\r
+  "Save all open files and kill emacs."\r
+  (interactive)\r
+  (save-some-buffers t)\r
+  (kill-emacs))\r
+\r
+(keymap-global-set "C-x M-c" #'re/kill-emacs)\r
+\r
+(defun re/restart-emacs ()\r
+  "Save all open files and restart emacs."\r
+  (interactive)\r
+  (save-some-buffers t)\r
+  (kill-emacs nil t))\r
+\r
+(keymap-global-set "C-x M-r" #'re/restart-emacs)\r
+\r
+(defun re/keyboard-quit ()\r
+  "Smarter version of `keyboard-quit'.\r
+Close the minibuffer if not focused when hit.\r
+Stolen from emacsredux.com."\r
+  (interactive)\r
+  (if (active-minibuffer-window)\r
+      (if (minibufferp)\r
+         (minibuffer-keyboard-quit)\r
+       (abort-recursive-edit))\r
+    (keyboard-quit)))\r
+\r
+(keymap-global-set "<remap> <keyboard-quit>" #'re/keyboard-quit) ; Make C-g better\r
+(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask\r
+(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files\r
+\f\r
+;;; Version-control mode\r
+\r
+(defun re/vc-clone ()\r
+  "Interactively clone with vc-mode.\r
+Prompt for url and local dir."\r
+  (interactive)\r
+  (let* ((url (read-string "Repository URL: "))\r
+        (dir (read-string "Local Dir: " (file-name-base url))))\r
+    (vc-git-clone url dir nil)))\r
+\r
+(keymap-global-set "C-x v C" #'re/vc-clone)\r
+\r
+(defun re/vc-show-branches (&optional arg)\r
+  "Display all Git branches in a separate buffer.\r
+Remotes as well when arg."\r
+  (interactive "P")\r
+  (let ((default-directory (if (boundp 'vc-dir-directory)\r
+                              vc-dir-directory\r
+                            default-directory)))\r
+    (vc-git-command "*git-branches*"\r
+                   nil\r
+                   nil\r
+                   "branch"\r
+                   "--verbose"\r
+                   (when arg "--remotes"))\r
+    (pop-to-buffer "*git-branches*")\r
+    (goto-char (point-min))\r
+    (special-mode)))\r
+\r
+(keymap-global-set "C-x v b b" #'re/vc-show-branches)\r
+\r
+(defun re/vc-fetch (&optional arg)\r
+  "Interactively fetch with vc-mode.\r
+Allows separate fetch in addition to pull.  Only care about git.\r
+With arg, ask for remote, otherwise fetch all."\r
+  (interactive "P")\r
+  (let* ((default-directory (if (boundp 'vc-dir-directory)\r
+                               vc-dir-directory\r
+                             default-directory)))\r
+    (vc-git-command "*vc-fetch*"\r
+                   nil\r
+                   nil\r
+                   "fetch"\r
+                   (if arg\r
+                       (read-string "Fetch From: " "origin")\r
+                     "--all")\r
+                   "--verbose")\r
+    (pop-to-buffer "*vc-fetch*")\r
+    (goto-char (point-min))\r
+    (special-mode)))\r
+\r
+(keymap-global-set "C-x v f" #'re/vc-fetch)\r
+\r
+(add-hook 'vc-dir-mode-hook\r
+         (lambda ()\r
+           (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches)\r
+           (keymap-set vc-dir-mode-map "f" #'re/vc-fetch)\r
+           (keymap-set vc-dir-mode-map "k" #'vc-revert)))\r
+\r
+(setq vc-make-backup-files nil\r
+      vc-handled-backends '(jj Git)\r
+      vc-git-log-switches '("--oneline" "--graph" "--decorate" "--all")\r
+      vc-git-log-edit-summary-target-len 50\r
+      vc-find-revision-no-save t)\r
+\f\r
+;;; Backups\r
+\r
+(setq backup-directory-alist `((".*" . "~/emacs-backups/"))\r
+      backup-by-copying t\r
+      delete-old-versions t\r
+      kept-new-versions 5\r
+      kept-old-versions 5)\r
+\f\r
+;;; Any Lisp Repl\r
+\r
+(defmacro re/send-on-close-paren (executor)\r
+  "Generalizes sending an execute on close paren.\r
+ Interactively call `executor'.  For `executor', use whatever\r
+ function is called by `<RET>' in the applicable REPL.  For a\r
+ non-repl, use `newline' or similar."\r
+  `(lambda (&optional arg)\r
+     (interactive "p")\r
+     (insert-char 41 arg)\r
+     (call-interactively ,executor)))\r
+\r
+(defun re/sexp-drop-paren-p ()\r
+  "Returns t if sexp needs fewer parens to balance."\r
+  (< (car (syntax-ppss)) 0))\r
+\r
+(defun re/sexp-need-paren-p ()\r
+  "Returns t if sexp needs more parens to balance."\r
+  (> (car (syntax-ppss)) 0))\r
+\r
+(defun re/sexp-unbalanced-count ()\r
+  "Returns distance from balanced sexp."\r
+  (abs (car (syntax-ppss))))\r
+\r
+(defun re/balance-sexp ()\r
+  "Balance the sexp before point.\r
+Either delete, move forward, or add as many ')' as needed."\r
+  (let ((distance (re/sexp-unbalanced-count)))\r
+    (cond ((re/sexp-need-paren-p)\r
+          (if (looking-at ")")\r
+              (progn\r
+                (forward-char)\r
+                (re/balance-sexp))\r
+            (insert-char 41 distance)))\r
+         ((re/sexp-drop-paren-p)\r
+          (backward-delete-char distance)))))\r
+\r
+(defmacro re/balance-and-eval-sexp (executor)\r
+  "Balance the sexp before point, then call `executor'.\r
+Call `re/balance-sexp', then interactively call `executor'.  Bind\r
+this to ']' for the interlisp experience.  For `executor', use\r
+whatever function is called by `<RET>' in the applicable REPL.\r
+For a non-repl, use `newline' or similar."\r
+  `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor)))\r
+\r
+(defvar *re/lisp-mode-hooks*\r
+  '(emacs-lisp-mode-hook\r
+    lisp-mode-hook\r
+    sly-mode-hook\r
+    scheme-mode-hook\r
+    geiser-mode-hook\r
+    lisp-interaction-mode-hook))\r
+\r
+(dolist (hook *re/lisp-mode-hooks*)\r
+  (add-hook hook\r
+           (lambda ()\r
+             (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1))\r
+             (sedit-mouse-mode 1)\r
+             (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region)\r
+             (keymap-set lisp-mode-shared-map\r
+                         "C-M-S-q"\r
+                         #'sedit-auto-prettify-sexp)\r
+             (keymap-set lisp-mode-shared-map\r
+                         "]"\r
+                         (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp))\r
+             (keymap-set lisp-interaction-mode-map\r
+                         "]"\r
+                         (re/balance-and-eval-sexp #'eval-print-last-sexp)))))\r
+\f\r
+;;; IELM\r
+;; Rarely used, but nice to have when I want it.\r
+\r
+(add-hook 'ielm-mode-hook\r
+         (lambda ()\r
+           (keymap-set inferior-emacs-lisp-mode-map\r
+                       "C-l"\r
+                       #'comint-clear-buffer)\r
+           (let ((eval-function #'ielm-send-input))\r
+             (keymap-set inferior-emacs-lisp-mode-map\r
+                         ")"\r
+                         (re/send-on-close-paren eval-function))\r
+             (keymap-set inferior-emacs-lisp-mode-map\r
+                         "]"\r
+                         (re/balance-and-eval-sexp eval-function)))))\r
+\f\r
+;;; Eshell\r
+\r
+(keymap-global-set "C-c e" #'eshell)\r
+\r
+(defun eshell-quit-or-delete-char (arg)\r
+  "Delete char if at one, quit eshell if on empty prompt.\r
+Stolen from https://depp.brause.cc/dotemacs"\r
+  (interactive "p")\r
+  (if (and (eolp) (looking-back eshell-prompt-regexp 0 t))\r
+      (eshell-life-is-too-much)\r
+    (delete-char arg)))\r
+\r
+(add-hook 'eshell-mode-hook\r
+         (lambda ()\r
+           (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char)\r
+           (let ((eval-function #'eshell-send-input))\r
+             (keymap-set eshell-mode-map\r
+                         ")"\r
+                         (re/send-on-close-paren eval-function))\r
+             (keymap-set eshell-mode-map\r
+                         "]"\r
+                         (re/balance-and-eval-sexp eval-function)))))\r
+\f\r
+;;; C-mode\r
+\r
+(dolist (mode-maps '(("\\.keymap\\'" . c-mode) ("\\.dtsi\\'" . c-mode)))\r
+  (add-to-list 'auto-mode-alist mode-maps t))\r
+\r
+(defun re/c-lineup-arglist-tabs-only (ignored)\r
+  "Line up argument lists by tabs, not spaces.\r
+ Stolen from https://kernel.org/doc/html/v4.10/process/coding-style.html"\r
+  (let* ((anchor (c-langelem-pos c-syntactic-element))\r
+        (column (c-langelem-2nd-pos c-syntactic-element))\r
+        (offset (- (1+ column) anchor))\r
+        (steps (floor offset c-basic-offset)))\r
+    (* (max steps 1) c-basic-offset)))\r
+\r
+(add-hook 'c-mode-common-hook\r
+         (lambda ()\r
+           (c-add-style "linux-tabs-only"\r
+                        '("linux" (c-offsets-alist\r
+                                   (arglist-cont-nonempty\r
+                                    c-lineup-gcc-asm-reg\r
+                                    re/c-lineup-arglist-tabs-only))))))\r
+\r
+(add-hook 'c-mode-hook\r
+         (lambda ()\r
+           (setq c-backspace-function 'backward-delete-char)\r
+           (c-set-style "linux-tabs-only")))\r
+\f\r
+;;; Auto-Revert\r
+\r
+(global-auto-revert-mode)\r
+(setq global-auto-revert-non-file-buffers nil)\r
+\f\r
+;;; Crash HandliƋ\r
+\r
+(setq attempt-stack-overflow-recovery nil\r
+      attempt-orderly-shutdown-on-fatal-signal nil)\r
+\f\r
+;;; Abbrev-mode and skeletons\r
+\r
+(define-skeleton workorder-link\r
+  "part of a link to a workorder, just enter the number."\r
+  ""\r
+  "https://eservice.r717.net/index.php/PLC_workorders/store/"\r
+  _ -)\r
+\r
+(define-skeleton skel-org-block\r
+  "Add a source block to an org file."\r
+  ""\r
+  "#+BEGIN_SRC"\r
+  \n\r
+  _ -\r
+  \n\r
+  "#+END_SRC")\r
+\r
+(define-skeleton skel-org-block-elisp\r
+  "Add an elisp source block to an org file."\r
+  ""\r
+  "#+BEGIN_SRC emacs-lisp"\r
+  \n\r
+  _ -\r
+  \n\r
+  "#+END_SRC")\r
+\r
+(setq save-abbrevs 'silently)\r
+\r
+(add-hook 'org-mode-hook #'abbrev-mode)\r
+\f\r
+;;; Customization Framework\r
+;; Disable it by making it save to a temp file (stolen from prot)\r
+\r
+(setq custom-file (make-temp-file "emacs-custom-"))\r