diff options
| author | Jim Porter | 2022-01-21 10:32:00 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-01-21 10:32:00 +0100 |
| commit | 587edc46dfc0aa035c49a5c97ff36472e2c4dbfd (patch) | |
| tree | 6fbaf9ec3124706ea25aab0421bbe1c3393cfaa1 /lisp/eshell | |
| parent | a6ad584ac27dcc6bbe2476face53a3165f99366d (diff) | |
| download | emacs-587edc46dfc0aa035c49a5c97ff36472e2c4dbfd.tar.gz emacs-587edc46dfc0aa035c49a5c97ff36472e2c4dbfd.zip | |
Further improve determination of when commands can be invoked directly
This covers the case when a subcommand is to be invoked in more places
than before, for example when a subcommand is concatenated in an
argument.
* lisp/eshell/esh-cmd.el (eshell--find-subcommands): New fuction.
(eshell--invoke-command-directly): Use 'eshell-find-subcommands'.
* test/lisp/eshell/eshell-tests.el
(eshell-test/interp-cmd-external-concat): New test (bug#30725).
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 25e3a5a2054..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,6 +904,17 @@ 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 | |||
| 906 | (defun eshell--invoke-command-directly (command) | 918 | (defun eshell--invoke-command-directly (command) |
| 907 | "Determine whether the given COMMAND can be invoked directly. | 919 | "Determine whether the given COMMAND can be invoked directly. |
| 908 | COMMAND should be a non-top-level Eshell command in parsed form. | 920 | COMMAND should be a non-top-level Eshell command in parsed form. |
| @@ -916,8 +928,7 @@ A command can be invoked directly if all of the following are true: | |||
| 916 | * NAME is a string referring to an alias function and isn't a | 928 | * NAME is a string referring to an alias function and isn't a |
| 917 | complex command (see `eshell-complex-commands'). | 929 | complex command (see `eshell-complex-commands'). |
| 918 | 930 | ||
| 919 | * Any argument in ARGS that calls a subcommand can also be | 931 | * Any subcommands in ARGS can also be invoked directly." |
| 920 | invoked directly." | ||
| 921 | (when (and (eq (car command) 'eshell-trap-errors) | 932 | (when (and (eq (car command) 'eshell-trap-errors) |
| 922 | (eq (car (cadr command)) 'eshell-named-command)) | 933 | (eq (car (cadr command)) 'eshell-named-command)) |
| 923 | (let ((name (cadr (cadr command))) | 934 | (let ((name (cadr (cadr command))) |
| @@ -931,15 +942,10 @@ A command can be invoked directly if all of the following are true: | |||
| 931 | (throw 'simple nil)))) | 942 | (throw 'simple nil)))) |
| 932 | (eshell-find-alias-function name) | 943 | (eshell-find-alias-function name) |
| 933 | (catch 'indirect-subcommand | 944 | (catch 'indirect-subcommand |
| 934 | (dolist (arg args t) | 945 | (iter-do (subcommand (eshell--find-subcommands args)) |
| 935 | (pcase arg | 946 | (unless (eshell--invoke-command-directly subcommand) |
| 936 | (`(eshell-escape-arg | 947 | (throw 'indirect-subcommand nil))) |
| 937 | (let ,_ | 948 | t))))) |
| 938 | (eshell-convert | ||
| 939 | (eshell-command-to-value | ||
| 940 | (eshell-as-subcommand ,subcommand))))) | ||
| 941 | (unless (eshell--invoke-command-directly subcommand) | ||
| 942 | (throw 'indirect-subcommand nil)))))))))) | ||
| 943 | 949 | ||
| 944 | (defun eshell-invoke-directly (command) | 950 | (defun eshell-invoke-directly (command) |
| 945 | "Determine whether the given COMMAND can be invoked directly. | 951 | "Determine whether the given COMMAND can be invoked directly. |