diff options
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/em-basic.el | 37 | ||||
| -rw-r--r-- | lisp/eshell/em-script.el | 18 | ||||
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 63 | ||||
| -rw-r--r-- | lisp/eshell/esh-opt.el | 12 |
4 files changed, 85 insertions, 45 deletions
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el index 27b343ad398..ba868cee59e 100644 --- a/lisp/eshell/em-basic.el +++ b/lisp/eshell/em-basic.el | |||
| @@ -82,7 +82,11 @@ equivalent of `echo' can always be achieved by using `identity'." | |||
| 82 | It returns a formatted value that should be passed to `eshell-print' | 82 | It returns a formatted value that should be passed to `eshell-print' |
| 83 | or `eshell-printn' for display." | 83 | or `eshell-printn' for display." |
| 84 | (if eshell-plain-echo-behavior | 84 | (if eshell-plain-echo-behavior |
| 85 | (concat (apply 'eshell-flatten-and-stringify args) "\n") | 85 | (progn |
| 86 | ;; If the output does not end in a newline, do not emit one. | ||
| 87 | (setq eshell-ensure-newline-p nil) | ||
| 88 | (concat (apply #'eshell-flatten-and-stringify args) | ||
| 89 | (when output-newline "\n"))) | ||
| 86 | (let ((value | 90 | (let ((value |
| 87 | (cond | 91 | (cond |
| 88 | ((= (length args) 0) "") | 92 | ((= (length args) 0) "") |
| @@ -109,18 +113,33 @@ or `eshell-printn' for display." | |||
| 109 | "Implementation of `echo'. See `eshell-plain-echo-behavior'." | 113 | "Implementation of `echo'. See `eshell-plain-echo-behavior'." |
| 110 | (eshell-eval-using-options | 114 | (eshell-eval-using-options |
| 111 | "echo" args | 115 | "echo" args |
| 112 | '((?n nil nil output-newline "terminate with a newline") | 116 | '((?n nil (nil) output-newline |
| 113 | (?h "help" nil nil "output this help screen") | 117 | "do not output the trailing newline") |
| 118 | (?N nil (t) output-newline | ||
| 119 | "terminate with a newline") | ||
| 120 | (?E nil nil _disable-escapes | ||
| 121 | "don't interpret backslash escapes (default)") | ||
| 122 | (?h "help" nil nil | ||
| 123 | "output this help screen") | ||
| 114 | :preserve-args | 124 | :preserve-args |
| 115 | :usage "[-n] [object]") | 125 | :usage "[OPTION]... [OBJECT]...") |
| 116 | (eshell-echo args output-newline))) | 126 | (if eshell-plain-echo-behavior |
| 127 | (eshell-echo args (if output-newline (car output-newline) t)) | ||
| 128 | ;; In Emacs 28.1 and earlier, "-n" was used to add a newline to | ||
| 129 | ;; non-plain echo in Eshell. This caused confusion due to "-n" | ||
| 130 | ;; generally having the opposite meaning for echo. Retain this | ||
| 131 | ;; compatibility for the time being. For more info, see | ||
| 132 | ;; bug#27361. | ||
| 133 | (when (equal output-newline '(nil)) | ||
| 134 | (display-warning | ||
| 135 | :warning "To terminate with a newline, you should use -N instead.")) | ||
| 136 | (eshell-echo args output-newline)))) | ||
| 117 | 137 | ||
| 118 | (defun eshell/printnl (&rest args) | 138 | (defun eshell/printnl (&rest args) |
| 119 | "Print out each of the arguments, separated by newlines." | 139 | "Print out each of the arguments as strings, separated by newlines." |
| 120 | (let ((elems (flatten-tree args))) | 140 | (let ((elems (flatten-tree args))) |
| 121 | (while elems | 141 | (dolist (elem elems) |
| 122 | (eshell-printn (eshell-echo (list (car elems)))) | 142 | (eshell-printn (eshell-stringify elem))))) |
| 123 | (setq elems (cdr elems))))) | ||
| 124 | 143 | ||
| 125 | (defun eshell/listify (&rest args) | 144 | (defun eshell/listify (&rest args) |
| 126 | "Return the argument(s) as a single list." | 145 | "Return the argument(s) as a single list." |
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el index e8459513f39..e0bcd8b099f 100644 --- a/lisp/eshell/em-script.el +++ b/lisp/eshell/em-script.el | |||
| @@ -113,27 +113,13 @@ Comments begin with `#'." | |||
| 113 | 113 | ||
| 114 | (defun eshell/source (&rest args) | 114 | (defun eshell/source (&rest args) |
| 115 | "Source a file in a subshell environment." | 115 | "Source a file in a subshell environment." |
| 116 | (eshell-eval-using-options | 116 | (eshell-source-file (car args) (cdr args) t)) |
| 117 | "source" args | ||
| 118 | '((?h "help" nil nil "show this usage screen") | ||
| 119 | :show-usage | ||
| 120 | :usage "FILE [ARGS] | ||
| 121 | Invoke the Eshell commands in FILE in a subshell, binding ARGS to $1, | ||
| 122 | $2, etc.") | ||
| 123 | (eshell-source-file (car args) (cdr args) t))) | ||
| 124 | 117 | ||
| 125 | (put 'eshell/source 'eshell-no-numeric-conversions t) | 118 | (put 'eshell/source 'eshell-no-numeric-conversions t) |
| 126 | 119 | ||
| 127 | (defun eshell/. (&rest args) | 120 | (defun eshell/. (&rest args) |
| 128 | "Source a file in the current environment." | 121 | "Source a file in the current environment." |
| 129 | (eshell-eval-using-options | 122 | (eshell-source-file (car args) (cdr args))) |
| 130 | "." args | ||
| 131 | '((?h "help" nil nil "show this usage screen") | ||
| 132 | :show-usage | ||
| 133 | :usage "FILE [ARGS] | ||
| 134 | Invoke the Eshell commands in FILE within the current shell | ||
| 135 | environment, binding ARGS to $1, $2, etc.") | ||
| 136 | (eshell-source-file (car args) (cdr args)))) | ||
| 137 | 123 | ||
| 138 | (put 'eshell/. 'eshell-no-numeric-conversions t) | 124 | (put 'eshell/. 'eshell-no-numeric-conversions t) |
| 139 | 125 | ||
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. | ||
| 909 | This 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. | ||
| 920 | COMMAND should be a non-top-level Eshell command in parsed form. | ||
| 921 | |||
| 922 | A 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) | 952 | COMMAND should be a top-level Eshell command in parsed form, as |
| 909 | (eq (car (cadr base)) 'eshell-named-command)) | 953 | produced 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." |
diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index bba1c4ad25d..c802bee3af5 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el | |||
| @@ -257,12 +257,12 @@ triggered to say that the switch is unrecognized." | |||
| 257 | remaining | 257 | remaining |
| 258 | (let ((extcmd (memq ':external options))) | 258 | (let ((extcmd (memq ':external options))) |
| 259 | (when extcmd | 259 | (when extcmd |
| 260 | (setq extcmd (eshell-search-path (cadr extcmd))) | 260 | (setq extcmd (eshell-search-path (cadr extcmd)))) |
| 261 | (if extcmd | 261 | (if extcmd |
| 262 | (throw 'eshell-ext-command extcmd) | 262 | (throw 'eshell-ext-command extcmd) |
| 263 | (error (if (characterp (car switch)) "%s: unrecognized option -%c" | 263 | (error (if (characterp (car switch)) "%s: unrecognized option -%c" |
| 264 | "%s: unrecognized option --%s") | 264 | "%s: unrecognized option --%s") |
| 265 | name (car switch)))))))) | 265 | name (car switch))))))) |
| 266 | 266 | ||
| 267 | (defun eshell--process-args (name args options) | 267 | (defun eshell--process-args (name args options) |
| 268 | "Process the given ARGS using OPTIONS." | 268 | "Process the given ARGS using OPTIONS." |