branch: externals/ess
commit be4bf810e1a160fbc444043c198e7be6ae93b9d3
Author: Lionel Henry <lionel....@gmail.com>
Commit: Lionel Henry <lionel....@gmail.com>

    Extract `ess--command-error-handler` from `ess-command`
---
 lisp/ess-inf.el | 111 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 62 insertions(+), 49 deletions(-)

diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el
index 0a07ca744f..b928c5dfcb 100644
--- a/lisp/ess-inf.el
+++ b/lisp/ess-inf.el
@@ -1393,56 +1393,44 @@ wrapping the code into:
         ;; Swap the process buffer with the output buffer before
         ;; sending the command
         (unwind-protect
-            (progn
-              ;; The process is restored from the filter once it's
-              ;; available again (i.e. a prompt or delimiter is
-              ;; detected). This handles the synchronous case when the
-              ;; command runs to completion, as well as the
-              ;; asynchronous case when an early exit occurs. The most
-              ;; common cause of early exits are interrupts sent by
-              ;; Emacs when the user types (see `when-no-input'). In
-              ;; these cases we forward the interrupt to the process
-              ;; and return to the caller right away. We can't restore
-              ;; synchronously after an interrupt because the output
-              ;; of the background command would spill into the
-              ;; process buffer of the user when the process doesn't
-              ;; interrupt in time.
-              (process-put proc 'cmd-restore-function
-                           (ess--command-make-restore-function proc))
-              (when use-delimiter
-                (process-put proc 'cmd-output-delimiter delim))
-              (process-put proc 'cmd-buffer out-buffer)
-              (set-process-filter proc 'inferior-ess-ordinary-filter)
-              (with-current-buffer out-buffer
-                (ess-setq-vars-local proc-forward-alist)
-                (setq buffer-read-only nil)
-                (erase-buffer)
-                (inferior-ess-mark-as-busy proc)
-                (process-send-string proc rich-cmd)
-                ;; Need time for ess-create-object-name-db on PC
-                (if no-prompt-check
-                    (sleep-for 0.02) ; 0.1 is noticeable!
-                  (unless (ess-wait-for-process proc nil wait force-redisplay 
timeout)
-                    (error "Timeout during background ESS command `%s'"
-                           (ess--strip-final-newlines cmd)))))
-              (setq early-exit nil))
+            (condition-case err
+                (progn
+                  ;; The process is restored from the filter once it's
+                  ;; available again (i.e. a prompt or delimiter is
+                  ;; detected). This handles the synchronous case when the
+                  ;; command runs to completion, as well as the
+                  ;; asynchronous case when an early exit occurs. The most
+                  ;; common cause of early exits are interrupts sent by
+                  ;; Emacs when the user types (see `when-no-input'). In
+                  ;; these cases we forward the interrupt to the process
+                  ;; and return to the caller right away. We can't restore
+                  ;; synchronously after an interrupt because the output
+                  ;; of the background command would spill into the
+                  ;; process buffer of the user when the process doesn't
+                  ;; interrupt in time.
+                  (process-put proc 'cmd-restore-function
+                               (ess--command-make-restore-function proc))
+                  (when use-delimiter
+                    (process-put proc 'cmd-output-delimiter delim))
+                  (process-put proc 'cmd-buffer out-buffer)
+                  (set-process-filter proc 'inferior-ess-ordinary-filter)
+                  (with-current-buffer out-buffer
+                    (ess-setq-vars-local proc-forward-alist)
+                    (setq buffer-read-only nil)
+                    (erase-buffer)
+                    (inferior-ess-mark-as-busy proc)
+                    (process-send-string proc rich-cmd)
+                    ;; Need time for ess-create-object-name-db on PC
+                    (if no-prompt-check
+                        (sleep-for 0.02) ; 0.1 is noticeable!
+                      (unless (ess-wait-for-process proc nil wait 
force-redisplay timeout)
+                        (error "Timeout during background ESS command `%s'"
+                               (ess--strip-final-newlines cmd))))
+                    (setq early-exit nil)))
+              (error (setq early-exit err))
+              (quit (setq early-exit err)))
           (if early-exit
-              ;; Protect process interruption from further quits
-              (let ((inhibit-quit t))
-                ;; In case of early exit send an interrupt to the
-                ;; process to abort the command
-                (with-current-buffer out-buffer
-                  (goto-char (point-min))
-                  (when (and use-delimiter
-                             (not (re-search-forward (ess--delimiter-start-re 
delim) nil t)))
-                    ;; CMD probably failed to parse if the start delimiter
-                    ;; can't be found in the output. Disable the delimiter
-                    ;; before interrupt to avoid a freeze.
-                    (ess-write-to-dribble-buffer
-                     "Disabling output delimiter because CMD failed to 
parse\n")
-                    (process-put proc 'cmd-output-delimiter nil))
-                  (goto-char (point-max))
-                  (ess--interrupt proc)))
+              (ess--command-error-handler proc out-buffer use-delimiter delim 
early-exit)
             (with-current-buffer out-buffer
               (goto-char (point-min))
               (when (re-search-forward (ess--delimiter-error-start-re) nil t)
@@ -1454,6 +1442,31 @@ wrapping the code into:
                              (buffer-substring start end)))))))))))
     out-buffer))
 
+(defun ess--command-error-handler (proc
+                                   out-buffer
+                                   use-delimiter
+                                   delim
+                                   early-exit)
+  (let ((inhibit-quit t))
+    ;; In case of early exit send an interrupt to the
+    ;; process to abort the command
+    (with-current-buffer out-buffer
+      (goto-char (point-min))
+      (when (and use-delimiter
+                 (not (re-search-forward (ess--delimiter-start-re delim) nil 
t)))
+        ;; CMD probably failed to parse if the start delimiter
+        ;; can't be found in the output. Disable the delimiter
+        ;; before interrupt to avoid a freeze.
+        (ess-write-to-dribble-buffer
+         "Disabling output delimiter because CMD failed to parse\n")
+        (process-put proc 'cmd-output-delimiter nil))
+      (goto-char (point-max))
+      (ess--interrupt proc)))
+  ;; Can be `t` when early exit is caused e.g. by a throw instead of
+  ;; an error or a quit
+  (unless (eq early-exit t)
+    (signal (car early-exit) (cdr early-exit))))
+
 ;; (ess-process-get 'ess-format-command-alist)
 ;;   "Alist of mode-specific parameters for formatting a command.
 ;; All elements are optional.

Reply via email to