mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Improve handling of Eshell "for" loops
This fixes some errors with more-complex string forms, and also allows iterating over sequences other than just lists. * lisp/eshell/esh-cmd.el (eshell-for-iterate): New function... (eshell-rewrite-for-command): ... use it. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop): Test multiple values. (esh-cmd-test/for-loop-string, esh-cmd-test/for-loop-vector): New tests. (esh-cmd-test/for-loop-mixed-args): Rename. * test/lisp/eshell/esh-proc-tests.el (esh-proc-test/sentinel/change-buffer): Make sure all the processes get cleaned up.
This commit is contained in:
parent
b3c82f939c
commit
08d5994b43
3 changed files with 49 additions and 35 deletions
|
|
@ -526,6 +526,20 @@ the second is ignored."
|
|||
(defvar eshell--local-vars nil
|
||||
"List of locally bound vars that should take precedence over env-vars.")
|
||||
|
||||
(iter-defun eshell-for-iterate (&rest args)
|
||||
"Iterate over the elements of each sequence in ARGS.
|
||||
If ARGS is not a sequence, treat it as a list of one element."
|
||||
(dolist (arg args)
|
||||
(cond
|
||||
((stringp arg)
|
||||
(iter-yield arg))
|
||||
((listp arg)
|
||||
(dolist (i arg) (iter-yield i)))
|
||||
((arrayp arg)
|
||||
(dotimes (i (length arg)) (iter-yield (aref arg i))))
|
||||
(t
|
||||
(iter-yield arg)))))
|
||||
|
||||
(defun eshell-rewrite-for-command (terms)
|
||||
"Rewrite a `for' command into its equivalent Eshell command form.
|
||||
Because the implementation of `for' relies upon conditional evaluation
|
||||
|
|
@ -533,23 +547,14 @@ of its argument (i.e., use of a Lisp special form), it must be
|
|||
implemented via rewriting, rather than as a function."
|
||||
(if (and (equal (car terms) "for")
|
||||
(equal (nth 2 terms) "in"))
|
||||
(let ((for-items (make-symbol "for-items"))
|
||||
(let ((iter-symbol (intern (nth 1 terms)))
|
||||
(body (car (last terms))))
|
||||
(setcdr (last terms 2) nil)
|
||||
`(let ((,for-items
|
||||
(append
|
||||
,@(mapcar
|
||||
(lambda (elem)
|
||||
(if (listp elem)
|
||||
(eshell-term-as-value elem)
|
||||
`(list ,elem)))
|
||||
(nthcdr 3 terms)))))
|
||||
(while ,for-items
|
||||
(let ((,(intern (cadr terms)) (car ,for-items))
|
||||
(eshell--local-vars (cons ',(intern (cadr terms))
|
||||
eshell--local-vars)))
|
||||
,body)
|
||||
(setq ,for-items (cdr ,for-items)))))))
|
||||
`(let ((eshell--local-vars (cons ',iter-symbol eshell--local-vars)))
|
||||
(iter-do (,iter-symbol (eshell-for-iterate
|
||||
,@(mapcar #'eshell-term-as-value
|
||||
(nthcdr 3 terms))))
|
||||
,body)))))
|
||||
|
||||
(defun eshell-structure-basic-command (func names keyword test &rest body)
|
||||
"With TERMS, KEYWORD, and two NAMES, structure a basic command.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue