emacs-diffs
[Top][All Lists]
Advanced

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

master bfd3124: Improve eww support for externally viewed PDFs


From: Basil L. Contovounesios
Subject: master bfd3124: Improve eww support for externally viewed PDFs
Date: Thu, 5 Nov 2020 12:34:41 -0500 (EST)

branch: master
commit bfd31242025cde90c8252db92dc54d0be4115c91
Author: Basil L. Contovounesios <contovob@tcd.ie>
Commit: Basil L. Contovounesios <contovob@tcd.ie>

    Improve eww support for externally viewed PDFs
    
    The *eww pdf* buffer is only needed when viewing PDFs within Emacs,
    e.g., with doc-view-mode.  External PDF viewers are called with a
    temporary file, so the buffer is not needed in that case.  What's
    more, mailcap-view-mime erased the buffer and left it in
    fundamental-mode until now, so the user was left staring at a
    useless, empty buffer.  To make things even worse, external viewers
    were invoked synchronously until now, so the user could not browse
    the PDF file and use Emacs simultaneously.
    
    * lisp/net/mailcap.el (mailcap--async-shell): New function.
    (mailcap-view-mime): Use it to invoke external viewers
    asynchronously.  Mention erasure of current buffer in that case in
    docstring.  Add a period between the temporary file name and its
    extension.
    
    * lisp/net/eww.el (eww-display-pdf): Simplify using
    insert-buffer-substring.  Fix coding-system-for-write for a stream
    of raw bytes.  Pop to *eww pdf* buffer only if it is used for
    displaying a document; otherwise kill it.  (bug#44338)
---
 lisp/net/eww.el     | 21 +++++++++++++--------
 lisp/net/mailcap.el | 30 ++++++++++++++++++++----------
 2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index ebc75e0..340a913 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -811,14 +811,19 @@ Currently this means either text/html or 
application/xhtml+xml."
 
 (declare-function mailcap-view-mime "mailcap" (type))
 (defun eww-display-pdf ()
-  (let ((data (buffer-substring (point) (point-max))))
-    (pop-to-buffer-same-window (get-buffer-create "*eww pdf*"))
-    (let ((coding-system-for-write 'raw-text)
-         (inhibit-read-only t))
-      (erase-buffer)
-      (insert data)
-      (mailcap-view-mime "application/pdf")))
-  (goto-char (point-min)))
+  (let ((buf (current-buffer))
+        (pos (point)))
+    (with-current-buffer (get-buffer-create "*eww pdf*")
+      (let ((coding-system-for-write 'raw-text-unix)
+            (inhibit-read-only t))
+        (erase-buffer)
+        (insert-buffer-substring buf pos)
+        (mailcap-view-mime "application/pdf"))
+      (if (zerop (buffer-size))
+          ;; Buffer contents passed to shell command via temporary file.
+          (kill-buffer)
+        (goto-char (point-min))
+        (pop-to-buffer-same-window (current-buffer))))))
 
 (defun eww-setup-buffer ()
   (when (or (plist-get eww-data :url)
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index f9c71c9..d0f8c12 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -1131,20 +1131,30 @@ For instance, \"foo.png\" will result in \"image/png\"."
             res)))
        (nreverse res)))))
 
+(defun mailcap--async-shell (command file)
+  "Asynchronously call MIME viewer shell COMMAND.
+Replace %s in COMMAND with FILE, as per `mailcap-mime-data'.
+Delete FILE once COMMAND exits."
+  (let ((buf (get-buffer-create " *mailcap shell*")))
+    (async-shell-command (format command file) buf)
+    (add-function :after (process-sentinel (get-buffer-process buf))
+                  (lambda (proc _msg)
+                    (when (memq (process-status proc) '(exit signal))
+                      (delete-file file))))))
+
 (defun mailcap-view-mime (type)
   "View the data in the current buffer that has MIME type TYPE.
-`mailcap--computed-mime-data' determines the method to use."
+The variable `mailcap--computed-mime-data' determines the method
+to use.  If the method is a shell command string, erase the
+current buffer after passing its contents to the shell command."
   (let ((method (mailcap-mime-info type)))
     (if (stringp method)
-        (let ((file (make-temp-file "emacs-mailcap" nil
-                                    (cadr (split-string type "/")))))
-          (unwind-protect
-              (let ((coding-system-for-write 'binary))
-                (write-region (point-min) (point-max) file nil 'silent)
-                (delete-region (point-min) (point-max))
-                (shell-command (format method file)))
-            (when (file-exists-p file)
-              (delete-file file))))
+        (let* ((ext (concat "." (cadr (split-string type "/"))))
+               (file (make-temp-file "emacs-mailcap" nil ext))
+               (coding-system-for-write 'binary))
+          (write-region nil nil file nil 'silent)
+          (delete-region (point-min) (point-max))
+          (mailcap--async-shell method file))
       (funcall method))))
 
 (provide 'mailcap)



reply via email to

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