- (list
- 'let (list (list 'for-items
- (append
- (list 'append)
- (mapcar
- (function
- (lambda (elem)
- (if (listp elem)
- elem
- (list 'list elem))))
- (cdr (cddr terms)))))
- (list 'eshell-command-body
- (list 'quote (list nil)))
- (list 'eshell-test-body
- (list 'quote (list nil))))
- (list
- 'progn
- (list
- 'while (list 'car (list 'symbol-value
- (list 'quote 'for-items)))
- (list
- 'progn
- (list 'let
- (list (list (intern (cadr terms))
- (list 'car
- (list 'symbol-value
- (list 'quote 'for-items)))))
- (list 'eshell-protect
- (eshell-invokify-arg body t)))
- (list 'setcar 'for-items
- (list 'cadr
- (list 'symbol-value
- (list 'quote 'for-items))))
- (list 'setcdr 'for-items
- (list 'cddr
- (list 'symbol-value
- (list 'quote 'for-items))))))
- (list 'eshell-close-handles
- 'eshell-last-command-status
- (list 'list (quote 'quote)
- 'eshell-last-command-result)))))))
+ `(let ((for-items
+ ;; Apparently, eshell-do-eval only works for immutable
+ ;; let-bindings, i.e. we cannot use `setq' on `for-items'.
+ ;; Instead we store the list in the car of a cons-cell (which
+ ;; acts as a ref-cell) so we can setcar instead of setq.
+ (list
+ (append
+ ,@(mapcar
+ (lambda (elem)
+ (if (listp elem)
+ elem
+ `(list ,elem)))
+ (cdr (cddr terms))))))
+ (eshell-command-body '(nil))
+ (eshell-test-body '(nil)))
+ (while (consp (car for-items))
+ (let ((,(intern (cadr terms)) (caar for-items)))
+ (eshell-protect
+ ,(eshell-invokify-arg body t)))
+ (setcar for-items (cdar for-items)))
+ (eshell-close-handles
+ eshell-last-command-status
+ (list 'quote eshell-last-command-result))))))