guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Notmuch, Debbugs: my helpers (was Re: New section to easily reference De


From: Simon Tournier
Subject: Notmuch, Debbugs: my helpers (was Re: New section to easily reference Debbugs URLs within Emacs Debbugs)
Date: Mon, 18 Sep 2023 18:07:53 +0200

Hi,

On Sun, 17 Sep 2023 at 16:51, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:

> If you use Emacs and Emacs-Debbugs, you may be interested in applying
> the settings newly documented in the 'Viewing Bugs within Emacs' section
> of the manual; see it at the bottom of info "(guix) The Perfect Setup").

Oh, cool!

On Saturday, I discovered ’honey-apple’ on IRC and today I was planning
to improve my setup.  Perfect timing! :-)

BTW, let me share some of my helpers.  They are quite simple but it
helps me.  Maybe it could be useful to others.  Well, I read my emails
using Emacs-Notmuch but I guess this should be adaptable for Gnus or
mu4e.

Since I often lag behind, I often have patches in my inbox where I have
been CC.  I try to keep focused on by an easy triage, so I quickly want
to know if this patch is still open or if it is already marked as done.
Before opening, or while reading, I just press ’C’ and it queries
Debbugs (SOAP) and displays the current status.

Similarly, sometimes old but still open bug pops up.  It is a reply or
just a ping and because it is old, I do not necessary have the context.
I just press ’b’ and it opens Emacs-Debbugs for the issue at hand.  If
there is many messages (that I do not have locally) and say it will need
some time to read them, and say I am often reading offline, well I just
press ’I’ and it downloads all the thread and injects it in my Guix
email folder (and also indexed by notmuch :-)).

Last, when reading from Debbugs, I press ’R’ for replying.  I like to
have https://issues.guix.gnu.org/issue/NNNNN at hand so pressing ’R’
stashes this URL specific to the issue and ready to be pasted.

Below the config. :-)

--8<---------------cut here---------------start------------->8---
  (defun my/notmuch-show-get-debbugs ()
    "Extract Debbugs number.

>From an email message, it exracts the number NNNN as in
NNNN@debbugs.gnu.org from the fields From/To/CC and it returns a
list of integers.

If in `notmuch-search-mode', then the returns is nil, so let try
to extract from the email subject assuming the pattern bug#NNNN."
    (let* ((all-mails (seq-reduce
                       (lambda (r f)
                         (let ((s (funcall f)))
                           (if s
                               (append r (split-string s "," t))
                             r)))
                       (list 'notmuch-show-get-from
                             'notmuch-show-get-to
                             'notmuch-show-get-cc)
                       nil))
           (debbugs (seq-filter
                     (lambda (x) (string-match-p (regexp-quote 
"@debbugs.gnu.org") x))
                     all-mails))
           (numbers (remq nil
                          (mapcar
                           (lambda (x)
                             (let ((n (when (string-match 
"\\([0-9]+\\)@debbugs.gnu.org" x)
                                        (match-string 1 x)))
                                   (d (when (string-match 
"\\([0-9]+\\)-done@debbugs.gnu.org" x)
                                        (match-string 1 x)))
                                   (c (when (string-match 
"\\([0-9]+\\)-close@debbugs.gnu.org" x)
                                        (match-string 1 x)))
                                   )
                               (or n d c)))
                           debbugs))))
      (or
       (mapcar 'string-to-number numbers)
       ;; Let extract from the subject
       (let* ((subject (notmuch-search-find-subject))
              (n (when (and subject
                            (string-match ".*bug#\\([0-9]+\\).*" subject))
                   (match-string 1 subject))))
         (when n
           (list (string-to-number n))))))))

  (defun my/notmuch-debbugs-check ()
    "Send request to Debbugs instance about pending status and report."
    (interactive)
    (let* ((number (car (my/notmuch-show-get-debbugs)))
           (meta (if number
                     (car (debbugs-get-status number))
                   (user-error "Notmuch: no @debbugs.gnu.org")))
           (status (debbugs-get-attribute meta 'pending))
           (listify #'(lambda (bug attr)
                      (let ((some (debbugs-get-attribute bug attr)))
                        (if (listp some)
                            some
                          (list some)))))
           (infos (or (sort (append
                             (funcall listify meta 'tags)
                             (funcall listify meta 'severity))
                            'string<)
                      "")))
      (message "Status bug#%d: %s %s" number status infos)))

  (define-key notmuch-tree-mode-map (kbd "C")
    'my/notmuch-debbugs-check)
  (define-key notmuch-search-mode-map (kbd "C")
    'my/notmuch-debbugs-check)
  (define-key notmuch-show-mode-map (kbd "C")
    #'(lambda ()
        ;; XXXX: For some reason, without wrapping with
        ;;     (lambda () (interactive) ...)
        ;; it returns: Wrong type argument: commandp
        (interactive)
        (my/notmuch-debbugs-check))

  (defun my/notmuch-debbugs-open ()
    "Open the current message with Debbugs mode."
    (interactive)
    (let ((numbers (my/notmuch-show-get-debbugs)))
      (if numbers
          (apply 'debbugs-gnu-bugs numbers)
        (user-error "Notmuch: no @debbugs.gnu.org"))))

  (define-key notmuch-tree-mode-map (kbd "b") ;rebind 
`notmuch-show-resend-message'
    'my/notmuch-debbugs-open)
  (define-key notmuch-search-mode-map (kbd "b") ;rebind 
`notmuch-show-resend-message'
    'my/notmuch-debbugs-open)
  (define-key notmuch-show-mode-map (kbd "b") ;rebind 
`notmuch-show-resend-message'
    'my/notmuch-debbugs-open)

  (define-key gnus-summary-mode-map "I" ;rebind `gnus-summary-increase-score'
    #'(lambda ()
        "Import thread to Notmuch."
        (interactive)
        ;; XXXX: Is `debbugs-get-status' using caching?
        (let* ((meta  (car (debbugs-get-status debbugs-gnu-bug-number)))
               (inbox (car (debbugs-get-attribute meta 'package))) ;match with 
`piem-inboxes'
               (raw   (debbugs-get-attribute meta 'msgid))
               (msgid (replace-regexp-in-string "<\\|>" "" raw)))
          (piem-inject-thread-into-maildir msgid inbox)
          (notmuch-command-to-string "new" "--no-hooks")
          (notmuch-tag (concat "id:" msgid) (list "+Later"))
          (message "Imported %s from %s using %s." debbugs-gnu-bug-number inbox 
msgid))))

  (define-key gnus-article-mode-map "R"
    #'(lambda ()
        "Start composing a reply mail to the current message.
The original article will be yanked, see 
`gnus-summary-wide-reply-with-original'."
        (interactive)
        (let* ((all-mails (seq-reduce
                           (lambda (r f)
                             (let ((s (funcall 'message-fetch-field f)))
                               (if s
                                   (append r (split-string s "," t))
                                 r)))
                           (list "from"
                                 "to"
                                 "cc")
                           nil))
               (debbugs (seq-filter
                         (lambda (x) (string-match-p (regexp-quote 
"@debbugs.gnu.org") x))
                         all-mails))
               (numbers (remq nil
                              (mapcar
                               (lambda (x)
                                 (let ((n (when (string-match 
"\\([0-9]+\\)@debbugs.gnu.org" x)
                                            (match-string 1 x)))
                                       (d (when (string-match 
"\\([0-9]+\\)-done@debbugs.gnu.org" x)
                                            (match-string 1 x))))
                                   (if n n d)))
                               debbugs)))
               (number (if numbers
                           (progn
                             (unless (= 1 (length numbers))
                               (user-error "Bang! Not a Debbugs message"))
                             (when (> 1 (length numbers))
                               (message "Consider only %s" (car numbers)))
                             (car numbers))
                         ""))
               (url (concat "https://issues.guix.gnu.org/issue/"; number)))
          (kill-new url)
          (gnus-summary-wide-reply-with-original nil)
          (message "Stashed: %s" url))))
--8<---------------cut here---------------end--------------->8---


Cheers,
simon



reply via email to

[Prev in Thread] Current Thread [Next in Thread]