1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Only set Eshell execution result metavariables when non-nil

This simplifies usage of 'eshell-close-handles' in several places and
makes it work more like the docstring indicated it would.

* lisp/eshell/esh-io.el (eshell-close-handles): Only store EXIT-CODE
and RESULT if they're non-nil.  Also, use 'dotimes' and 'dolist' to
simplify the implementation.

* lisp/eshell/em-alias.el (eshell-write-aliases-list):
* lisp/eshell/esh-cmd.el (eshell-rewrite-for-command)
(eshell-structure-basic-command): Adapt calls to
'eshell-close-handles'.

* test/lisp/eshell/eshell-tests.el (eshell-test/simple-command-result)
(eshell-test/lisp-command, eshell-test/lisp-command-with-quote)
(eshell-test/for-loop, eshell-test/for-name-loop)
(eshell-test/for-name-shadow-loop, eshell-test/lisp-command-args)
(eshell-test/subcommand, eshell-test/subcommand-args)
(eshell-test/subcommand-lisp): Move from here...

* test/lisp/eshell/esh-cmd-tests.el
(esh-cmd-test/simple-command-result, esh-cmd-test/lisp-command)
(esh-cmd-test/lisp-command-with-quote, esh-cmd-test/for-loop)
(esh-cmd-test/for-name-loop, esh-cmd-test/for-name-shadow-loop)
(esh-cmd-test/lisp-command-args, esh-cmd-test/subcommand)
(esh-cmd-test/subcommand-args, esh-cmd-test/subcommand-lisp): ... to
here.
(esh-cmd-test/and-operator, esh-cmd-test/or-operator)
(esh-cmd-test/for-loop-list, esh-cmd-test/for-loop-multiple-args)
(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):
New tests.

* doc/misc/eshell.texi (Invocation): Explain '&&' and '||'.
(for loop): Move from here...
(Control Flow): ... to here, and add documentation for other control
flow forms.
This commit is contained in:
Jim Porter 2022-08-06 13:37:28 -07:00
parent 2d4058b3ff
commit 30320d9420
6 changed files with 261 additions and 103 deletions

View file

@ -206,7 +206,7 @@ file named by `eshell-aliases-file'.")
(let ((eshell-current-handles
(eshell-create-handles eshell-aliases-file 'overwrite)))
(eshell/alias)
(eshell-close-handles 0))))
(eshell-close-handles 0 'nil))))
(defsubst eshell-lookup-alias (name)
"Check whether NAME is aliased. Return the alias if there is one."

View file

@ -541,9 +541,7 @@ implemented via rewriting, rather than as a function."
,(eshell-invokify-arg body t)))
(setcar for-items (cadr for-items))
(setcdr for-items (cddr for-items)))
(eshell-close-handles
eshell-last-command-status
(list 'quote eshell-last-command-result))))))
(eshell-close-handles)))))
(defun eshell-structure-basic-command (func names keyword test body
&optional else)
@ -574,9 +572,7 @@ function."
`(let ((eshell-command-body '(nil))
(eshell-test-body '(nil)))
(,func ,test ,body ,else)
(eshell-close-handles
eshell-last-command-status
(list 'quote eshell-last-command-result))))
(eshell-close-handles)))
(defun eshell-rewrite-while-command (terms)
"Rewrite a `while' command into its equivalent Eshell command form.

View file

@ -254,6 +254,30 @@ a nil value of mode defaults to `insert'."
(setq idx (1+ idx))))
handles)
(defun eshell-close-handles (&optional exit-code result handles)
"Close all of the current HANDLES, taking refcounts into account.
If HANDLES is nil, use `eshell-current-handles'.
EXIT-CODE is the process exit code (zero, if the command
completed successfully). If nil, then use the exit code already
set in `eshell-last-command-status'.
RESULT is the quoted value of the last command. If nil, then use
the value already set in `eshell-last-command-result'."
(when exit-code
(setq eshell-last-command-status exit-code))
(when result
(cl-assert (eq (car result) 'quote))
(setq eshell-last-command-result (cadr result)))
(let ((handles (or handles eshell-current-handles)))
(dotimes (idx eshell-number-of-handles)
(when-let ((handle (aref handles idx)))
(setcdr handle (1- (cdr handle)))
(when (= (cdr handle) 0)
(dolist (target (ensure-list (car (aref handles idx))))
(eshell-close-target target (= eshell-last-command-status 0)))
(setcar handle nil))))))
(defun eshell-close-target (target status)
"Close an output TARGET, passing STATUS as the result.
STATUS should be non-nil on successful termination of the output."
@ -305,32 +329,6 @@ STATUS should be non-nil on successful termination of the output."
((consp target)
(apply (car target) status (cdr target)))))
(defun eshell-close-handles (exit-code &optional result handles)
"Close all of the current handles, taking refcounts into account.
EXIT-CODE is the process exit code; mainly, it is zero, if the command
completed successfully. RESULT is the quoted value of the last
command. If nil, then the meta variables for keeping track of the
last execution result should not be changed."
(let ((idx 0))
(cl-assert (or (not result) (eq (car result) 'quote)))
(setq eshell-last-command-status exit-code
eshell-last-command-result (cadr result))
(while (< idx eshell-number-of-handles)
(let ((handles (or handles eshell-current-handles)))
(when (aref handles idx)
(setcdr (aref handles idx)
(1- (cdr (aref handles idx))))
(when (= (cdr (aref handles idx)) 0)
(let ((target (car (aref handles idx))))
(if (not (listp target))
(eshell-close-target target (= exit-code 0))
(while target
(eshell-close-target (car target) (= exit-code 0))
(setq target (cdr target)))))
(setcar (aref handles idx) nil))))
(setq idx (1+ idx)))
nil))
(defun eshell-kill-append (string)
"Call `kill-append' with STRING, if it is indeed a string."
(if (stringp string)