I'll fill out the how and why of this all as I figure out what the hell I'm doing. My current Emacs Configuration is a mess of copy and pasted snippet loosely grouped together. There's a fair number of work around, to transient configuration issues that now no longer exist, and more of stuff cribbed off StackOverflow & held together with string & bubble gum. While not yet calling Configuration Bankrupt's, I am going to try to see if I can restructure this technical debt.
This Emacs configuration is written using the [[https://en.wikipedia.org/wiki/Literate_programming][Literate Programming]] (sort of) paradigm (well sort of) proposed by [[https://en.wikipedia.org/wiki/Donald_Knuth][Donald Knuth]] in 1984, and uses Hlissner's awesome [[https://github.com/doomemacs/doomemacs][Doom Emacs]] configuration framework.
While I like Literate Programming, I kind of think that literate configuration is largely a mixed bag. Literate Programming produces often more words then code. For even medium size configurations discoverability & readability of what is happening can be bogged down in the weight of prose explaining the backstory, current thought, moral pondering, pros & cons, and deciding thoughts. This extra cruft potentially makes understanding more through, but at cost of readability & readability is king. As a compromise I'm going to version both to the verbose =config.org= file and all of the produced configuration files. As an example about that verbosity mentioned prior this entire paragraph could have been skipped.
This is built on top of Hlissner's awesome [[https://github.com/doomemacs/doomemacs][Doom Emacs]] configuration frameworks. Configuration is divided into 150 modules, & fair number of convenience functions. Rather than detailing stuff about I'll say to go read [[https://github.com/doomemacs/doomemacs/blob/master/docs/faq.org][FAQs]] & [[https://github.com/doomemacs/doomemacs/blob/master/docs/index.org][Index]].
Configuration is located in the ~DOOMDIR~ directory. This is default value is located is the ~$HOME/.doom.d~ directory. Typically this directory contains:
+ =init.el= :: Enabled Doom Modules
+ =config.el= :: General Emacs configuration
+ =package.el= :: Packages to fetch from MELPA, Github, etc.
Additional configuration for scoped functionality will be named as =+name.el=.
** Tangle
This org-mode document works by using [[https://orgmode.org/manual/Extracting-Source-Code.html][tangles]]. By default Doom's literate config mode adds any ~#+begin_src~ blocks into the =config.el= file[fn:1]. If you want to tangle to a specific file you pass in a file name.
#+begin_src orgmode :tangle no
#+begin_src emacs-lisp :tangle "example.el"
#+end_src
or to disable it tangling for a codeblock set the =:tangle= property in code block header to =no=.
#+begin_src orgmode :tangle no
#+begin_src orgmode :tangle no
#+end_src
*** Noweb Reference
This document uses [[https://orgmode.org/manual/Noweb-Reference-Syntax.html][noweb reference syntax]]. This allows us to extract bits of configuration into named codeblocks, which can be interpulated into another code block's variable. For example:
#+begin_example :tangle no
#+NAME: initialization
#+BEGIN_SRC emacs-lisp
(setq sentence "Never a foot too far, even.")
#+END_SRC
#+BEGIN_SRC emacs-lisp :noweb yes
(reverse sentence)
#+END_SRC
#+end_example
will produce
#+begin_example
#+BEGIN_SRC emacs-lisp :noweb yes
(setq sentence "Never a foot too far, even.")
(reverse sentence)
#+END_SRC
#+end_example
NOTE: unless you explicitly turn off the named code block will be tangled into =config.el=. Use the no tangle option if you want to disable this.
There [[https://nullprogram.com/blog/2016/12/22/][minor but non-zero start time benefits]] for using Lexical Bindings comments. All files created should start with
#+BEGIN_SRC emacs-lisp
;;; config.el -*- lexical-binding: t; -*-
#+END_SRC
replace =config.el= with the filename being loaded.
I use the [[https://www.nerdfonts.com/][nerdfont]]'s [[https://github.com/i-tu/Hasklig][Hasklig]] for my monospace font & Huerta Tipografica's [[https://www.huertatipografica.com/en/fonts/alegreya-ht-pro][ Alegreya]] serif font.
The configuration is below is pulled from the template =init.example.el= provided by doom. This one is based off commit [[https://github.com/doomemacs/doomemacs/blob/e96624926d724aff98e862221422cd7124a99c19/templates/init.example.el][e966249]].
The code of these can be found in the [[https://github.com/doomemacs/doomemacs/tree/master/modules][modeules directory]], the read me for each module will list any additional configuration options.
Vterm is great. It does require some additional configuration to work properly. See [[https://github.com/doomemacs/doomemacs/tree/master/modules/term/vterm][relavant doc]] for more.
NOTE: =:leader r= is currently being used by roam. See [[id:f9ffe9df-a417-45c4-8bf2-6ee655140648][Roam Keybinds]]. This conflicts with the =upload= module. If you wish to use this module in the future you will need to updated one of the keybinds to not conflict.
Keybinds custom keybinds can be located at =$DOOMDIR/+keybinds.el=.
#+begin_src emacs-lisp
(load! "+keybinds")
#+end_src
Doom comes with some good keybind macros (see [[https://github.com/doomemacs/doomemacs/blob/master/docs/faq.org#bind-my-own-keys-or-change-existing-ones][here]] for why). Documentation for this can be found [[https://github.com/doomemacs/doomemacs/blob/master/docs/faq.org#bind-my-own-keys-or-change-existing-ones][here]], but in broad strokes:
1. Start with a =map!= macro. You can use
2. When possible use =:when= to limit scope.
3. Use =:prefix= and =:prefix-map= where possible.
4. Always use =:desc= to describe what is being done.
Below is a sample snippet from Rameez Khan's [[https://rameezkhan.me/posts/2020/2020-07-03--adding-keybindings-to-doom-emacs/][blog]] (first hit on "doom emacs keybind" using [[https://duckduckgo.com/][DDG]]):
#+begin_src emacs-lisp :tangle no
(map! :leader
(:prefix-map ("a" . "applications")
(:prefix ("j" . "journal")
:desc "New journal entry" "j" #'org-journal-new-entry
Lets set the local leader to =,=. We may want to remap this to =;= later. Both of these seem to have issues with potential key conflicts with evil-snipe. This seems to primarily exists with regards to org-mode. Github issue can be found [[https://github.com/doomemacs/doomemacs/issues/4242][here]].
#+begin_src emacs-lisp :tangle "+keybinds.el" :noweb no-export :comments no
(setq doom-localleader-key ",")
#+end_src
*** Roam Keybinds
:PROPERTIES:
:ID: f9ffe9df-a417-45c4-8bf2-6ee655140648
:END:
The standard keybind for getting to Roam's daily capture is pretty long. To capture a Log entry I have to type =SPC n r d T l=. I want to capture as many logs and goals as possible, so lets shorten this up some.
#+begin_src emacs-lisp :tangle "+keybinds.el" :noweb no-export :comments no
=:leader r= is used by =:tools upload= for "remote", but since I'm not using this lets just not care about that.
** Orgmode
This file will be needed for emacs batch automations, where its not reasonable to start up my entire working env. This file can be located at =$DOOMDIR/+orgmode.el=.
#+begin_src emacs-lisp
(load! "+orgmode")
#+end_src
*** Lexical bindings
#+begin_src emacs-lisp :tangle "+orgmode.el" :noweb no-export :comments no
This file may get consumed via emacs batch scripting, so we need ot make sure the orgmode is actually loaded.
#+begin_src emacs-lisp :tangle "+orgmode.el" :noweb no-export :comments no
(require 'org)
#+end_src
*** Directories
My notes are stored via [[https://nextcloud.com/][NextCloud]] to sync multiple machines. The Nextcloud directory can be located in a couple different location based off the OS that the machine is running, but
Where the NextCloud general sync directory may vary based on machine but notes should always be stored at =$HOME/org=.
#+begin_src emacs-lisp :tangle "+orgmode.el" :noweb no-export :comments no
(custom-set-variables '(org-directory "~/org/"))
#+end_src
I've tried to organize things based on purpose & this will likely change in the future. The current directory looks like this
#+begin_example :tangle no
~/org
├── .archive
├── .attach
├── Projects
├── Roam
├── Todo
└── Work
#+end_example
**** =.archive=
Where old files go. See =org-archive-subtree= for more.
**** =.attach=
Stuff that is not an orgmode document.
#+begin_src emacs-lisp :tangle "+orgmode.el" :noweb no-export :comments no
Babel execute can be tweaked per the syntax see orgmode docs [[https://orgmode.org/manual/Evaluating-Code-Blocks.html][here]].
**** Diff
The snippet below is largely pulled from John Kitchin [[https://emacs.stackexchange.com/questions/63517/org-mode-evaluate-diff-code-block/63520#63520][Stackexchange Post]].
#+begin_src emacs-lisp :tangle "+orgmode.el" :noweb no-export :comments no
(defun org-babel-execute:diff (body params)
"Applies diff patches. Use with care.
See https://emacs.stackexchange.com/questions/63517/org-mode-evaluate-diff-code-block"
[fn:1] See [[https://github.com/doomemacs/doomemacs/tree/master/modules/config/literate#change-where-src-blocks-are-tangled-or-prevent-it-entirely][Doom FAQ on this for more.]]