summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Meyer <kyle@kyleam.com>2021-02-07 12:39:22 -0500
committerKyle Meyer <kyle@kyleam.com>2021-02-07 12:39:22 -0500
commit2339ba46872bf990129275771306182c82235dbf (patch)
tree456917ee4cb83a2c7ff3494b1f9e23eea06d7fe9
parent0cc9929f21448e7cb34ecc23bf9ff4fc7bef4773 (diff)
parentf4975ba183c54ec364827380ee70c5ccc426e06f (diff)
downloadpiem-2339ba46872bf990129275771306182c82235dbf.tar.gz
Merge branch 'km/copy-mid-url'
-rw-r--r--piem-notmuch.el10
-rw-r--r--piem.el70
-rw-r--r--piem.texi35
-rw-r--r--tests/piem-tests.el13
4 files changed, 111 insertions, 17 deletions
diff --git a/piem-notmuch.el b/piem-notmuch.el
index a222f3f..2a5c525 100644
--- a/piem-notmuch.el
+++ b/piem-notmuch.el
@@ -109,13 +109,9 @@ message itself if it looks like a patch."
(defun piem-notmuch-show-get-public-inbox-link (mid)
"Given the message-id MID, return the public-inbox url.
This will lookup the url in the `piem-inboxes' variable."
- (let* ((inbox (or (piem-notmuch-get-inbox)
- (user-error "No inbox associated with current buffer")))
- (link (or (piem-inbox-get :url inbox)
- (user-error "No url was found for %s" inbox))))
- (concat
- (piem--ensure-trailing-slash link)
- (piem-escape-mid mid))))
+ (piem-mid-url mid
+ (or (piem-notmuch-get-inbox)
+ (user-error "No inbox associated with current buffer"))))
;;;###autoload
(define-minor-mode piem-notmuch-mode
diff --git a/piem.el b/piem.el
index b66894f..6424498 100644
--- a/piem.el
+++ b/piem.el
@@ -37,6 +37,7 @@
;;; Code:
+(require 'browse-url)
(require 'cl-lib)
(require 'mail-extr)
(require 'message)
@@ -191,6 +192,29 @@ Functions should accept one argument, the message ID given to
`piem-inject-thread-into-maildir'."
:type 'hook)
+(defcustom piem-browse-url-browser-function nil
+ "Overriding value for `browse-url-browser-function'.
+
+public-inbox's HTTP interface is well suited for browsers like
+w3m and EWW, allowing you to stay in Emacs rather than launch an
+external browser. However, assuming you have `browse-url'
+configured to usually go through an external browser, sending
+public-inbox URLs through, say, EWW would require you to
+configure `browse-url-browser-function' with a regular expression
+for each inbox URL that you want to be handled by
+`eww-browse-url'.
+
+Instead, you can simply set this option to `eww-browse-url' (or
+anything else `browse-url-browser-function' accepts), and piem
+will use it when calling `browse-url'.
+
+When this option is nil, piem calls `browse-url' without
+overriding the value of `browse-url-browser-function'."
+ :type (append
+ '(choice
+ (const :tag "Don't override `browse-url-browser-function'" nil))
+ (cdr (get 'browse-url-browser-function 'custom-type))))
+
;;;; Subprocess handling
@@ -444,7 +468,7 @@ buffer."
nil))))
-;;;; Download helpers
+;;;; Link handling
(defconst piem--unreserved-chars
(append url-unreserved-chars
@@ -456,6 +480,38 @@ buffer."
"Escape MID for use in path part of a public-inbox URL."
(url-hexify-string mid piem--unreserved-chars))
+(defun piem-mid-url (mid &optional inbox)
+ "Return a public-inbox URL for MID.
+The URL is determined by INBOX's entry in `piem-inboxes'. 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"))))
+ (piem-escape-mid mid)))
+
+(defun piem-copy-mid-url (&optional browse)
+ "Copy public-inbox URL for the current buffer's message.
+With prefix argument BROWSE, call `browse-url' on the URL
+afterwards. If `piem-browse-url-browser-function' is non-nil, it
+is used as the value of `browse-url-browser-function'."
+ (interactive "P")
+ (let ((url (piem-mid-url
+ (or (piem-mid)
+ (user-error "No message ID found for the current buffer"))
+ (piem-inbox))))
+ (prog1
+ (kill-new (message "%s" url))
+ (when browse
+ (let ((browse-url-browser-function
+ (or piem-browse-url-browser-function
+ browse-url-browser-function)))
+ (browse-url url))))))
+
+
+;;;; Download helpers
+
(defvar piem--has-gunzip)
(defun piem-check-gunzip ()
"Return non-nil if gunzip is available."
@@ -550,10 +606,7 @@ This function depends on :url being configured for entries in
"`piem-maildir-directory' does not look like a Maildir directory"))
((not (or message-only (piem-check-gunzip)))
(user-error "gunzip executable not found")))
- (when-let ((url (concat (or (piem-inbox-get :url)
- (user-error
- "Could not find inbox URL for current buffer"))
- (piem-escape-mid mid)
+ (when-let ((url (concat (piem-mid-url mid)
(if message-only "/raw" "/t.mbox.gz")))
(buffer (url-retrieve-synchronously url 'silent)))
(unwind-protect
@@ -776,9 +829,10 @@ this triggers the creation of a new worktree."
;;;###autoload (autoload 'piem-dispatch "piem" nil t)
(define-transient-command piem-dispatch ()
"Invoke a piem command."
- [("a" "apply patch" piem-am)
- ("b" "call b4-am" piem-b4-am)
- ("i" "inject thread into maildir" piem-inject-thread-into-maildir)])
+ [[("a" "apply patch" piem-am)
+ ("b" "call b4-am" piem-b4-am)]
+ [("i" "inject thread into maildir" piem-inject-thread-into-maildir)
+ ("l" "copy public-inbox link" piem-copy-mid-url)]])
diff --git a/piem.texi b/piem.texi
index e7b4b32..aa48705 100644
--- a/piem.texi
+++ b/piem.texi
@@ -48,7 +48,7 @@ This manual is for piem version @value{VERSION}.
* Overview::
* Getting started::
* Applying patches::
-* Injecting messages into a Maildir directory::
+* Miscellaneous functionality::
* Contributing::
* Related projects and tools::
@@ -384,8 +384,11 @@ other things, functionality for applying patch series, including
b4-inspired patch extraction.
+@node Miscellaneous functionality
+@chapter Miscellaneous functionality
+
@node Injecting messages into a Maildir directory
-@chapter Injecting messages into a Maildir directory
+@section Injecting messages into a Maildir directory
@cindex Maildir
public-inbox allows you to follow lists through several mechanisms
@@ -442,6 +445,34 @@ non-nil if a message ID is known and should be skipped. For Notmuch,
#'piem-notmuch-known-mid-p)
@end lisp
+@node Copying public-inbox URLs
+@section Copying public-inbox URLs
+
+@findex piem-copy-mid-url
+When referring to a message from a public-inbox archive, a common format
+to use is a URL that points to a specific archive and ends with
+@code{/$INBOX/$MESSAGE_ID}, e.g.,
+@url{https://public-inbox.org/meta/20190108015420.GA28903@@dcvr}.
+Calling @code{piem-copy-mid-url} (available in the @code{piem-dispatch}
+transient) constructs such a URL, using the message ID and inbox
+asscociated with the current buffer, and then copies the URL to the kill
+ring. When a prefix agument is given, @code{browse-url} is called after
+copying the URL.
+
+@vindex piem-browse-url-browser-function
+Note that EWW works nicely with public-inbox's HTTP interface. If you'd
+prefer it to be invoked even though it's not your default browser (as
+configured by @code{browse-url-browser-function}), you can set
+@code{piem-browse-url-browser-function} to @code{eww-browse-url}.
+
+@findex piem-notmuch-mode
+@findex piem-notmuch-show-get-public-inbox-link
+For notmuch.el users, there's an additional entry point for copying
+public-inbox URLs: enabling @code{piem-notmuch-mode} adds a ``piem''
+candidate to archives offered by
+@code{notmuch-show-stash-mlarchive-link} and
+@code{notmuch-show-stash-mlarchive-link-and-go}.
+
@node Contributing
@chapter Contributing
diff --git a/tests/piem-tests.el b/tests/piem-tests.el
index 795686a..969c9d0 100644
--- a/tests/piem-tests.el
+++ b/tests/piem-tests.el
@@ -49,6 +49,19 @@
(should (equal (piem-escape-mid "msg@id") "msg@id"))
(should (equal (piem-escape-mid "m/g@id") "m%2Fg@id")))
+(ert-deftest piem-mid-url ()
+ (let ((piem-inboxes '(("inbox-a" :url "https://example.com/a/")
+ ("inbox-b" :url "https://example.com/b/"))))
+ (should (equal (piem-mid-url "msg@id" "inbox-a")
+ "https://example.com/a/msg@id"))
+ (should (equal (piem-mid-url "m/sg@id" "inbox-b")
+ "https://example.com/b/m%2Fsg@id"))
+ (should-error (piem-mid-url "msg@id")
+ :type 'user-error))
+ (let ((piem-inboxes '(("inbox-a"))))
+ (should-error (piem-mid-url "msg@id" "inbox-a")
+ :type 'user-error)))
+
(ert-deftest piem-name-branch-who-what-v ()
(should (equal (piem-name-branch-who-what-v
(list :from "Foo Bar <f@example.com>"