1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-08 15:35:02 +00:00

Improve Gnus ephemeral bug group browsing

* doc/misc/gnus.texi (Foreign Groups): Update description of
gnus-read-ephemeral-emacs-bug-group for multiple bug
IDs (bug#11961).

* lisp/gnus/gnus-group.el (gnus-bug-group-download-format-alist):
Use HTTPS for Debian's bug tracker.
(gnus-group--read-bug-ids): New function for reading multiple bug
IDs in the minibuffer.  Improves on previous brittle approach of
word-at-point -> read-string -> string-to-number by a) defaulting to
the more accurate bug-reference-bug-regexp or number-at-point
without using the intrusive INITIAL-INPUT argument, and b) not
attempting to parse bug IDs.
(gnus-read-ephemeral-bug-group): Use it.  Extend docstring and
commentary.  Fix handling of multiple bug IDs as either numbers or
strings.  Hoist some string consing out of inner loop.  Delete
temporary file even on error.  Throw more informative error when
url-insert-file-contents successfully returns an error (bug#36433).
(gnus-read-ephemeral-debian-bug-group): Use gnus-group--read-bug-ids
and fix docstring for multiple bug IDs.  Accept optional WINDOW-CONF
like other ephemeral bug group commands.
(gnus-read-ephemeral-emacs-bug-group): Use gnus-group--read-bug-ids
and fix string/numeric ID conversions.  Try loading debbugs-gnu
before testing for debbugs-gnu-summary-mode (bug#36433).
This commit is contained in:
Basil L. Contovounesios 2019-07-06 16:34:10 +02:00 committed by Lars Ingebrigtsen
parent cfcaf06fe5
commit d7ee13331c
2 changed files with 98 additions and 71 deletions

View File

@ -2716,9 +2716,10 @@ given @acronym{URL}. Supported @acronym{URL} formats include:
@item gnus-read-ephemeral-emacs-bug-group @item gnus-read-ephemeral-emacs-bug-group
@findex gnus-read-ephemeral-emacs-bug-group @findex gnus-read-ephemeral-emacs-bug-group
Read an Emacs bug report in an ephemeral group. Gnus will prompt for a Read an Emacs bug report in an ephemeral group. Gnus will prompt for
bug number. The default is the number at point. The @acronym{URL} is multiple bug numbers. The default is the number at point. The
specified in @code{gnus-bug-group-download-format-alist}. @acronym{URL} template is specified in
@code{gnus-bug-group-download-format-alist}.
@item gnus-read-ephemeral-debian-bug-group @item gnus-read-ephemeral-debian-bug-group
@findex gnus-read-ephemeral-debian-bug-group @findex gnus-read-ephemeral-debian-bug-group

View File

@ -2423,7 +2423,7 @@ Valid input formats include:
(defcustom gnus-bug-group-download-format-alist (defcustom gnus-bug-group-download-format-alist
'((emacs . "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s;mboxmaint=yes;mboxstat=yes") '((emacs . "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s;mboxmaint=yes;mboxstat=yes")
(debian (debian
. "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s&mbox=yes;mboxmaint=yes")) . "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s&mbox=yes;mboxmaint=yes"))
"Alist of symbols for bug trackers and the corresponding URL format string. "Alist of symbols for bug trackers and the corresponding URL format string.
The URL format string must contain a single \"%s\", specifying The URL format string must contain a single \"%s\", specifying
the bug number, and browsing the URL must return mbox output." the bug number, and browsing the URL must return mbox output."
@ -2434,90 +2434,116 @@ the bug number, and browsing the URL must return mbox output."
:version "24.1" :version "24.1"
:type '(repeat (cons (symbol) (string :tag "URL format string")))) :type '(repeat (cons (symbol) (string :tag "URL format string"))))
(autoload 'thing-at-point-looking-at "thingatpt")
(defvar bug-reference-bug-regexp)
(defun gnus-group--read-bug-ids ()
"Return a list of bug IDs read in the minibuffer."
(require 'bug-reference)
(let ((def (cond ((thing-at-point-looking-at bug-reference-bug-regexp 500)
(match-string 2))
((number-at-point)))))
;; Pass DEF as the value of COLLECTION instead of DEF because:
;; a) null input should not cause DEF to be returned and
;; b) TAB and M-n still work this way.
(completing-read-multiple "Bug IDs: " (and def (list (format "%s" def))))))
(defun gnus-read-ephemeral-bug-group (ids mbox-url &optional window-conf) (defun gnus-read-ephemeral-bug-group (ids mbox-url &optional window-conf)
"Browse bug NUMBER as ephemeral group." "Browse bug reports with IDS in an ephemeral group.
(interactive (list (read-string "Enter bug number: " IDS can be either a single bug ID (a number or string), or a list
(thing-at-point 'word) nil) thereof. MBOX-URL is a URL format string identifying the bug
;; FIXME: Add completing-read from tracker; see `gnus-bug-group-download-format-alist' for details.
;; `gnus-emacs-bug-group-download-format' ... Interactively, read multiple bug IDS in the minibuffer and
(cdr (assoc 'emacs gnus-bug-group-download-format-alist)))) default to the MBOX-URL for the Emacs bug tracker. WINDOW-CONF
(when (stringp ids) is the name of the Gnus window configuration to use when exiting
(setq ids (string-to-number ids))) the ephemeral group."
(unless (listp ids) (interactive
(setq ids (list ids))) (list (gnus-group--read-bug-ids)
(alist-get 'emacs gnus-bug-group-download-format-alist)))
(or ids (user-error "No bug IDs specified"))
(setq ids (mapcar (lambda (id) (format "%s" id))
(if (consp ids) ids (list ids))))
(let ((tmpfile (make-temp-file "gnus-temp-group-"))) (let ((tmpfile (make-temp-file "gnus-temp-group-")))
(let ((coding-system-for-write 'binary) (unwind-protect
(coding-system-for-read 'binary))
(with-temp-file tmpfile
(mm-disable-multibyte)
(dolist (id ids)
(let ((file (format "~/.emacs.d/debbugs-cache/%s" id)))
(if (and (not gnus-plugged)
(file-exists-p file))
(insert-file-contents file)
(url-insert-file-contents (format mbox-url id) t))))
;; Add the debbugs address so that we can respond to reports easily. ;; Add the debbugs address so that we can respond to reports easily.
(let ((address (let* ((address (format "%s@%s" (car ids)
(format "%s@%s" (car ids) (url-host (url-generic-parse-url mbox-url))))
(url-host (url-generic-parse-url mbox-url))))) (address-re (concat "\\(?:\\`\\|[ ,<]\\)"
(goto-char (point-min)) (regexp-quote address)
(while (re-search-forward (concat "^" message-unix-mail-delimiter) "\\(?:\\'\\|[ ,>]\\)"))
nil t) (delim (concat "^" message-unix-mail-delimiter)))
(narrow-to-region (point) (let ((coding-system-for-write 'binary)
(if (search-forward "\n\n" nil t) (coding-system-for-read 'binary))
(1- (point)) (with-temp-file tmpfile
(point-max))) (mm-disable-multibyte)
(unless (string-match (concat "\\(?:\\`\\|[ ,<]\\)" (dolist (id ids)
(regexp-quote address) (let ((file (concat "~/.emacs.d/debbugs-cache/" id)))
"\\(?:\\'\\|[ ,>]\\)") (if (and (not gnus-plugged)
(concat (message-fetch-field "to") " " (file-exists-p file))
(message-fetch-field "cc"))) (insert-file-contents file)
;; Pass non-nil VISIT to avoid errors with non-nil
;; `url-automatic-caching' (bug#26063, bug#29008)
;; and immediately unvisit.
;; FIXME: This masks real errors!
(url-insert-file-contents (format mbox-url id) t)
(setq buffer-file-name nil))))
(goto-char (point-min)) (goto-char (point-min))
(if (re-search-forward "^To:" nil t) ;; Throw an informative error early instead of passing nonsense
(progn ;; to `gnus-group-read-ephemeral-group' (bug#36433).
(unless (save-excursion (re-search-forward delim nil t))
(error "Invalid mbox format for bug IDs: %s"
(string-join ids ", ")))
(while (re-search-forward delim nil t)
(narrow-to-region (point)
(if (search-forward "\n\n" nil t)
(1- (point))
(point-max)))
(unless (string-match-p address-re
(concat (message-fetch-field "to") " "
(message-fetch-field "cc")))
(goto-char (point-min))
(if (not (re-search-forward "^To:" nil t))
(insert "To: " address "\n")
(message-next-header) (message-next-header)
(skip-chars-backward "\t\n ") (skip-chars-backward "\t\n ")
(insert ", " address)) (insert ", " address)))
(insert "To: " address "\n"))) (goto-char (point-max))
(goto-char (point-max)) (widen))))
(widen))) (gnus-group-read-ephemeral-group
;; `url-insert-file-contents' sets this because of the 2nd arg. (concat "nndoc+ephemeral:bug#" (string-join ids ","))
(setq buffer-file-name nil))) `(nndoc ,tmpfile
(gnus-group-read-ephemeral-group (nndoc-article-type mbox))
(format "nndoc+ephemeral:bug#%s" nil window-conf))
(mapconcat 'number-to-string ids ",")) (delete-file tmpfile))))
`(nndoc ,tmpfile
(nndoc-article-type mbox))
nil window-conf)
(delete-file tmpfile)))
(defun gnus-read-ephemeral-debian-bug-group (number) (defun gnus-read-ephemeral-debian-bug-group (ids &optional window-conf)
"Browse Debian bug NUMBER as ephemeral group." "Browse Debian bug reports with IDS in an ephemeral group.
(interactive (list (read-string "Enter bug number: " The arguments have the same meaning as those of
(thing-at-point 'word) nil))) `gnus-read-ephemeral-bug-group', which see."
(interactive (list (gnus-group--read-bug-ids)))
(gnus-read-ephemeral-bug-group (gnus-read-ephemeral-bug-group
number ids
(cdr (assoc 'debian gnus-bug-group-download-format-alist)))) (alist-get 'debian gnus-bug-group-download-format-alist)
window-conf))
(defvar debbugs-gnu-bug-number) ; debbugs-gnu (defvar debbugs-gnu-bug-number) ; debbugs-gnu
(defun gnus-read-ephemeral-emacs-bug-group (ids &optional window-conf) (defun gnus-read-ephemeral-emacs-bug-group (ids &optional window-conf)
"Browse Emacs bugs IDS as an ephemeral group." "Browse Emacs bug reports with IDS in an ephemeral group.
(interactive (list (string-to-number The arguments have the same meaning as those of
(read-string "Enter bug number: " `gnus-read-ephemeral-bug-group', which see."
(thing-at-point 'word) nil)))) (interactive (list (gnus-group--read-bug-ids)))
(when (stringp ids)
(setq ids (string-to-number ids)))
(unless (listp ids)
(setq ids (list ids)))
(gnus-read-ephemeral-bug-group (gnus-read-ephemeral-bug-group
ids ids
(cdr (assoc 'emacs gnus-bug-group-download-format-alist)) (alist-get 'emacs gnus-bug-group-download-format-alist)
window-conf) window-conf)
(when (fboundp 'debbugs-gnu-summary-mode) (when (and (require 'debbugs-gnu nil t)
(fboundp 'debbugs-gnu-summary-mode))
(with-current-buffer (window-buffer (selected-window)) (with-current-buffer (window-buffer (selected-window))
(debbugs-gnu-summary-mode 1) (debbugs-gnu-summary-mode 1)
(set (make-local-variable 'debbugs-gnu-bug-number) (car ids))))) (let ((id (or (car-safe ids) ids)))
(if (stringp id) (setq id (string-to-number id)))
(setq-local debbugs-gnu-bug-number id)))))
(defun gnus-group-jump-to-group (group &optional prompt) (defun gnus-group-jump-to-group (group &optional prompt)
"Jump to newsgroup GROUP. "Jump to newsgroup GROUP.