* lisp/eshell/esh-cmd.el (eshell-post-rewrite-command-function): New var.
[bpt/emacs.git] / lisp / eshell / esh-cmd.el
index 75e0e1d..87c72d2 100644 (file)
@@ -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))