Streamlining the Posting Process with emacs
Andrew Fontaine <andrew@afontaine.ca>Writing posts can be a bit troublesome to set up, and my major posting season is nearly here! Fortunately, I can customize emacs a bit to make this whole process at least a bit more optimized.
Making New Posts
When making a new post, I set the Reply-To
header to ensure that any further
discussion goes to the correct place, and also set the X-Blog-Tags
header to
capture blog tagging. It looks a lot nicer to get them out of the subject line
and tucked away. The end result is below:
(defun afontaine/set-reply-to ()
(save-excursion
(message-add-header
"Reply-To: andrew@afontaine.ca,~afontaine/blog-discuss@lists.sr.ht\n")))
(defun afontaine/set-blog-tags (tags)
(save-excursion
(message-add-header
(concat "X-Blog-Tags: " tags ))))
(defun afontaine/new-blog-post (tags)
(interactive "sBlog tags: ")
(let ((mu4e-compose-mode-hook '(afontaine/set-reply-to)))
(call-interactively #'mu4e-compose-new)
(afontaine/set-blog-tags tags)
(message-goto-body)))
There are lot of examples of setting headers via mu4e-compose-mode-hook
in
mu4e’s documentation, so setting the Reply-To
header was no issue.
Setting the tags, however, was a little trickier. As they change from post to
post, I wanted to be able to read them in when creating a post. Here, I looked
to documentation on emacs’ minibuffer
to understand how to read in a
string. While read-string
looks to be the trick, the intro paragraph specifies
that I should be using the powers of the interactive
function to fetch my
arguments instead.
Using interactive
specifies that if I want to get a string, I need to
pass in the s
command, and that I can add a prompt directly after it. Thus,
passing in "sBlog tags: "
allows me to send in blog tags as part of the
creation process. To pass those arguments through, I just call a normal function
instead of adding it to mu4e-compose-mode-hook
, and then put the cursor right
at the body ready to go!
Writing Posts
I’m also tired of writing posts in the compose window. While I will draft longer ones in a normal file and then send that off when it is ready, these shorter posts that I can write pretty quickly don’t need all the extra process.
Instead, I just want the compose window to know about markdown. It doesn’t, of course, but I can open the body in a new buffer that does:
(defun afontaine/get-start ()
(message-goto-body)
(point))
(defun afontaine/get-end ()
(message-goto-signature)
(search-backward "--")
(goto-char (- (point) 1)))
(defun afontaine/edit-post-in-markdown ()
(interactive)
(let* ((start (afontaine/get-start))
(end (afontaine/get-end))
(buffer (edit-indirect-region start end)))
(switch-to-buffer-other-window buffer)
(markdown-mode)))
Using theedit-indirect
library, I open the body of the message in a new
buffer, and enable markdown-mode
in that, giving me all the syntax
highlighting and link inserting power I crave.
To get the body, I need to figure out the region of text that is the message body. Thankfully, emacs has some good functions to help out.
message-goto-body
moves my point
(emacs for cursor) to the start of the
body. The end is a little trickier though. message-goto-signature
puts the
point at the beginning of my signature (obviously), below the --
, which I
don’t want to include. I search backwards for the --
, and move the point back
to immediately before that, getting the whole of the body. I search from the end
to ensure I am at the --
, and not an ---
(which is markdown for a horizontal
rule, or <hr>
tag). This also ensures the function works well if I am editing
a draft email.
Once I’m done writing, a quick C-c C-c
puts my post into the message body, and
ready to send.
For the most part, I think this works pretty well. I’ll see how the next month goes, as I try to keep up posting with my advent of code adventures. I’m also hopeful this will encourage me to post more, as it really streamlines the process of setting up a new post. Emacs really is that easy to customize in powerful ways.
Want to discuss this post?
Reach out via email to ~afontaine/blog-discuss@lists.sr.ht, and be sure to follow the mailing list etiquette.
Other posts