On 2018-09-03 18:21:32, David Edmondson wrote:
> How about this patch?
>
> You'll need to set “notmuch-crypto-get-keys-asynchronously” to “t” to
> see any benefit.

This is great!

As you said on IRC, the patch is more likely:

diff --git i/emacs/notmuch-crypto.el w/emacs/notmuch-crypto.el
index fc2b5301..175dc5f2 100644
--- i/emacs/notmuch-crypto.el
+++ w/emacs/notmuch-crypto.el
@@ -43,6 +43,18 @@ mode."
   :package-version '(notmuch . "0.25")
   :group 'notmuch-crypto)
 
+(defcustom notmuch-crypto-get-keys-asynchronously nil
+  "Retrieve gpg keys asynchronously.
+
+If this variable is non-nil, hitting the crypto button will
+trigger network operations in the background. This will also have
+the effect of disabling the automatic refresh on completion. Keep
+this set to nil to make sure the button display is up to date,
+but this will freeze everything until the crypto operation is
+completed, which can take a long time for larger keyrings."
+  :type 'boolean
+  :group 'notmuch-crypto)
+
 (defface notmuch-crypto-part-header
   '((((class color)
       (background dark))
@@ -145,19 +157,35 @@ mode."
 	(call-process epg-gpg-program nil t t "--list-keys" fingerprint))
       (recenter -1))))
 
+(defun notmuch-crypto--async-key-sentinel (process event)
+  (let ((status (process-status process))
+	(exit-status (process-exit-status process)))
+    (when (memq status '(exit signal))
+      (message "Asynchronous GPG key retrieval %s."
+	       (if (= exit-status 0)
+		   "completed"
+		 "failed")))))
+
 (defun notmuch-crypto-sigstatus-error-callback (button)
   (let* ((sigstatus (button-get button :notmuch-sigstatus))
 	 (keyid (concat "0x" (plist-get sigstatus :keyid)))
-	 (buffer (get-buffer-create "*notmuch-crypto-gpg-out*"))
-	 (window (display-buffer buffer t nil)))
-    (with-selected-window window
-      (with-current-buffer buffer
-	(goto-char (point-max))
-	(call-process epg-gpg-program nil t t "--recv-keys" keyid)
-	(insert "\n")
-	(call-process epg-gpg-program nil t t "--list-keys" keyid))
-      (recenter -1))
-    (notmuch-show-refresh-view)))
+	 (buffer (get-buffer-create "*notmuch-crypto-gpg-out*")))
+    (if notmuch-crypto-get-keys-asynchronously
+	(progn
+	  (message "Getting the GPG key %s asynchronously..." keyid)
+	  (make-process :name "notmuch GPG key retrieval"
+		       :buffer buffer
+		       :command (list epg-gpg-program "--recv-keys" keyid)
+		       :sentinel #'notmuch-crypto--async-key-sentinel))
+      (let ((window (display-buffer buffer t nil)))
+	(with-selected-window window
+	  (with-current-buffer buffer
+	    (goto-char (point-max))
+	    (call-process epg-gpg-program nil t t "--recv-keys" keyid)
+	    (insert "\n")
+	    (call-process epg-gpg-program nil t t "--list-keys" keyid))
+	  (recenter -1))
+	(notmuch-show-refresh-view)))))
 
 (defun notmuch-crypto-insert-encstatus-button (encstatus)
   (let* ((status (plist-get encstatus :status))
One thing that's missing is to refresh the view automatically. I
understand this might be difficult to implement however. For example, I
naively tried to add this at the end of the sentinel:

      (when (= exit-status 0)
        (notmuch-show-refresh-view))

Then switch to another buffer (back to the search view, FWIW). The
sentinel then fails with:

error in process sentinel: notmuch-escape-boolean-term: Wrong type argument: 
stringp, nil
error in process sentinel: Wrong type argument: stringp, nil

Not sure why exactly. But I would certainly take the async update over
automatic refresh any time. It would also be useful to indicate that
will be the effect of the variable in the customize help as well. I gave
that a try in the above patch.

Thanks for the ultra-fast response!

A.

-- 
The United States is a nation of laws:
badly written and randomly enforced.
                        - Frank Zappa
_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to