Mercurial > emacs
diff lisp/eshell/esh-cmd.el @ 33020:e21feeab77fb
See ChangeLog
| author | John Wiegley <johnw@newartisans.com> |
|---|---|
| date | Sun, 29 Oct 2000 05:18:48 +0000 |
| parents | 8e57189d61b4 |
| children | f4b209194d8c |
line wrap: on
line diff
--- a/lisp/eshell/esh-cmd.el Sun Oct 29 04:56:45 2000 +0000 +++ b/lisp/eshell/esh-cmd.el Sun Oct 29 05:18:48 2000 +0000 @@ -203,6 +203,21 @@ :type 'hook :group 'eshell-cmd) +(defcustom eshell-complex-commands nil + "*A list of commands names or functions, that determine complexity. +That is, if a command is defined by a function named eshell/NAME, +and NAME is part of this list, it is invoked as a complex command. +Complex commands are always correct, but run much slower. If a +command works fine without being part of this list, then it doesn't +need to be. + +If an entry is a function, it will be called with the name, and should +return non-nil if the command is complex." + :type '(repeat :tag "Commands" + (choice (string :tag "Name") + (function :tag "Predicate"))) + :group 'eshell-cmd) + ;;; Code: (require 'esh-util) @@ -518,8 +533,8 @@ (list 'car (list 'symbol-value (list 'quote 'for-items))))) - (list 'eshell-copy-handles - (eshell-invokify-arg body t))) + (list 'eshell-protect + (eshell-invokify-arg body t))) (list 'setcar 'for-items (list 'cadr (list 'symbol-value @@ -583,7 +598,7 @@ (eshell-structure-basic-command 'while '("while" "until") (car terms) (eshell-invokify-arg (cadr terms) nil t) - (list 'eshell-copy-handles + (list 'eshell-protect (eshell-invokify-arg (car (last terms)) t))))) (defun eshell-rewrite-if-command (terms) @@ -596,13 +611,15 @@ (eshell-structure-basic-command 'if '("if" "unless") (car terms) (eshell-invokify-arg (cadr terms) nil t) - (eshell-invokify-arg - (if (= (length terms) 5) - (car (last terms 3)) - (car (last terms))) t) - (eshell-invokify-arg - (if (= (length terms) 5) - (car (last terms))) t)))) + (list 'eshell-protect + (eshell-invokify-arg + (if (= (length terms) 5) + (car (last terms 3)) + (car (last terms))) t)) + (if (= (length terms) 5) + (list 'eshell-protect + (eshell-invokify-arg + (car (last terms)))) t)))) (defun eshell-exit-success-p () "Return non-nil if the last command was \"successful\". @@ -651,8 +668,8 @@ (assert (car sep-terms)) (setq final (eshell-structure-basic-command 'if (string= (car sep-terms) "&&") "if" - (list 'eshell-commands (car results)) - final + (list 'eshell-protect (car results)) + (list 'eshell-protect final) nil t) results (cdr results) sep-terms (cdr sep-terms))) @@ -690,8 +707,8 @@ (list 'eshell-lisp-command (list 'quote obj))) (ignore (goto-char here)))))) -(defun eshell-separate-commands - (terms separator &optional reversed last-terms-sym) +(defun eshell-separate-commands (terms separator &optional + reversed last-terms-sym) "Separate TERMS using SEPARATOR. If REVERSED is non-nil, the list of separated term groups will be returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value @@ -772,21 +789,6 @@ (eshell-errorn (error-message-string err)) (eshell-close-handles 1))))) -;; (defun eshell-copy-or-protect-handles () -;; (if (eshell-processp (car (aref eshell-current-handles -;; eshell-output-handle))) -;; (eshell-protect-handles eshell-current-handles) -;; (eshell-create-handles -;; (car (aref eshell-current-handles -;; eshell-output-handle)) nil -;; (car (aref eshell-current-handles -;; eshell-error-handle)) nil))) - -;; (defmacro eshell-copy-handles (object) -;; "Duplicate current I/O handles, so OBJECT works with its own copy." -;; `(let ((eshell-current-handles (eshell-copy-or-protect-handles))) -;; ,object)) - (defmacro eshell-copy-handles (object) "Duplicate current I/O handles, so OBJECT works with its own copy." `(let ((eshell-current-handles @@ -965,6 +967,22 @@ (if subform (concat "\n\n" (eshell-stringify subform)) "")))))) +(defun eshell-invoke-directly (command input) + (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)) + (setq name (cadr (cadr base)))) + (and name (stringp name) + (not (member name eshell-complex-commands)) + (catch 'simple + (progn + (eshell-for pred eshell-complex-commands + (if (and (functionp pred) + (funcall pred name)) + (throw 'simple nil))) + t)) + (fboundp (intern-soft (concat "eshell/" name)))))) + (defun eshell-eval-command (command &optional input) "Evaluate the given COMMAND iteratively." (if eshell-current-command @@ -1163,29 +1181,29 @@ ((eq (car form) 'prog1) (cadr form)) (t + ;; If a command desire to replace its execution form with + ;; another command form, all it needs to do is throw the new + ;; form using the exception tag `eshell-replace-command'. + ;; For example, let's say that the form currently being + ;; eval'd is: + ;; + ;; (eshell-named-command "hello") + ;; + ;; Now, let's assume the 'hello' command is an Eshell alias, + ;; the definition of which yields the command: + ;; + ;; (eshell-named-command "echo" (list "Hello" "world")) + ;; + ;; What the alias code would like to do is simply substitute + ;; the alias form for the original form. To accomplish + ;; this, all it needs to do is to throw the substitution + ;; form with the `eshell-replace-command' tag, and the form + ;; will be replaced within the current command, and + ;; execution will then resume (iteratively) as before. + ;; Thus, aliases can even contain references to asynchronous + ;; sub-commands, and things will still work out as they + ;; should. (let (result new-form) - ;; If a command desire to replace its execution form with - ;; another command form, all it needs to do is throw the - ;; new form using the exception tag - ;; `eshell-replace-command'. For example, let's say that - ;; the form currently being eval'd is: - ;; - ;; (eshell-named-command \"hello\") - ;; - ;; Now, let's assume the 'hello' command is an Eshell - ;; alias, the definition of which yields the command: - ;; - ;; (eshell-named-command \"echo\" (list \"Hello\" \"world\")) - ;; - ;; What the alias code would like to do is simply - ;; substitute the alias form for the original form. To - ;; accomplish this, all it needs to do is to throw the - ;; substitution form with the `eshell-replace-command' - ;; tag, and the form will be replaced within the current - ;; command, and execution will then resume (iteratively) - ;; as before. Thus, aliases can even contain references - ;; to asynchronous sub-commands, and things will still - ;; work out as they should. (if (setq new-form (catch 'eshell-replace-command (ignore
