1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-06 03:40:56 -08:00

em-extpipe: Catch eshell-incomplete thrown while parsing

* lisp/eshell/em-extpipe.el (em-extpipe--or-with-catch): New macro.
(eshell-parse-external-pipeline): Use new macro to treat
`eshell-incomplete' as a failure of the parse function to move us
forward (Bug#54603).  Thanks to Jim Porter <jporterbugs@gmail.com> for
the report and for help isolating the problem.

* test/lisp/eshell/eshell-tests.el
(eshell-test/lisp-command-with-quote): New test for Bug#54603, thanks
to Jim Porter <jporterbugs@gmail.com> (bug#54603).
This commit is contained in:
Sean Whitton 2022-04-02 16:08:41 +02:00 committed by Lars Ingebrigtsen
parent 6dc4e3b95c
commit 02ef00d89c
2 changed files with 22 additions and 4 deletions

View file

@ -49,6 +49,19 @@
(add-hook 'eshell-pre-rewrite-command-hook
#'eshell-rewrite-external-pipeline -20 t))
(defmacro em-extpipe--or-with-catch (&rest disjuncts)
"Evaluate DISJUNCTS like `or' but catch `eshell-incomplete'.
If `eshell-incomplete' is thrown during the evaluation of a
disjunct, that disjunct yields nil."
(let ((result (gensym)))
`(let (,result)
(or ,@(cl-loop for disjunct in disjuncts collect
`(if (catch 'eshell-incomplete
(ignore (setq ,result ,disjunct)))
nil
,result))))))
(defun eshell-parse-external-pipeline ()
"Parse a pipeline intended for execution by the external shell.
@ -105,10 +118,11 @@ as though it were Eshell syntax."
(if (re-search-forward pat next t)
(throw 'found (match-beginning 1))
(goto-char next)
(while (or (eshell-parse-lisp-argument)
(eshell-parse-backslash)
(eshell-parse-double-quote)
(eshell-parse-literal-quote)))
(while (em-extpipe--or-with-catch
(eshell-parse-lisp-argument)
(eshell-parse-backslash)
(eshell-parse-double-quote)
(eshell-parse-literal-quote)))
;; Guard against an infinite loop if none of
;; the parsers moved us forward.
(unless (or (> (point) next) (eobp))