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).
This commit is contained in:
parent
a6ad584ac2
commit
587edc46df
2 changed files with 24 additions and 11 deletions
|
@ -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.
|
||||
|
|
|
@ -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)")))
|
||||
|
|
Loading…
Add table
Reference in a new issue