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=.
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 interpolated into another code block's variable. For example:
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.
I am currently using Firefox with [[https://github.com/tridactyl/tridactyl][Tridactyl]]. The =editorcmd= creates a temporary file & opens it with the editor of choice. The domain is included in the temporary file name. We can use this to set the syntax of the file in question. This likely just be markdown.
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.
For use with Github this requires the creation of a Github Token (see [[https://github.com/settings/tokens][here]]). This will need to be appended to your =~/.authinfo.gpg= file using the format below[fn:2].
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
This file will be needed for emacs batch automation, where its not reasonable to start up my entire working env. This file can be located at =$DOOMDIR/+orgmode.el=.
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
[[https://mermaid.js.org/][MermaidJS]] is a diagramming and charting tool similar to Dot/Graphviz, but significantly prettier with less boilerplate. We'll likely only ever want to modify it in the context of =org-mode= so we'll want [[https://github.com/arnm/ob-mermaid][ob-mermaid]].
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"
GPT is more useful than I thought. Its incredibly helpful for writing prose which I can struggle with due to mild dysgraphia. We will be using the [[https://github.com/karthink/gptel][karthink/gptel]] package.
This package supports multiple LLM backends. I'm going to be using the OpenAI ChatGPT backend by default. We'll need to set the API key. There are a couple ways this can be done, but we're going to set this using =~/.authinfo.gpg=. This will need to be decrypted before use, but this is pretty minor.
We've enabled the [[doom-module:editor snippets][snippets module]] [[*Editor][earlier]]. This will give us use of the [[https://github.com/doomemacs/snippets][Doom Snippets package]], but we'll want to add our own as well. Custom snippets are added under =$DOOMDIR/snippets/= directory. Documentation on how to write snippets can be found at [[http://joaotavora.github.io/yasnippet/snippet-development.html][yas-snippet/documentation]] and [[https://github.com/doomemacs/snippets][doom-snippets github page]].
While we'll want to store these snippets in this orgmode document, using the =+snippets/create= & =snippets/edit= may be useful for creating these.
*** Orgmode
In my work todo and my roam notes I've been using a list elements with nerd-fonts icons under my section header to provide quick links for the context. Below are a few that I've been using.
[fn:2] See [[https://github.com/doomemacs/doomemacs/tree/master/modules/tools/magit#i-recently-updated-and-now-i-get-deferred-error--wrong-type-argument-sequencep-code-reviewauth-token-set-whenever-i-try-to-review][Doom Magit documentation.]]
[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.]]