From: Stefan Monnier Date: Tue, 17 Sep 2013 15:19:12 +0000 (-0400) Subject: * lisp/eshell/esh-cmd.el (eshell-post-rewrite-command-function): New var. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~1579 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e8b66a6a262b12405e2f29f3693a1f2d57061e2b;p=emacs.git * lisp/eshell/esh-cmd.el (eshell-post-rewrite-command-function): New var. (eshell-post-rewrite-command-hook): Make obsolete. (eshell-parse-command): Simplify. (eshell-structure-basic-command): Remove unused arg `vocal-test'. (eshell--cmd): Declare. (eshell-parse-pipeline): Remove unused var `final-p'. Pass a dynvar to eshell-post-rewrite-command-hook. Implement the new eshell-post-rewrite-command-function. (eshell-invoke-directly): Remove unused arg `input'. * lisp/eshell/esh-io.el (eshell-io-initialize): Use eshell-post-rewrite-command-function. (eshell--apply-redirections): Rename from eshell-apply-redirections; adjust to new calling convention. (eshell-create-handles): Rename args to avoid clashing with dynvar `standard-output'. Fixes: debbugs:15399 --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b8d62097251..059bb0218f3 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,21 @@ +2013-09-17 Stefan Monnier + + * eshell/esh-cmd.el (eshell-post-rewrite-command-function): New var. + (eshell-post-rewrite-command-hook): Make obsolete. + (eshell-parse-command): Simplify. + (eshell-structure-basic-command): Remove unused arg `vocal-test'. + (eshell--cmd): Declare. + (eshell-parse-pipeline): Remove unused var `final-p'. + Pass a dynvar to eshell-post-rewrite-command-hook. + Implement the new eshell-post-rewrite-command-function. + (eshell-invoke-directly): Remove unused arg `input'. + * eshell/esh-io.el (eshell-io-initialize): + Use eshell-post-rewrite-command-function (bug#15399). + (eshell--apply-redirections): Rename from eshell-apply-redirections; + adjust to new calling convention. + (eshell-create-handles): Rename args to avoid clashing with dynvar + `standard-output'. + 2013-09-17 Glenn Morris * simple.el (messages-buffer-mode): New major mode. diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 75e0e1d27c8..87c72d2caf5 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -205,12 +205,16 @@ forms or strings)." :type 'hook :group 'eshell-cmd) -(defcustom eshell-post-rewrite-command-hook nil +(defvar eshell-post-rewrite-command-function #'identity + "Function run after command rewriting is finished. +Takes the (rewritten) command, modifies it as it sees fit and returns +the new result to use instead.") +(defvar eshell-post-rewrite-command-hook nil "A hook run after command rewriting is finished. Each function is passed the symbol containing the rewritten command, -which may be modified directly. Any return value is ignored." - :type 'hook - :group 'eshell-cmd) +which may be modified directly. Any return value is ignored.") +(make-obsolete-variable 'eshell-post-rewrite-command-hook + 'eshell-post-rewrite-command-function "24.4") (defcustom eshell-complex-commands '("ls") "A list of commands names or functions, that determine complexity. @@ -335,10 +339,10 @@ otherwise t.") ;; Command parsing -(defun eshell-parse-command (command &optional args top-level) +(defun eshell-parse-command (command &optional args toplevel) "Parse the COMMAND, adding ARGS if given. COMMAND can either be a string, or a cons cell demarcating a buffer -region. TOP-LEVEL, if non-nil, means that the outermost command (the +region. TOPLEVEL, if non-nil, means that the outermost command (the user's input command) is being parsed, and that pre and post command hooks should be run before and after the command." (let* (sep-terms @@ -363,7 +367,7 @@ hooks should be run before and after the command." (setq cmd (if (or (not (car sep-terms)) (string= (car sep-terms) ";")) - (eshell-parse-pipeline cmd (not (car sep-terms))) + (eshell-parse-pipeline cmd) `(eshell-do-subjob (list ,(eshell-parse-pipeline cmd))))) (setq sep-terms (cdr sep-terms)) @@ -376,17 +380,12 @@ hooks should be run before and after the command." (if (cdr cmd) (setcar cmd `(eshell-commands ,(car cmd)))) (setq cmd (cdr cmd)))) - (setq commands - `(progn - ,@(if top-level - '((run-hooks 'eshell-pre-command-hook))) - ,@(if (not top-level) - commands - `((catch 'top-level (progn ,@commands)) - (run-hooks 'eshell-post-command-hook))))) - (if top-level - `(eshell-commands ,commands) - commands))) + (if toplevel + `(eshell-commands (progn + (run-hooks 'eshell-pre-command-hook) + (catch 'top-level (progn ,@commands)) + (run-hooks 'eshell-post-command-hook))) + (macroexp-progn commands)))) (defun eshell-debug-command (tag subform) "Output a debugging message to '*eshell last cmd*'." @@ -509,14 +508,11 @@ implemented via rewriting, rather than as a function." (list 'quote eshell-last-command-result)))))) (defun eshell-structure-basic-command (func names keyword test body - &optional else vocal-test) + &optional else) "With TERMS, KEYWORD, and two NAMES, structure a basic command. 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 VOCAL-TEST is non-nil, it means output from the test should be -shown, as well as output from the body." +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. @@ -586,7 +582,9 @@ For an external command, it means an exit code of 0." eshell-last-command-result (= eshell-last-command-status 0))) -(defun eshell-parse-pipeline (terms &optional final-p) +(defvar eshell--cmd) + +(defun eshell-parse-pipeline (terms) "Parse a pipeline from TERMS, return the appropriate Lisp forms." (let* (sep-terms (bigpieces (eshell-separate-commands terms "\\(&&\\|||\\)" @@ -603,8 +601,11 @@ For an external command, it means an exit code of 0." (run-hook-with-args 'eshell-pre-rewrite-command-hook cmd) (setq cmd (run-hook-with-args-until-success 'eshell-rewrite-command-hook cmd)) - (run-hook-with-args 'eshell-post-rewrite-command-hook 'cmd) - (setcar p cmd)) + (let ((eshell--cmd cmd)) + (run-hook-with-args 'eshell-post-rewrite-command-hook + 'eshell--cmd) + (setq cmd eshell--cmd)) + (setcar p (funcall eshell-post-rewrite-command-function cmd))) (setq p (cdr p))) (nconc results (list @@ -625,8 +626,7 @@ For an external command, it means an exit code of 0." (setq final (eshell-structure-basic-command 'if (string= (car sep-terms) "&&") "if" `(eshell-protect ,(car results)) - `(eshell-protect ,final) - nil t) + `(eshell-protect ,final)) results (cdr results) sep-terms (cdr sep-terms))) final)) @@ -916,7 +916,7 @@ at the moment are: "Completion for the `debug' command." (while (pcomplete-here '("errors" "commands")))) -(defun eshell-invoke-directly (command input) +(defun eshell-invoke-directly (command) (let ((base (cadr (nth 2 (nth 2 (cadr command))))) name) (if (and (eq (car base) 'eshell-trap-errors) (eq (car (cadr base)) 'eshell-named-command)) diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index f620890ee6b..c4c0bd43790 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -179,8 +179,8 @@ not be added to this variable." (make-local-variable 'eshell-current-redirections) (add-hook 'eshell-pre-rewrite-command-hook 'eshell-strip-redirections nil t) - (add-hook 'eshell-post-rewrite-command-hook - 'eshell-apply-redirections nil t)) + (add-function :filter-return (local 'eshell-post-rewrite-command-function) + #'eshell--apply-redirections)) (defun eshell-parse-redirection () "Parse an output redirection, such as '2>'." @@ -223,28 +223,27 @@ not be added to this variable." (setq eshell-current-redirections (cdr eshell-current-redirections)))) -(defun eshell-apply-redirections (cmdsym) +(defun eshell--apply-redirections (cmd) "Apply any redirection which were specified for COMMAND." (if eshell-current-redirections - (set cmdsym - (append (list 'progn) - eshell-current-redirections - (list (symbol-value cmdsym)))))) + `(progn + ,@eshell-current-redirections + ,cmd) + cmd)) (defun eshell-create-handles - (standard-output output-mode &optional standard-error error-mode) + (stdout output-mode &optional stderr error-mode) "Create a new set of file handles for a command. The default location for standard output and standard error will go to -STANDARD-OUTPUT and STANDARD-ERROR, respectively. +STDOUT and STDERR, respectively. OUTPUT-MODE and ERROR-MODE are either `overwrite', `append' or `insert'; a nil value of mode defaults to `insert'." (let ((handles (make-vector eshell-number-of-handles nil)) - (output-target (eshell-get-target standard-output output-mode)) - (error-target (eshell-get-target standard-error error-mode))) + (output-target (eshell-get-target stdout output-mode)) + (error-target (eshell-get-target stderr error-mode))) (aset handles eshell-output-handle (cons output-target 1)) - (if standard-error - (aset handles eshell-error-handle (cons error-target 1)) - (aset handles eshell-error-handle (cons output-target 1))) + (aset handles eshell-error-handle + (cons (if stderr error-target output-target) 1)) handles)) (defun eshell-protect-handles (handles) diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 1a80e3894e1..e770c773920 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -671,7 +671,7 @@ newline." (run-hooks 'eshell-input-filter-functions) (and (catch 'eshell-terminal (ignore - (if (eshell-invoke-directly cmd input) + (if (eshell-invoke-directly cmd) (eval cmd) (eshell-eval-command cmd input)))) (eshell-life-is-too-much)))))