Every time you call my name
I hear the angels say
Dig my grave
, I was watching one of Gavin Freeborn’s many Emacs videos. I mentally noted his Org-Mode 📖 code block prompting. It was different from what I had.
, I dug a bit into his Emacs configuration; and experimented with org-tempo
. But it wasn’t quite what I wanted.
So, I started cleaning up my my Emacs configuration, moving some functions I no longer use into a “graveyard” file.
During this process, I was looking at a function I had commented out. It overloaded the tilde (e.g. ~) key in Org-Mode.
When I typed three consecutive tilde it would would replace those three tilde with a source block, position the cursor inside the block and then call org-edit-special
to perhaps create a special editing buffer.
Enter the Overload of Back-tick/Grave
After typing the third consecutive back-tick, the following function:
- Deletes the three back-ticks.
- Prompts for the content to insert.
- Positions into the newly inserted content.
- Attempts to edit the content in Org-Mode’s special editing buffer.
(defun dig-my-grave ()
"Three consecutive graves (e.g. “`”) at the start of the line prompts for
inserting content. See `dig-my-grave/templates-alist/org-mode'."
(interactive)
(if (or (and (> (point) 3)
(string= (buffer-substring-no-properties
(- (point) 3) (point)) "\n``"))
;; Account for starting on the first line
(and (= (point) 3)
(string= (buffer-substring-no-properties
(- (point) 2) (point)) "``")))
;; We have just hit our third back-tick at the beginning of the line.
(progn
(delete-char -2)
;; I use the alist-get pattern a lot...perhaps a function?
(let ((value (alist-get (completing-read "Special Content: "
dig-my-grave/templates-alist/org-mode nil t)
dig-my-grave/templates-alist/org-mode nil nil #'string=)))
(cond
;; Let's assume that we're dealing with registered org blocks.
((stringp value)
(insert value) (forward-line -1) (org-edit-special))
;; Trust the function
((commandp value) (call-interactively value))
((functionp value) (funcall value))
((ad-lambda-p) (funcall value))
;; Time for a pull request
(t (error "Unprocessable value %s for #'dig-my-grave" value)))))
(setq last-command-event ?`)
(call-interactively #'org-self-insert-command)))
For the above dig-my-grave
function to work, I need map ` to the function.
Near complete control over the environment.
(require 'org)
(define-key org-mode-map (kbd "`") #'dig-my-grave)
And below is the list of templates; They represent the vast majority of the blocks I use in Emacs 📖:
(defvar dig-my-grave/templates-alist/org-mode
'(("Bash" . "#+begin_src bash :results scalar replace :exports both :tangle yes\n#+end_src")
("Blockquote" . tempel-insert-blockquote_block)
("Details and Summary" . "#+begin_details\n#+begin_summary\n\n#+end_summary\n#+end_details")
("Emacs Lisp" . "#+begin_src emacs-lisp\n#+end_src")
("Org Structure" . org-insert-structure-template)
("Plant UML" . "#+begin_src plantuml\n@startuml\n!theme amiga\n\n@enduml\n#+end_src")
("Ruby" . "#+begin_src ruby\n#+end_src")
("Update" . tempel-insert-update_block))
"A list of `cons' cells with `car' as the label and `cdr' as
the value that we'll insert. Used as the collection for the
`dig-my-grave' `completing-read'.")
There are three functions:
tempel-insert-blockquote_quote
- A Tempel template to insert a blockquote block that I export to my blog post.
tempel-insert-update_block
- A Tempel template to insert an update block that I export to my blog post.
org-insert-structure-template
- The build-in Org-Mode function to prompt for registered templates.
You can find the above code in the .emacs.d/dig-my-grave.el file of my Emacs configuration.
Conclusion
Now I can repurpose the ingrained Markdown keystrokes for code-blocks into something useful for my Org-Mode writing that I find easy to remember.
Which has me thinking, what are other ways that I might leverage the above function. The progn
function hints at generalization. I suppose I’ll hold this and let my mind wander.
In almost all settings other than Markdown, I don’t type ```
; how might I bring this to those other modes. Also, I suspect that I want to add the above to a minor-mode, so that I can disable it; in those few cases where I want to type ```
.