>From 4595e0f159fffc93fc5be750478e52db4885d373 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Tue, 3 Nov 2020 22:54:34 +0000 Subject: [PATCH] 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): Pop to *eww pdf* buffer only if it is used for displaying a document; otherwise kill it (bug#44338). Simplify buffer-substring+insert as insert-buffer-substring. --- 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 ebc75e0e8a..e9763ef6df 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -811,14 +811,19 @@ eww-display-image (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) + (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 94cd9e2156..ad715c4b0e 100644 --- a/lisp/net/mailcap.el +++ b/lisp/net/mailcap.el @@ -1128,20 +1128,30 @@ mailcap-file-default-commands 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) -- 2.28.0