From 6dbe3e96cf8420e64b05abc25ec3c8dc2478e0db Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 18 Nov 2011 09:49:42 -0500 Subject: [PATCH] * lisp/eshell/esh-cmd.el (eshell-do-eval): Handle `setq'. (eshell-rewrite-for-command): Remove workaround. (eshell-do-pipelines, eshell-do-pipelines-synchronously) (eshell-do-eval, eshell-exec-lisp): Avoid gratuitous setq. * lisp/eshell/esh-util.el (eshell-condition-case, eshell-for): Use declare. Fixes: debbugs:9907 --- lisp/ChangeLog | 6 +++ lisp/eshell/esh-cmd.el | 110 +++++++++++++++++++--------------------- lisp/eshell/esh-util.el | 7 ++- 3 files changed, 62 insertions(+), 61 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 03fa622031a..654e886a3a4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,11 @@ 2011-11-18 Stefan Monnier + * eshell/esh-cmd.el (eshell-do-eval): Handle `setq' (bug#9907). + (eshell-rewrite-for-command): Remove workaround. + (eshell-do-pipelines, eshell-do-pipelines-synchronously) + (eshell-do-eval, eshell-exec-lisp): Avoid gratuitous setq. + * eshell/esh-util.el (eshell-condition-case, eshell-for): Use declare. + * files-x.el (modify-file-local-variable): Obey commenting conventions. 2011-11-17 Glenn Morris diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index a7c92084bf9..7b90797eb43 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -480,25 +480,20 @@ implemented via rewriting, rather than as a function." (let ((body (car (last terms)))) (setcdr (last terms 2) nil) `(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)))))) + (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))) + (while (consp for-items) + (let ((,(intern (cadr terms)) (car for-items))) (eshell-protect ,(eshell-invokify-arg body t))) - (setcar for-items (cdar for-items))) + (setq for-items (cdr for-items))) (eshell-close-handles eshell-last-command-status (list 'quote eshell-last-command-result)))))) @@ -766,9 +761,8 @@ This macro calls itself recursively, with NOTFIRST non-nil." `(eshell-copy-handles (progn ,(when (cdr pipeline) - `(let (nextproc) - (setq nextproc - (eshell-do-pipelines (quote ,(cdr pipeline)) t)) + `(let ((nextproc + (eshell-do-pipelines (quote ,(cdr pipeline)) t))) (eshell-set-output-handle ,eshell-output-handle 'append nextproc) (eshell-set-output-handle ,eshell-error-handle @@ -796,10 +790,9 @@ This macro calls itself recursively, with NOTFIRST non-nil." Output of each command is passed as input to the next one in the pipeline. This is used on systems where `start-process' is not supported." (when (setq pipeline (cadr pipeline)) - `(let (result) + `(progn ,(when (cdr pipeline) - `(let (output-marker) - (setq output-marker ,(point-marker)) + `(let ((output-marker ,(point-marker))) (eshell-set-output-handle ,eshell-output-handle 'append output-marker) (eshell-set-output-handle ,eshell-error-handle @@ -811,21 +804,21 @@ This is used on systems where `start-process' is not supported." (when (memq (car head) eshell-deferrable-commands) (ignore (setcar head - (intern-soft - (concat (symbol-name (car head)) "*")))))) - ;; The last process in the pipe should get its handles + (intern-soft + (concat (symbol-name (car head)) "*")))))) + ;; The last process in the pipe should get its handles ;; redirected as we found them before running the pipe. ,(if (null (cdr pipeline)) `(progn (setq eshell-current-handles tail-handles) (setq eshell-in-pipeline-p nil))) - (setq result ,(car pipeline)) - ;; tailproc gets the result of the last successful process in - ;; the pipeline. - (setq tailproc (or result tailproc)) - ,(if (cdr pipeline) - `(eshell-do-pipelines-synchronously (quote ,(cdr pipeline)))) - result))) + (let ((result ,(car pipeline))) + ;; tailproc gets the result of the last successful process in + ;; the pipeline. + (setq tailproc (or result tailproc)) + ,(if (cdr pipeline) + `(eshell-do-pipelines-synchronously (quote ,(cdr pipeline)))) + result)))) (defalias 'eshell-process-identity 'identity) @@ -890,8 +883,7 @@ Returns a string comprising the output from the command." (eshell-print "errors\n")) (if eshell-debug-command (eshell-print "commands\n"))) - ((or (string= (car args) "-h") - (string= (car args) "--help")) + ((member (car args) '("-h" "--help")) (eshell-print "usage: eshell-debug [kinds] This command is used to aid in debugging problems related to Eshell @@ -1091,6 +1083,11 @@ be finished later after the completion of an asynchronous subprocess." (eshell-manipulate "handling special form" (setcar args `(eshell-do-eval ',(car args) ,synchronous-p)))) (eval form)) + ((eq (car form) 'setq) + (if (cddr args) (error "Unsupported form (setq X1 E1 X2 E2..)")) + (eshell-manipulate "evaluating arguments to setq" + (setcar (cdr args) (eshell-do-eval (cadr args) synchronous-p))) + (list 'quote (eval form))) (t (if (and args (not (memq (car form) '(run-hooks)))) (eshell-manipulate @@ -1127,11 +1124,12 @@ be finished later after the completion of an asynchronous subprocess." ;; Thus, aliases can even contain references to asynchronous ;; sub-commands, and things will still work out as they ;; should. - (let (result new-form) - (if (setq new-form - (catch 'eshell-replace-command - (ignore - (setq result (eval form))))) + (let* (result + (new-form + (catch 'eshell-replace-command + (ignore + (setq result (eval form)))))) + (if new-form (progn (eshell-manipulate "substituting replacement form" (setcar form (car new-form)) @@ -1247,25 +1245,23 @@ or an external command." PRINTER and ERRPRINT are functions to use for printing regular messages, and errors. FORM-P should be non-nil if FUNC-OR-FORM represent a lisp form; ARGS will be ignored in that case." - (let (result) - (eshell-condition-case err - (progn - (setq result - (save-current-buffer - (if form-p - (eval func-or-form) - (apply func-or-form args)))) - (and result (funcall printer result)) - result) - (error - (let ((msg (error-message-string err))) - (if (and (not form-p) - (string-match "^Wrong number of arguments" msg) - (fboundp 'eldoc-get-fnsym-args-string)) - (let ((func-doc (eldoc-get-fnsym-args-string func-or-form))) - (setq msg (format "usage: %s" func-doc)))) - (funcall errprint msg)) - nil)))) + (eshell-condition-case err + (let ((result + (save-current-buffer + (if form-p + (eval func-or-form) + (apply func-or-form args))))) + (and result (funcall printer result)) + result) + (error + (let ((msg (error-message-string err))) + (if (and (not form-p) + (string-match "^Wrong number of arguments" msg) + (fboundp 'eldoc-get-fnsym-args-string)) + (let ((func-doc (eldoc-get-fnsym-args-string func-or-form))) + (setq msg (format "usage: %s" func-doc)))) + (funcall errprint msg)) + nil))) (defsubst eshell-apply* (printer errprint func args) "Call FUNC, with ARGS, trapping errors and return them as output. diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 424d246a2b6..bbb453be711 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -140,14 +140,13 @@ function `string-to-number'." (defmacro eshell-condition-case (tag form &rest handlers) "If `eshell-handle-errors' is non-nil, this is `condition-case'. Otherwise, evaluates FORM with no error handling." + (declare (indent 2)) (if eshell-handle-errors `(condition-case ,tag ,form ,@handlers) form)) -(put 'eshell-condition-case 'lisp-indent-function 2) - (defun eshell-find-delimiter (open close &optional bound reverse-p backslash-p) "From point, find the CLOSE delimiter corresponding to OPEN. @@ -275,14 +274,14 @@ Prepend remote identification of `default-directory', if any." text)) (defmacro eshell-for (for-var for-list &rest forms) - "Iterate through a list" + "Iterate through a list." + (declare (indent 2)) `(let ((list-iter ,for-list)) (while list-iter (let ((,for-var (car list-iter))) ,@forms) (setq list-iter (cdr list-iter))))) -(put 'eshell-for 'lisp-indent-function 2) (make-obsolete 'eshell-for 'dolist "24.1") -- 2.39.2