summaryrefslogtreecommitdiff
path: root/lisp/ess-inf.el
diff options
context:
space:
mode:
authorLionel Henry <lionel.hry@gmail.com>2021-03-24 14:09:32 +0100
committerLionel Henry <lionel.hry@gmail.com>2021-03-31 09:50:44 +0200
commit6d4028462ca0cb2cec3e9a6dcb33b7529ddffaa7 (patch)
tree253d1d240ea6e2c642e11337906a5e0777e8a453 /lisp/ess-inf.el
parentab9545ce4b1ae4349041e45fae706a7d6c771f5e (diff)
Be defensive against missing trailing newlines in output
And defensive against errors in background filter
Diffstat (limited to 'lisp/ess-inf.el')
-rw-r--r--lisp/ess-inf.el49
1 files changed, 30 insertions, 19 deletions
diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el
index 229bae5..4cd0e31 100644
--- a/lisp/ess-inf.el
+++ b/lisp/ess-inf.el
@@ -418,9 +418,12 @@ output, if any."
(when (re-search-forward (ess--delimiter-start-re delim) nil t)
(let ((start (1+ (match-end 0))))
(when (re-search-forward (ess--delimiter-end-re delim) nil t)
+ (when (not (equal (line-beginning-position)
+ (match-beginning 0)))
+ (error "Missing newline in command output"))
(let ((end (max (1- (match-beginning 0))
start)))
- (goto-char (match-end 0))
+ (goto-char (1+ (match-end 0)))
(goto-char (- (line-end-position) 2))
(when (looking-at "> ")
(let ((new (when (> (point-max) (line-end-position))
@@ -475,7 +478,7 @@ buffer instead of the command buffer."
(concat "\\(" delim "-START$\\)"))
(defun ess--delimiter-end-re (delim)
- (concat "^\\(" delim "-END[\n\r]+\\)"))
+ (concat "\\(" delim "-END\\)"))
(defun inferior-ess-mark-as-busy (proc)
"Put PROC's busy value to t."
@@ -1062,23 +1065,31 @@ Returns nil if TIMEOUT was reached, non-nil otherwise."
(defun inferior-ess-ordinary-filter (proc string)
(ess--if-verbose-write-process-state proc string "ordinary-filter")
(let* ((cmd-buf (process-get proc 'cmd-buffer))
- (cmd-delim (process-get proc 'cmd-output-delimiter)))
- (with-current-buffer cmd-buf
- (goto-char (point-max))
- (insert string))
- (when-let ((info (if cmd-delim
- (ess--command-delimited-output-info cmd-buf cmd-delim)
- (ess--command-output-info cmd-buf))))
- (ess--command-set-status proc cmd-buf info)
- (when (not (process-get proc 'busy))
- ;; Restore the user's process filter as soon as process is
- ;; available
- (when-let ((cmd-restore-function (process-get proc 'cmd-restore-function)))
- (funcall cmd-restore-function))
- ;; Run callback with command output
- (when-let ((cb (process-get proc 'callbacks)))
- (inferior-ess-run-callback proc (with-current-buffer cmd-buf
- (buffer-string))))))))
+ (cmd-delim (process-get proc 'cmd-output-delimiter))
+ (early-exit t))
+ (unwind-protect
+ (progn
+ (with-current-buffer cmd-buf
+ (goto-char (point-max))
+ (insert string))
+ (when-let ((info (if cmd-delim
+ (ess--command-delimited-output-info cmd-buf cmd-delim)
+ (ess--command-output-info cmd-buf))))
+ (ess--command-set-status proc cmd-buf info)
+ (when (not (process-get proc 'busy))
+ ;; Restore the user's process filter as soon as process is
+ ;; available
+ (funcall (process-get proc 'cmd-restore-function))
+ ;; Run callback with command output
+ (when (process-get proc 'callbacks)
+ (inferior-ess-run-callback proc (with-current-buffer cmd-buf
+ (buffer-string))))))
+ (setq early-exit nil))
+ ;; Be defensive when something goes wrong. Restore process to a
+ ;; usable state.
+ (when early-exit
+ (process-put proc 'busy nil)
+ (funcall (process-get proc 'cmd-restore-function))))))
(defvar ess-presend-filter-functions nil
"List of functions to call before sending the input string to the process.