diff options
Diffstat (limited to 'piem.el')
-rw-r--r-- | piem.el | 116 |
1 files changed, 76 insertions, 40 deletions
@@ -4,7 +4,7 @@ ;; Author: Kyle Meyer <kyle@kyleam.com> ;; Keywords: vc, tools -;; Version: 0.4.0 +;; Version: 0.5.0 ;; Package-Requires: ((emacs "26.3") (transient "0.3.0")) ;; Homepage: https://git.kyleam.com/piem/about/ @@ -80,9 +80,11 @@ list that supports the following properties: repository, with the first value in this list offered as the default. :url - A URL hosting HTTPS archives. This value must end with a slash. + A URL hosting HTTPS archives. :maildir A Maildir directory to inject messages into. + :gnu-package + A GNU Bug Tracker label to match with for the inbox. Here's an example for the public-inbox project itself: @@ -156,10 +158,10 @@ value passed to `git am'. If unspecified, \"mboxrd\" is used." :type 'hook) (defcustom piem-add-message-id-header nil - "Whether to add Message-Id header to non-mail patches. + "Whether to add Message-ID header to non-mail patches. If this value is non-nil and a patch returned by a function in `piem-am-ready-mbox-functions' looks like a patch that was -attached rather than sent inline, add a Message-Id header with +attached rather than sent inline, add a Message-ID header with the return value of `piem-mid'." :type 'boolean) @@ -393,7 +395,9 @@ files." (rx string-start "publicinbox." (group (one-or-more not-newline)) "." (group - (or "address" "coderepo" "listid" "maildir" "url")) + (or "address" "coderepo" + "listid" "maildir" + "url" "gnu-package")) string-end) key) (let* ((inbox-name (match-string 1 key)) @@ -488,27 +492,46 @@ non-nil, make the match specific for that message." (mail-decode-encoded-word-string val))) headers)))) +(defun piem-inbox-by-gnu-package-match (gnu-package) + "Return inbox based on matching :gnu-package properties. +GNU-PACKAGE should be a string. This function is intended to be +used by libraries implementing a function for +`piem-get-inbox-function'." + (when gnu-package + (catch 'hit + (dolist (inbox (piem-merged-inboxes)) + (let* ((info (cdr inbox)) + (p-package (plist-get info :gnu-package))) + (when (and gnu-package + p-package + (string-equal (downcase p-package) + (downcase gnu-package))) + (throw 'hit (car inbox)))))))) + (defun piem-inbox-by-header-match () "Return inbox based on matching message headers. This should be called from a buffer containing a message and is intended to be used by libraries implementing a function for -`piem-get-mid-functions'." - (pcase-let ((`(,listid ,to ,cc) - (piem--message-fetch-decoded-fields '("list-id" "to" "cc")))) - (catch 'hit - (dolist (inbox (piem-merged-inboxes)) - (let* ((info (cdr inbox)) - (p-listid (plist-get info :listid))) - (when (and listid - p-listid - (string-match-p (concat "<" (regexp-quote p-listid) ">") - listid)) - (throw 'hit (car inbox))) - (when-let ((addr (plist-get info :address)) - (to (mapconcat #'identity (list to cc) - " "))) - (when (string-match-p (regexp-quote addr) to) - (throw 'hit (car inbox))))))))) +`piem-get-inbox-functions'." + (pcase-let ((`(,listid ,to ,cc ,gnu-package) + (piem--message-fetch-decoded-fields + '("list-id" "to" "cc" "x-gnu-pr-package")))) + (or (catch 'hit + (dolist (inbox (piem-merged-inboxes)) + (let* ((info (cdr inbox)) + (p-listid (plist-get info :listid))) + (when (and listid + p-listid + (string-match-p + (concat "<" (regexp-quote p-listid) ">") + listid)) + (throw 'hit (car inbox))) + (when-let ((addr (plist-get info :address)) + (to (mapconcat #'identity (list to cc) + " "))) + (when (string-match-p (regexp-quote addr) to) + (throw 'hit (car inbox))))))) + (piem-inbox-by-gnu-package-match gnu-package)))) (defun piem-inbox () "Return the current buffer's inbox." @@ -522,6 +545,13 @@ returned by `piem-inbox'." (when-let ((p (or inbox (piem-inbox)))) (plist-get (cdr (assoc p (piem-merged-inboxes))) key))) +(defun piem-inbox-url (&optional inbox) + "Return URL associated with INBOX. +If INBOX is nil, use the inbox returned by `piem-inbox'." + (when-let ((inbox (or inbox (piem-inbox))) + (url (piem-inbox-get :url inbox))) + (piem--ensure-trailing-slash url))) + (defun piem-inbox-coderepo (&optional inbox) "Return the code repository of current buffer's inbox." (when-let ((inbox (or inbox (piem-inbox))) @@ -601,8 +631,11 @@ public-inbox's configuration), return the value of (rx line-start (zero-or-one space) line-end)))) (cond ((looking-at-p + ;; git-format-patch switched to "Message-ID" spelling + ;; in v2.41. (rx line-start - "Message-Id: <" (one-or-more not-newline) ">" + "Message-" (or "Id" "ID") + ": <" (one-or-more not-newline) ">" line-end)) (throw 'has-message-id nil)) ((looking-at-p @@ -612,7 +645,7 @@ public-inbox's configuration), return the value of (when (= header-count 3) ;; Found all the expected headers before hitting a ;; blank line. Assume we're in a header. - (insert (format "Message-Id: <%s>\n" mid)))))))) + (insert (format "Message-ID: <%s>\n" mid)))))))) (defun piem-am-ready-mbox (&optional buffer-name) "Generate a buffer containing an am-ready mbox. @@ -662,10 +695,9 @@ The URL for INBOX may be defined in `piem-inboxes' or public-inbox's configuration. If INBOX is nil, use the inbox returned by `piem-inbox'." (concat - (piem--ensure-trailing-slash - (or (piem-inbox-get :url inbox) - (user-error "Couldn't find URL for %s" - (or inbox "current buffer")))) + (or (piem-inbox-url inbox) + (user-error "Couldn't find URL for %s" + (or inbox "current buffer"))) (piem-escape-mid mid))) ;;;###autoload @@ -756,7 +788,7 @@ is used as the value of `browse-url-browser-function'." (save-excursion (message-narrow-to-head-1) (message-fetch-field "message-id" t))) - (error "Message lacks Message-Id header"))))))) + (error "Message lacks Message-ID header"))))))) (cl-incf n-skipped) (let ((case-fold-search nil)) (while (re-search-forward @@ -817,17 +849,21 @@ message for MID, not the entire thread." ;;;; Patch handling (defun piem-am-extract-attached-patch (handle) - "Return content for HANDLE if it looks like a patch." - (and (listp handle) - (let ((type (mm-handle-media-type handle)) - (filename (mm-handle-filename handle))) - (or (member type '("text/x-diff" "text/x-patch")) - (and filename - (equal type "text/plain") - (string-suffix-p ".patch" filename t)))) - (with-temp-buffer - (mm-display-inline handle) - (buffer-substring-no-properties (point-min) (point-max))))) + "Get the content for HANDLE if it looks like a patch. +The return value is of the form (N . CONTENT), where N is the +number at the start of the file name." + (when (listp handle) + (let ((type (mm-handle-media-type handle)) + (filename (mm-handle-filename handle))) + (and (or (member type '("text/x-diff" "text/x-patch")) + (and filename + (equal type "text/plain") + (string-suffix-p ".patch" filename t))) + (with-temp-buffer + (mm-display-inline handle) + (cons + (string-to-number filename) + (buffer-substring-no-properties (point-min) (point-max)))))))) (defun piem-extract-mbox-info (&optional buffer) "Collect information from message in BUFFER. |