koldfront

Tweaking get news in Gnus #gnus

🕘︎ - 2020-10-04

It is nice to be able to easily change the details of how things work when they are just a little off kilter for your preferences.

When I ask my email program/newsreader Gnus to look for new email/news by pressing g in the *Group* buffer, the count of unread messages is updated - and the way I have ordered my groups, I usually want to start reading from the top. However, by default, Gnus doesn't move the cursor after updating the list.

Let's fix that.

What to do? Well, C-h k g tells me that g bound to a function called gnus-group-get-new-news, so maybe I'll write a function to be called when g is pressed, that calls gnus-group-get-new-news and does some more.

What I want to happen is that after new email/news is fetched, is that the cursor is put at the first group with unread messages, for me to start reading.

So I wrote this:

(defun asjo-group-get-new-news ()
  "Do the equivalent of g M-< n :*)"
  (interactive)
  (gnus-group-get-new-news)
  (gnus-group-next-unread-group 1))

(define-key gnus-group-mode-map [(g)] 'asjo-group-get-new-news)

and put it in my ~/.gnus.

I've been using that for years. Sometimes it's a little annoying, because the first groups I have are the drafts and delayed groups, and I don't want to read those over and over - they are drafts and delayed for a reason. So I want to skip past them. Luckily I have a topic called "email" I can skip to, so:

(defun asjo-group-get-new-news ()
  "Do the equivalent of g M-< n :*)"
  (interactive)
  (gnus-group-get-new-news)
  (goto-char (point-min))
  (search-forward "email")
  (gnus-group-next-unread-group 1))

So that's nice, when there is new stuff to read, the cursor is put on the first group after the draft/delayed groups.

But what happens when there is no new news? Then the cursor ends up on the email-topic. Hm. I don't like that. So I changed the function to this:

(defun asjo-group-get-new-news ()
  "Do the equivalent of g M-< n :*)"
  (interactive)
  (gnus-group-get-new-news)
  (goto-char (point-min))
  (search-forward "email")
  (let ((current-place (point)))
    (gnus-group-next-unread-group 1)
    (when (= current-place (point))
      (goto-char (point-min)))))

So if gnus-group-next-unread-group doesn't move the cursor, the cursor is returned to the top of the *Group* list.

Being able to make little tweaks like this is one of the things that makes Emacs in general and Gnus is particular so nice to use.

The solution I presented depend on the [ email ] topic being at the top and visible. That's not always the case, so I have changed my function to:

(defun asjo-group-get-new-news ()
  "Fetch news and move point"
  (interactive)
  (gnus-group-get-new-news)
  (goto-char (point-min))
  (when (search-forward " [" nil t)
    (let ((current-place (point)))
      (gnus-group-next-unread-group 1)
      (when (= current-place (point))
        (goto-char (point-min))))))

so it tries to find the first indented topic (which should be the first one after [ Gnus ]), and then goes to the first group with unread articles in it after that, which I think is a better solution.

Also using search-forward with NOERROR set allows the function to not show an error when there's nowhere to jump to.

- Adam Sjøgren 🕡︎ - 2020-11-08

Add comment

To avoid spam many websites make you fill out a CAPTCHA, or log in via an account at a corporation such as Twitter, Facebook, Google or even Microsoft GitHub.

I have chosen to use a more old school method of spam prevention.

To post a comment here, you need to:

¹ Such as Thunderbird, Pan, slrn or Gnus (part of Emacs).