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
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))))
(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))
(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))
(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}"
(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}"