[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 9d4fa4ed4b 2/3: Allow using dollar expansions in Eshell condition
From: |
Jim Porter |
Subject: |
master 9d4fa4ed4b 2/3: Allow using dollar expansions in Eshell conditionals |
Date: |
Sat, 13 Aug 2022 01:13:05 -0400 (EDT) |
branch: master
commit 9d4fa4ed4b1f2b081e8ed14cbe16d9ec4b993988
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Jim Porter <jporterbugs@gmail.com>
Allow using dollar expansions in Eshell conditionals
* 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 | 43 +++++++++++++++-------------
lisp/eshell/esh-cmd.el | 9 +++---
test/lisp/eshell/esh-cmd-tests.el | 60 ++++++++++++++++++++++++++++++++-------
3 files changed, 79 insertions(+), 33 deletions(-)
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index d643cb5096..141c30ae9b 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -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
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 96272ca1a3..454a90e91d 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -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))))
diff --git a/test/lisp/eshell/esh-cmd-tests.el
b/test/lisp/eshell/esh-cmd-tests.el
index 1d5cd29d7c..b31159a1a8 100644
--- a/test/lisp/eshell/esh-cmd-tests.el
+++ b/test/lisp/eshell/esh-cmd-tests.el
@@ -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}"