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