Small commands for a more usable Gnus

2023/12/09

Categories: Emacs Tags: Emacs

I’ve written a bit about Gnus on the blog before, but if you are just now starting to follow along, all you need to know is that Gnus is kinda like Outlook, but it’s highly user-configurable, it supports a wider variety of reading sources, and it has a lot of machinery to help you read internet sources more effectively. Gnus is a mode for reading email and net news in Emacs.

Most of Gnus’s operation happens in the Group buffer – a place where you can select news sources to read, go to the Server browser, and conduct other reading tasks. This is a very 90s design. Of course, if you are using Emacs, you are probably all over the place doing different things from 100 buffers, so I wanted to write today about my efforts to create some commands that make Gnus less centered around the group buffer, and more easily accessible from any Emacs activity.

More Accessible Searching

I rely heavily on email searches to find my place. And Gnus has a very capable parsing system for IMAP queries. Conducting an email search is a bit laborious in Gnus, so we can write a command to bind all the steps to a hotkey. This command opens up a new search IMAP query in my personal email. It’s like hitting Ctrl-e in Outlook.

(defun jth-search-fastmail ()
  "Search Fastmail from anywhere in Emacs"
  (interactive)
  (unless (get-buffer gnus-group-buffer)
    (gnus))
  (with-current-buffer gnus-group-buffer
    (gnus-group-enter-server-mode)
    (search-forward "fastmail")
    (gnus-group-read-ephemeral-search-group nil)))

More accessible reader groups

Sometimes I am working on something and I want to jump directly to my Sent Mail folder to check on something. Since this is a hidden group in my Gnus, it’s a multi-step process to jump to it. So, I wrote a command to jump to any group (with tab completion) from anywhere in Emacs. You can even use savehist-mode to keep the history of visited groups in chronological order based on last access.

(defun jth-gnus-switch-group ()
  "Start reading a group from anywhere in Emacs"
  (interactive)
  ;; If gnus is not running, start gnus
  (unless (get-buffer gnus-group-buffer)
    (gnus))
  (gnus-summary-read-group
   (completing-read "Group: " gnus-group-list)))

I would like to eventually improve this function to make the group display show all the extra info that I keep in my group buffer, including group level and unread counts, probably by using marginalia, but for now, it does the job

Lastly, one can go a step further by writing glue code at the OS level to conduct email searches or access groups from anywhere in the OS (outside of Emacs). For instance, on MacOS, you can write some Lua code in Hammerspoon to call Emacs and then these Emacs Lisp functions. On Windows, you would likely use AutoHotKey. That would be pretty cool, but I’m rather content to keep my Gnus-ing inside Emacs for now.

As usual, Emacs has some rough edges, but it is easy to smooth over them with the Emacs Lisp extension language.