Finding the best style of literate emacs configuration
I can’t decide on the best style and I’d like to before I start writing Managing your emacs configuration, system configuration, and all dependencies in a single org file.
The typical per-package use-package literate style
Typically use-package is the first and only way of organizing emacs configurations most emacsers are exposed to.
It’s natural that most literate configs would faithfully represent that organizational structure, but with the added benefit if collapsible nodes and perhaps notes on the entire use package block.
To my great surprise, this style is pretty close to Knuth’s own style of literate programming. Maybe Knuth is doing it wrong was on to something?
Here’s our first example:
* use-package
** magit
#+begin_src elisp
(use-package magit)
#+end_src
** haskell-mode
#+begin_src elisp
(use-package haskell-mode)
#+end_src
** org-roam
#+begin_src elisp
(use-package org-roam)
#+end_src
** git-time-machine
#+begin_src elisp
(use-package git-time-machine)
#+end_src
** python-mode
#+begin_src elisp
(use-package python-mode)
#+end_src
** lsp-mode
#+begin_src elisp
(use-package lsp-mode)
#+end_src
** lsp-haskell
#+begin_src elisp
(use-package lsp-haskell)
#+end_src
Per use-case literate style
Once your configuration starts getting really large, the use-package style alone can start losing meaning and feel very overwhelming.
A solution is to organize by use case and use noweb-ref
in case ordering matters to tangle the blocks organized by use case into use package blocks. Here’s an example:
* My emacs use-cases
** Version control with Git
*** use magit as a porcelain
#+begin_src elisp
(use-package magit)
#+end_src
*** enable easily showing history of a file
#+begin_src elisp
(use-package git-time-machine)
#+end_src
** Haskell development
*** Haskell-mode provides most functionality
#+begin_src elisp
(use-package haskell-mode)
#+end_src
*** [[*Language Server Protocol][lsp-mode]] integration
#+begin_src elisp
(use-package lsp-haskell)
#+end_src
** Zettlekasten
#+begin_src elisp
(use-package org-roam)
#+end_src
** Language Server Protocol for development in many languages
*** lsp-mode
#+begin_src elisp
(use-package lsp-mode)
#+end_src
*** eglot :noexport:
#+begin_src elisp
(use-package lsp-mode)
#+end_src
** Python development
*** Python-mode provides most functionality
#+begin_src elisp
(use-package python-mode)
#+end_src
*** [[*Language Server Protocol][lsp-mode]] integration
#+begin_src elisp
(use-package lsp-python)
#+end_src
Here complexity only scales as your personal use-cases scale. There are a few interesting things to note about this example.
It’s way less complex at a glance and can reflect your mental model of your work
Our working memory can only handle 7 things at a time, so perhaps keeping your use cases categorized to be less than 7 would be a good idea?
As seen with eglot and :noexport
separating by use-case lets you easily tryout different packages for given use-cases.
Another example is Narrowing framework
with consult active and ivy and helm tagged noexport
.
discussion points
literate configs can be harder to debug
Improving debugging of literate emacs configutations
TODO Per use-case literate style with :config
examples
The more complex version of Per use-case literate style where:
- ordering becomes important and you need to tangle to
use-package
blocks - You have
:init
,:config
,:bind
,:custom
for certain configs and need to be able to tangle to them from any given use-case
TODO are there other styles?
What about Alhassy, Prot, and Tecosaurs configs I have listed in Literate emacs configuration examples?
I think Prot roughly goes by use case? Maybe fully, can’t remember.
TODO investigate prior work of wider literate programming community
TODO review Theme-Based Literate Programming
TODO http://akkartik.name/post/literate-programming
this article criticizes the style of literate programming i try to convince isn’t as good as well.
TODO HN discussion on “Knuth is doing it wrong”
Huh, how can people say this is nothing new when most that use literate programming don’t use this style?