aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/eshell/esh-cmd.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/eshell/esh-cmd.el')
-rw-r--r--lisp/eshell/esh-cmd.el63
1 files changed, 49 insertions, 14 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index a2d7d9431a9..04d65df4f33 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -107,6 +107,7 @@
107(require 'esh-module) 107(require 'esh-module)
108(require 'esh-io) 108(require 'esh-io)
109(require 'esh-ext) 109(require 'esh-ext)
110(require 'generator)
110 111
111(eval-when-compile 112(eval-when-compile
112 (require 'cl-lib) 113 (require 'cl-lib)
@@ -903,21 +904,55 @@ at the moment are:
903 "Completion for the `debug' command." 904 "Completion for the `debug' command."
904 (while (pcomplete-here '("errors" "commands")))) 905 (while (pcomplete-here '("errors" "commands"))))
905 906
907(iter-defun eshell--find-subcommands (haystack)
908 "Recursively search for subcommand forms in HAYSTACK.
909This yields the SUBCOMMANDs when found in forms like
910\"(eshell-as-subcommand SUBCOMMAND)\"."
911 (dolist (elem haystack)
912 (cond
913 ((eq (car-safe elem) 'eshell-as-subcommand)
914 (iter-yield (cdr elem)))
915 ((listp elem)
916 (iter-yield-from (eshell--find-subcommands elem))))))
917
918(defun eshell--invoke-command-directly (command)
919 "Determine whether the given COMMAND can be invoked directly.
920COMMAND should be a non-top-level Eshell command in parsed form.
921
922A command can be invoked directly if all of the following are true:
923
924* The command is of the form
925 \"(eshell-trap-errors (eshell-named-command NAME ARGS))\",
926 where ARGS is optional.
927
928* NAME is a string referring to an alias function and isn't a
929 complex command (see `eshell-complex-commands').
930
931* Any subcommands in ARGS can also be invoked directly."
932 (when (and (eq (car command) 'eshell-trap-errors)
933 (eq (car (cadr command)) 'eshell-named-command))
934 (let ((name (cadr (cadr command)))
935 (args (cdr-safe (nth 2 (cadr command)))))
936 (and name (stringp name)
937 (not (member name eshell-complex-commands))
938 (catch 'simple
939 (dolist (pred eshell-complex-commands t)
940 (when (and (functionp pred)
941 (funcall pred name))
942 (throw 'simple nil))))
943 (eshell-find-alias-function name)
944 (catch 'indirect-subcommand
945 (iter-do (subcommand (eshell--find-subcommands args))
946 (unless (eshell--invoke-command-directly subcommand)
947 (throw 'indirect-subcommand nil)))
948 t)))))
949
906(defun eshell-invoke-directly (command) 950(defun eshell-invoke-directly (command)
907 (let ((base (cadr (nth 2 (nth 2 (cadr command))))) name) 951 "Determine whether the given COMMAND can be invoked directly.
908 (if (and (eq (car base) 'eshell-trap-errors) 952COMMAND should be a top-level Eshell command in parsed form, as
909 (eq (car (cadr base)) 'eshell-named-command)) 953produced by `eshell-parse-command'."
910 (setq name (cadr (cadr base)))) 954 (let ((base (cadr (nth 2 (nth 2 (cadr command))))))
911 (and name (stringp name) 955 (eshell--invoke-command-directly base)))
912 (not (member name eshell-complex-commands))
913 (catch 'simple
914 (progn
915 (dolist (pred eshell-complex-commands)
916 (if (and (functionp pred)
917 (funcall pred name))
918 (throw 'simple nil)))
919 t))
920 (eshell-find-alias-function name))))
921 956
922(defun eshell-eval-command (command &optional input) 957(defun eshell-eval-command (command &optional input)
923 "Evaluate the given COMMAND iteratively." 958 "Evaluate the given COMMAND iteratively."