diff --git a/config.org b/config.org index cab5077..8987412 100644 --- a/config.org +++ b/config.org @@ -63,18 +63,18 @@ Unlike a standard markup language, however, Org mode has built-in capabilities f The second block above was automatically generated by =org-mode=. -(This feature does not exclusively work with Emacs Lisp, but other languages require a compiler or interpreter to be installed.) +(This feature does not exclusively work with Emacs Lisp, but other languages require the corresponding build tools to be installed.) **** Tangle, Weave, Export, Publish -Since Org's ability to execute and code process its output is so robust, it's only natural that one might consider using Org to annotate existing code. This could be done by maintaining both the Org document and an actual source file separately, but that would require duplicating edits in both files, which is not ideal. +Since Org's ability to execute code and process its output is so robust, it's only natural that one might consider using Org to annotate a codebase, storing the code inside source blocks in the document. This could be done by maintaining both the Org file and the actual source files separately, but that would require manually duplicating edits in both files, which is not ideal. -The solution is [[https://en.wikipedia.org/wiki/Literate_programming][literate programming]], the practice of embedding an active codebase into a document. Literate programming can be done in a few different ways; some languages support directly processing literate programs, including Julia and Agda. However, the way Org implements it is closer to the traditional method, which involves two processing systems: +The solution is [[https://en.wikipedia.org/wiki/Literate_programming][literate programming]], the practice of embedding usable code into a markup document. Literate programming can be done in a few different ways; a handful of languages support directly processing these markup documents, such as Haskell and Julia. However, the way Org implements it is closer to the traditional method, which involves two processing systems: -1. /Tangling/, converting the file into source code that can be executed. Tangling must be performed before the code is used, and in Org is typically done into a separate generated file. +1. /Tangling/, converting the file into raw source code. Tangling must be performed before the code is used; in Org, code is tangled into a new file, and this can be done to generate many source files at once. 2. /Weaving/, formatting the file into a human-readable document. Org conceptually divides this further into "exporting" and "publishing," where the latter is intended specifically for converting into web-ready HTML. -You are currently reading the published version of this literate program[fn:1]. If you were to download this repository and use it as your config, Emacs would be running the tangled version. These versions are generated in separate processes, but both of them require running code, since as demonstrated above, the exported documentation can contain program execution results. +You are currently reading the published version of this literate program[fn:1]. If you were to download this repository and use it as your config, Emacs would be running the tangled version. These versions are generated in separate processes, but both are ultimately derived from the content and metadata inside of the Org file. [fn:1] Unless you're reading the raw file on Github, in which case you are probably already decently familiar with =org-mode= to be able to read its markup. @@ -1355,7 +1355,7 @@ There's a lot of reasons why I don't like Spacemacs and why I left it for Doom E [[https://user-images.githubusercontent.com/33982951/39624821-a4abccee-4f92-11e8-9e91-3d5b542bbb85.png][Spacemacs's dashboard has /impeccable/ style.]] -Doom Emacs tends to favor practicality over aesthetics with a focus on minimalism, and its dashboard is no exception. If we want something that looks visually appealing, we're going to need a serious overhaul. +Doom Emacs tends to favor practicality over aesthetics, and its dashboard is no exception. If we want something that looks visually appealing, we're going to need a serious overhaul. *** Splash Banner @@ -1527,16 +1527,18 @@ When I first learned about Embark and began to use it, I was a bit disappointed Some of the targeting functions are a bit too general in what they accept. We'll adjust the expression and identifier targeters to only work in ~prog-mode~ and the "defun" targeter to only work in Emacs Lisp code. #+begin_src emacs-lisp -(defun ~/embark-target-prog-mode (old-fn) +(defadvice! ~/embark-target-prog-mode (old-fn) "Advise an embark target to only activate in `prog-mode'." - (when (derived-mode-p 'prog-mode) (funcall old-fn))) + :around #'embark-target-expression-at-point + (when (derived-mode-p 'prog-mode) + (funcall old-fn))) -(defun ~/embark-target-identifier (old-fn) +(defadvice! ~/embark-target-identifier (old-fn) "Advise an embark target to only activate in `prog-mode' and not in `lsp-mode'." - (when (and (derived-mode-p 'prog-mode) (not (bound-and-true-p lsp-mode))) (funcall old-fn))) - -(advice-add #'embark-target-expression-at-point :around #'~/embark-target-prog-mode) -(advice-add #'embark-target-identifier-at-point :around #'~/embark-target-identifier) + :around #'embark-target-identifier-at-point + (when (and (derived-mode-p 'prog-mode) + (not (bound-and-true-p lsp-mode))) + (funcall old-fn))) (after! embark (embark-define-thingatpt-target defun emacs-lisp-mode)) @@ -2094,7 +2096,7 @@ These new categories can then be used to define [[*Keymaps][Embark keymaps]] for ** Operation Hints -I like having hints that show how large the editing operation I just performed was, but the =ophints= module in Doom doesn't look very good to me (it gets rid of pulses and color), so I'll override it. +I like having ophints for vim editing so that I don't get lost when making large edits, but the =ophints= module in Doom doesn't look very good to me (it gets rid of pulses and color), so I'll override it. #+begin_src emacs-lisp :tangle modules/ui/ophints/packages.el ;; -*- no-byte-compile: t; -*- @@ -2145,7 +2147,7 @@ I like having hints that show how large the editing operation I just performed w #+call: confpkg("Pkg: yasnippet") -Snippets are an extremely versatile way of avoiding unnecessary typing, especially when writing code. +Snippets are a sophisticated method of warding off the scourge of unnecessary keystrokes. They were a bit hard to get used to, but I've warmed up to them over time. *** Tweaks @@ -2174,7 +2176,7 @@ If there are any trailing newlines in the snippet file, they will be inserted wh When editing a snippet, the binding =C-c C-t= can be used to test it in a fresh buffer. This is very useful, but with Evil it has the issue of leaving the editor in normal state, when snippets are designed to be expanded in insert state. #+begin_src emacs-lisp -(defadvice! ~/yas-tryout-insert-mode (&rest _) +(defadvice! ~/yas-tryout-insert-state (&rest _) "Switch to Insert state when trying out a snippet." :after #'yas-tryout-snippet (evil-insert-state)) @@ -2182,26 +2184,20 @@ When editing a snippet, the binding =C-c C-t= can be used to test it in a fresh *** Creating New Snippets -Doom's command to create a new snippet, ~+snippets/new~, defines a template inside of itself purely for when creating a snippet through this command. This doesn't make much sense to me when file templates already exist as a standard system in Doom, so we'll override this function to use that. +Doom's command to create a new snippet, ~+snippets/new~, defines a template inside of itself purely for when creating a snippet through this command. This doesn't make much sense to me when file templates already exist as a standard system in Doom, and snippets are stored inside files! #+begin_src emacs-lisp (defadvice! ~/snippets-new (&optional all-modes) - "Use standard file template when creating a new snippet." + "Use standard Doom Emacs file template system when creating a new snippet." :override #'+snippets/new (let* ((mode (+snippets--snippet-mode-name-completing-read all-modes)) (default-directory (+snippet--ensure-dir (expand-file-name mode +snippets-dir))) (snippet-key (read-string "Enter a key for the snippet: ")) (snippet-file-name (expand-file-name snippet-key))) (when (+snippets--use-snippet-file-name-p snippet-file-name) - (switch-to-buffer snippet-key) - (snippet-mode) - (erase-buffer) - (set-visited-file-name snippet-file-name) - (+file-templates--expand t)))) + (find-file snippet-file-name)))) #+end_src -Since the snippet is expanded in an environment including the variable ~snippet-key~, our template can use that to automatically fill in the key we specified. - ** Treemacs #+call: confpkg("Pkg: treemacs") @@ -3194,7 +3190,7 @@ Annoyingly, the only good way to fix these issues is to completely override the *** Default Categories -When an explicit category is not specified, Org mode typically defaults to the filename (sans extension). This ... sort of makes sense? I guess? It doesn't really, because filename conventions don't make for good category names. This is especially bad for Org-roam, where filenames are automatically generated and can be very large and hard to read. +When an explicit category is not specified, Org mode typically defaults to the filename (sans extension). This ... sort of makes sense? I guess? It doesn't really, because filename conventions don't make for good agenda category names. I want my category names to be in title case, whereas a file name is typically going to be all lowercase and without spaces. This is especially bad for Org-roam, where filenames are automatically generated and way too long to be a UI element. To fix this issue, it is thankfully rather simple to patch Org-mode's category system[fn:2]. The following code sets things up so that the file's =#+title= metadata is used as the default category, falling back on the default behavior if a title is not given. @@ -3509,6 +3505,7 @@ The Org agenda is a very nice feature, but by default it doesn't really provide #+end_src The ~org-agenda~ dispatcher is occasionally useful, but most of the time when I want to open my agenda, it's to see my "preferred" view. +By customizing ~org-super-agenda-groups~ via a let-binding in my custom agenda view, I can set up a sophisticated multi-category agenda system. #+begin_src emacs-lisp (defun ~/org-agenda-section-by-link (prefix tag item) @@ -3547,8 +3544,11 @@ The ~org-agenda~ dispatcher is occasionally useful, but most of the time when I (~/org-agenda-section-by-link "Area: " "area" item)) :order 4)))))))))) +#+end_src +This "overview" agenda command is very nice. It's so nice, in fact, that it's almost always the only agenda view I want to use! Having to go through the dispatcher every time I want to access it is annoying and unnecessary. +#+begin_src emacs-lisp (defun ~/org-agenda (&optional arg) "Wrapper around preferred agenda view." (interactive "P") @@ -3557,7 +3557,8 @@ The ~org-agenda~ dispatcher is occasionally useful, but most of the time when I (map! :leader :desc "Org agenda" "o a" #'~/org-agenda - :desc "Org agenda dispatcher" ; Use shift to access full dispatcher + ;; Use shift to access full dispatcher + :desc "Org agenda dispatcher" "o A" #'org-agenda) #+end_src