]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow using dollar expansions in Eshell conditionals
authorJim Porter <jporterbugs@gmail.com>
Tue, 9 Aug 2022 04:24:27 +0000 (21:24 -0700)
committerJim Porter <jporterbugs@gmail.com>
Sat, 13 Aug 2022 05:07:13 +0000 (22:07 -0700)
* lisp/eshell/esh-cmd.el (eshell-structure-basic-command): Forms
beginning with 'eshell-escape-arg' are "data-wise".

* test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/while-loop)
(esh-cmd-test/until-loop, esh-cmd-test/if-statement)
(esh-cmd-test/if-else-statement, esh-cmd-test/unless-statement)
(esh-cmd-test/unless-else-statement): Use variable interpolation.
(esh-cmd-test/while-loop-ext-cmd, esh-cmd-test/until-loop-ext-cmd)
(esh-cmd-test/if-else-statement-ext-cmd)
(esh-cmd-test/unless-else-statement-ext-cmd): New tests, adapted from
the existing ones.

* doc/misc/eshell.texi (Control Flow): Update documentation for
conditionals (bug#57129).

doc/misc/eshell.texi
lisp/eshell/esh-cmd.el
test/lisp/eshell/esh-cmd-tests.el

index d643cb5096079257cb85a903b2f4fabbcf471074..141c30ae9b94d4a9575291a79c356564ca6abae8 100644 (file)
@@ -1020,27 +1020,32 @@ Because Eshell commands can not (easily) be combined with lisp forms,
 Eshell provides command-oriented control flow statements for
 convenience.
 
+Most of Eshell's control flow statements accept a @var{conditional}.
+This can take a few different forms.  If @var{conditional} is a dollar
+expansion, the condition is satisfied if the result is a
+non-@code{nil} value.  If @var{conditional} is a @samp{@{
+@var{subcommand} @}}, the condition is satisfied if the
+@var{subcommand}'s exit status is 0.
+
 @table @code
 
-@item if @{ @var{conditional} @} @{ @var{true-commands} @}
-@itemx if @{ @var{conditional} @} @{ @var{true-commands} @} @{ @var{false-commands} @}
-Evaluate @var{true-commands} if @var{conditional} returns success
-(i.e.@: its exit code is zero); otherwise, evaluate
-@var{false-commands}.
-
-@item unless @{ @var{conditional} @} @{ @var{false-commands} @}
-@itemx unless @{ @var{conditional} @} @{ @var{false-commands} @} @{ @var{true-commands} @}
-Evaluate @var{false-commands} if @var{conditional} returns failure
-(i.e.@: its exit code is non-zero); otherwise, evaluate
-@var{true-commands}.
-
-@item while @{ @var{conditional} @} @{ @var{commands} @}
-Repeatedly evaluate @var{commands} so long as @var{conditional}
-returns success.
-
-@item until @{ @var{conditional} @} @{ @var{commands} @}
-Repeatedly evaluate @var{commands} so long as @var{conditional}
-returns failure.
+@item if @var{conditional} @{ @var{true-commands} @}
+@itemx if @var{conditional} @{ @var{true-commands} @} @{ @var{false-commands} @}
+Evaluate @var{true-commands} if @var{conditional} is satisfied;
+otherwise, evaluate @var{false-commands}.
+
+@item unless @var{conditional} @{ @var{false-commands} @}
+@itemx unless @var{conditional} @{ @var{false-commands} @} @{ @var{true-commands} @}
+Evaluate @var{false-commands} if @var{conditional} is not satisfied;
+otherwise, evaluate @var{true-commands}.
+
+@item while @var{conditional} @{ @var{commands} @}
+Repeatedly evaluate @var{commands} so long as @var{conditional} is
+satisfied.
+
+@item until @var{conditional} @{ @var{commands} @}
+Repeatedly evaluate @var{commands} until @var{conditional} is
+satisfied.
 
 @item for @var{var} in @var{list}@dots{} @{ @var{commands} @}
 Iterate over each element of of @var{list}, storing the element in
index 96272ca1a3d59c5c6551064724b0460355a6f363..454a90e91d3016c5742183417547e8244da542c7 100644 (file)
@@ -549,10 +549,11 @@ implemented via rewriting, rather than as a function."
 The first of NAMES should be the positive form, and the second the
 negative.  It's not likely that users should ever need to call this
 function."
-  ;; If the test form begins with `eshell-convert', it means
-  ;; something data-wise will be returned, and we should let
-  ;; that determine the truth of the statement.
-  (unless (eq (car test) 'eshell-convert)
+  ;; If the test form begins with `eshell-convert' or
+  ;; `eshell-escape-arg', it means something data-wise will be
+  ;; returned, and we should let that determine the truth of the
+  ;; statement.
+  (unless (memq (car test) '(eshell-convert eshell-escape-arg))
     (setq test
          `(progn ,test
                   (eshell-exit-success-p))))
index 1d5cd29d7cfa8b3fa677d1ea06c45ad00874c720..b31159a1a8ff46601ac2ec123a16365b49379d11 100644 (file)
@@ -132,6 +132,15 @@ e.g. \"{(+ 1 2)} 3\" => 3"
 
 (ert-deftest esh-cmd-test/while-loop ()
   "Test invocation of a while loop."
+  (with-temp-eshell
+   (let ((eshell-test-value '(0 1 2)))
+     (eshell-command-result-p
+      (concat "while $eshell-test-value "
+              "{ setq eshell-test-value (cdr eshell-test-value) }")
+      "(1 2)\n(2)\n"))))
+
+(ert-deftest esh-cmd-test/while-loop-ext-cmd ()
+  "Test invocation of a while loop using an external command."
   (skip-unless (executable-find "["))
   (with-temp-eshell
    (let ((eshell-test-value 0))
@@ -142,6 +151,15 @@ e.g. \"{(+ 1 2)} 3\" => 3"
 
 (ert-deftest esh-cmd-test/until-loop ()
   "Test invocation of an until loop."
+  (with-temp-eshell
+   (let ((eshell-test-value nil))
+     (eshell-command-result-p
+      (concat "until $eshell-test-value "
+              "{ setq eshell-test-value t }")
+      "t\n"))))
+
+(ert-deftest esh-cmd-test/until-loop-ext-cmd ()
+  "Test invocation of an until loop using an external command."
   (skip-unless (executable-find "["))
   (with-temp-eshell
    (let ((eshell-test-value 0))
@@ -152,15 +170,26 @@ e.g. \"{(+ 1 2)} 3\" => 3"
 
 (ert-deftest esh-cmd-test/if-statement ()
   "Test invocation of an if statement."
-  (skip-unless (executable-find "["))
   (with-temp-eshell
-   (eshell-command-result-p "if {[ foo = foo ]} {echo yes}"
-                            "yes\n")
-   (eshell-command-result-p "if {[ foo = bar ]} {echo yes}"
-                            "\\`\\'")))
+   (let ((eshell-test-value t))
+     (eshell-command-result-p "if $eshell-test-value {echo yes}"
+                              "yes\n"))
+   (let ((eshell-test-value nil))
+     (eshell-command-result-p "if $eshell-test-value {echo yes}"
+                              "\\`\\'"))))
 
 (ert-deftest esh-cmd-test/if-else-statement ()
   "Test invocation of an if/else statement."
+  (with-temp-eshell
+   (let ((eshell-test-value t))
+     (eshell-command-result-p "if $eshell-test-value {echo yes} {echo no}"
+                              "yes\n"))
+   (let ((eshell-test-value nil))
+     (eshell-command-result-p "if $eshell-test-value {echo yes} {echo no}"
+                              "no\n"))))
+
+(ert-deftest esh-cmd-test/if-else-statement-ext-cmd ()
+  "Test invocation of an if/else statement using an external command."
   (skip-unless (executable-find "["))
   (with-temp-eshell
    (eshell-command-result-p "if {[ foo = foo ]} {echo yes} {echo no}"
@@ -170,15 +199,26 @@ e.g. \"{(+ 1 2)} 3\" => 3"
 
 (ert-deftest esh-cmd-test/unless-statement ()
   "Test invocation of an unless statement."
-  (skip-unless (executable-find "["))
   (with-temp-eshell
-   (eshell-command-result-p "unless {[ foo = foo ]} {echo no}"
-                            "\\`\\'")
-   (eshell-command-result-p "unless {[ foo = bar ]} {echo no}"
-                            "no\n")))
+   (let ((eshell-test-value t))
+     (eshell-command-result-p "unless $eshell-test-value {echo no}"
+                              "\\`\\'"))
+   (let ((eshell-test-value nil))
+     (eshell-command-result-p "unless $eshell-test-value {echo no}"
+                              "no\n"))))
 
 (ert-deftest esh-cmd-test/unless-else-statement ()
   "Test invocation of an unless/else statement."
+  (with-temp-eshell
+   (let ((eshell-test-value t))
+     (eshell-command-result-p "unless $eshell-test-value {echo no} {echo yes}"
+                              "yes\n"))
+   (let ((eshell-test-value nil))
+     (eshell-command-result-p "unless $eshell-test-value {echo no} {echo yes}"
+                              "no\n"))))
+
+(ert-deftest esh-cmd-test/unless-else-statement-ext-cmd ()
+  "Test invocation of an unless/else statement using an external command."
   (skip-unless (executable-find "["))
   (with-temp-eshell
    (eshell-command-result-p "unless {[ foo = foo ]} {echo no} {echo yes}"