diff options
author | Jim Porter <jporterbugs@gmail.com> | 2022-01-21 10:32:00 +0100 |
---|---|---|
committer | Lars Ingebrigtsen <larsi@gnus.org> | 2022-01-21 10:32:00 +0100 |
commit | 587edc46dfc0aa035c49a5c97ff36472e2c4dbfd (patch) | |
tree | 6fbaf9ec3124706ea25aab0421bbe1c3393cfaa1 | |
parent | a6ad584ac27dcc6bbe2476face53a3165f99366d (diff) | |
download | emacs-587edc46dfc0aa035c49a5c97ff36472e2c4dbfd.tar.gz emacs-587edc46dfc0aa035c49a5c97ff36472e2c4dbfd.tar.bz2 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).
-rw-r--r-- | lisp/eshell/esh-cmd.el | 28 | ||||
-rw-r--r-- | test/lisp/eshell/eshell-tests.el | 7 |
2 files changed, 24 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 @@ (require 'esh-module) (require 'esh-io) (require 'esh-ext) +(require 'generator) (eval-when-compile (require 'cl-lib) @@ -903,6 +904,17 @@ at the moment are: "Completion for the `debug' command." (while (pcomplete-here '("errors" "commands")))) +(iter-defun eshell--find-subcommands (haystack) + "Recursively search for subcommand forms in HAYSTACK. +This yields the SUBCOMMANDs when found in forms like +\"(eshell-as-subcommand SUBCOMMAND)\"." + (dolist (elem haystack) + (cond + ((eq (car-safe elem) 'eshell-as-subcommand) + (iter-yield (cdr elem))) + ((listp elem) + (iter-yield-from (eshell--find-subcommands elem)))))) + (defun eshell--invoke-command-directly (command) "Determine whether the given COMMAND can be invoked directly. 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: * NAME is a string referring to an alias function and isn't a complex command (see `eshell-complex-commands'). -* Any argument in ARGS that calls a subcommand can also be - invoked directly." +* Any subcommands in ARGS can also be invoked directly." (when (and (eq (car command) 'eshell-trap-errors) (eq (car (cadr command)) 'eshell-named-command)) (let ((name (cadr (cadr command))) @@ -931,15 +942,10 @@ A command can be invoked directly if all of the following are true: (throw 'simple nil)))) (eshell-find-alias-function name) (catch 'indirect-subcommand - (dolist (arg args t) - (pcase arg - (`(eshell-escape-arg - (let ,_ - (eshell-convert - (eshell-command-to-value - (eshell-as-subcommand ,subcommand))))) - (unless (eshell--invoke-command-directly subcommand) - (throw 'indirect-subcommand nil)))))))))) + (iter-do (subcommand (eshell--find-subcommands args)) + (unless (eshell--invoke-command-directly subcommand) + (throw 'indirect-subcommand nil))) + t))))) (defun eshell-invoke-directly (command) "Determine whether the given COMMAND can be invoked directly. diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el index c4cb9bf4850..1a7ab0ab06f 100644 --- a/test/lisp/eshell/eshell-tests.el +++ b/test/lisp/eshell/eshell-tests.el @@ -167,6 +167,13 @@ e.g. \"{(+ 1 2)} 3\" => 3" (eshell-command-result-p "echo ${*echo hi}" "hi\n"))) +(ert-deftest eshell-test/interp-cmd-external-concat () + "Interpolate command result from external command with concatenation" + (skip-unless (executable-find "echo")) + (with-temp-eshell + (eshell-command-result-p "echo ${echo hi}-${*echo there}" + "hi-there\n"))) + (ert-deftest eshell-test/window-height () "$LINES should equal (window-height)" (should (eshell-test-command-result "= $LINES (window-height)"))) |