unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#54603: 29.0.50; [PATCH] Eshell's external pipe module interferes with other argument parsing hooks
@ 2022-03-28  2:21 Jim Porter
  2022-03-31 11:46 ` Lars Ingebrigtsen
  2022-03-31 18:26 ` Sean Whitton
  0 siblings, 2 replies; 16+ messages in thread
From: Jim Porter @ 2022-03-28  2:21 UTC (permalink / raw)
  To: 54603

[-- Attachment #1: Type: text/plain, Size: 1838 bytes --]

 From "emacs -Q --eval '(eshell)':

   ~ $ (eq 'foo nil)
   Expecting completion of delimiter ' ...

   M-: (unload-feature 'em-extpipe)

   ~ $ (eq 'foo nil)
   ;; No output, since it returns nil. This is correct.

(As an ironic twist, you'd normally be able to run "(unload-feature 
'em-extpipe)" as a command in Eshell, but this bug prevents that from 
working.)

I don't fully understand all the details of the code in 
lisp/eshell/em-extpipe.el yet, but I think this is the culprit:

                          (while (or (eshell-parse-lisp-argument)
                                     (eshell-parse-backslash)
                                     (eshell-parse-double-quote)
                                     (eshell-parse-literal-quote)))

In particular, since there are 3 single-quotes, 
`eshell-parse-literal-quote' throws an `eshell-incomplete' error, which 
gums up the works.

The attached patch resolves the issue for me, but I'm not sure if it's 
the best strategy. If possible, I think it would be better for 
`eshell-parse-external-pipeline' to solely focus on finding the external 
pipe operators ("*|", "*<", and "*>")[1] and then for 
`eshell-rewrite-external-pipeline' to prepare the command string to pass 
to sh. This would also have the advantage[2] of making it possible to 
support a richer set of Eshell features with external pipes, such as the 
following:

   ~ $ echo $(message "[%s]" "hi") *| cat
   zsh:1: command not found: message

(If you remove the "*", this outputs "[hi]", and it should be 
technically possible to make this work with external pipes too, provided 
it executes the Lisp code before generating the command string for sh.)

[1] See `eshell-parse-delimiter' for an example of how that might be 
implemented.
[2] Well, maybe there's room for debate on what the right behavior here is.

[-- Attachment #2: 0001-Make-Eshell-s-extpipe-more-lenient-when-looking-for-.patch --]
[-- Type: text/plain, Size: 2576 bytes --]

From fab48a28ff80f1c74f2d50d4f69edb056f88d119 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Sun, 27 Mar 2022 19:04:42 -0700
Subject: [PATCH] Make Eshell's extpipe more lenient when looking for its
 operators

This could cause some errors when executing Eshell commands with an
odd number of quotation marks, such as "(eq 'foo nil)".

* lisp/eshell/em-extpipe.el (eshell-parse-external-pipeline): Catch
'eshell-incomplete' errors.

* test/lisp/eshell/eshell-tests.el
(eshell-test/lisp-command-with-quote): New test.
---
 lisp/eshell/em-extpipe.el        | 9 +++++----
 test/lisp/eshell/eshell-tests.el | 4 ++++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/lisp/eshell/em-extpipe.el b/lisp/eshell/em-extpipe.el
index eb5b3bfe1d..e7b421982a 100644
--- a/lisp/eshell/em-extpipe.el
+++ b/lisp/eshell/em-extpipe.el
@@ -105,10 +105,11 @@ eshell-parse-external-pipeline
                        (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)))
+                         (catch 'eshell-incomplete
+                           (while (or (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))
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index e31db07c61..1e303f70e5 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -44,6 +44,10 @@ eshell-test/lisp-command
   "Test `eshell-command-result' with an elisp command."
   (should (equal (eshell-test-command-result "(+ 1 2)") 3)))
 
+(ert-deftest eshell-test/lisp-command-with-quote ()
+  "Test `eshell-command-result' with an elisp command containing a quote."
+  (should (equal (eshell-test-command-result "(eq 'foo nil)") nil)))
+
 (ert-deftest eshell-test/for-loop ()
   "Test `eshell-command-result' with a for loop.."
   (let ((process-environment (cons "foo" process-environment)))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-04-02 15:52 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-28  2:21 bug#54603: 29.0.50; [PATCH] Eshell's external pipe module interferes with other argument parsing hooks Jim Porter
2022-03-31 11:46 ` Lars Ingebrigtsen
2022-03-31 16:26   ` Jim Porter
2022-03-31 16:50     ` Eli Zaretskii
2022-03-31 17:35     ` Michael Albinus
2022-03-31 22:55   ` Sean Whitton
2022-03-31 18:26 ` Sean Whitton
2022-03-31 20:58   ` Jim Porter
2022-03-31 21:55     ` Sean Whitton
2022-03-31 22:19       ` Jim Porter
2022-03-31 22:48         ` Sean Whitton
2022-03-31 23:31           ` Jim Porter
2022-04-01 21:16             ` Sean Whitton
2022-04-02  1:31               ` Jim Porter
2022-04-02 14:09                 ` Lars Ingebrigtsen
2022-04-02 15:52                   ` Sean Whitton

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).