]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix evaluation of asynchronous expansions in Eshell indices
authorJim Porter <jporterbugs@gmail.com>
Thu, 19 Jan 2023 03:15:38 +0000 (19:15 -0800)
committerJim Porter <jporterbugs@gmail.com>
Fri, 20 Jan 2023 01:51:54 +0000 (17:51 -0800)
Previously, this code passed the indices to a separate function, which
called 'eval' on them, but it should instead make an S-expr that
'eshell-do-eval' can evaluate (bug#60942).

* lisp/eshell/esh-var.el (eshell-eval-indices): Mark obsolete.
(eshell-prepare-indices): New function...
(eshell-parse-variable): ... use it.  Also, remove irrelevant comment.
(eshell-parse-variable-ref): Fix quoting in docstring.
(eshell-parse-indices): Fix typo in docstring.

* test/lisp/eshell/esh-var-tests.el
(esh-var-test/interp-var-indices-subcommand)
(esh-var-test/quoted-interp-var-indices-subcommand): New tests.

lisp/eshell/esh-var.el
test/lisp/eshell/esh-var-tests.el

index 27e68138aa2ec59600722a8505cca11e90b621b9..83dd5cb50f5cd9313a3d9a36d5b3d8ed2ad27050 100644 (file)
@@ -467,9 +467,7 @@ process any indices that come after the variable reference."
          indices (and (not (eobp))
                       (eq (char-after) ?\[)
                       (eshell-parse-indices))
-          ;; This is an expression that will be evaluated by `eshell-do-eval',
-          ;; which only support let-binding of dynamically-scoped vars
-         value `(let ((indices (eshell-eval-indices ',indices))) ,value))
+          value `(let ((indices ,(eshell-prepare-indices indices))) ,value))
     (when get-len
       (setq value `(length ,value)))
     (when eshell-current-quoted
@@ -496,7 +494,7 @@ Possible variable references are:
 
   NAME          an environment or Lisp variable value
   \"LONG-NAME\"   disambiguates the length of the name
-  `LONG-NAME'   as above
+  \\='LONG-NAME\\='   as above
   {COMMAND}     result of command is variable's value
   (LISP-FORM)   result of Lisp form is variable's value
   <COMMAND>     write the output of command to a temporary file;
@@ -591,7 +589,7 @@ Possible variable references are:
   "Parse and return a list of index-lists.
 
 For example, \"[0 1][2]\" becomes:
-  ((\"0\" \"1\") (\"2\")."
+  ((\"0\" \"1\") (\"2\"))."
   (let (indices)
     (while (eq (char-after) ?\[)
       (let ((end (eshell-find-delimiter ?\[ ?\])))
@@ -609,8 +607,14 @@ For example, \"[0 1][2]\" becomes:
 
 (defun eshell-eval-indices (indices)
   "Evaluate INDICES, a list of index-lists generated by `eshell-parse-indices'."
+  (declare (obsolete eshell-prepare-indices "30.1"))
   (mapcar (lambda (i) (mapcar #'eval i)) indices))
 
+(defun eshell-prepare-indices (indices)
+  "Prepare INDICES to be evaluated by Eshell.
+INDICES is a list of index-lists generated by `eshell-parse-indices'."
+  `(list ,@(mapcar (lambda (idx-list) (cons 'list idx-list)) indices)))
+
 (defun eshell-get-variable (name &optional indices quoted)
   "Get the value for the variable NAME.
 INDICES is a list of index-lists (see `eshell-parse-indices').
index 0cc1b92266feeefee99b351fa5d13b50052934b1..82324d72163f0620d398811cb1dd303f1a367840 100644 (file)
     (eshell-command-result-equal "echo $eshell-test-value[0 2 4]"
                                  '("zero" "two" "four"))))
 
+(ert-deftest esh-var-test/interp-var-indices-subcommand ()
+  "Interpolate list variable with subcommand expansion for indices"
+  (skip-unless (executable-find "echo"))
+  (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
+    (eshell-command-result-equal
+     "echo $eshell-test-value[${*echo 0}]"
+     "zero")
+    (eshell-command-result-equal
+     "echo $eshell-test-value[${*echo 0} ${*echo 2}]"
+     '("zero" "two"))))
+
 (ert-deftest esh-var-test/interp-var-split-indices ()
   "Interpolate string variable with indices"
   (let ((eshell-test-value "zero one two three four"))
     (eshell-command-result-equal "echo \"$eshell-test-value[1 2 4]\""
                                  "(\"one\" \"two\" \"four\")")))
 
+(ert-deftest esh-var-test/quote-interp-var-indices-subcommand ()
+  "Interpolate list variable with subcommand expansion for indices
+inside double-quotes"
+  (skip-unless (executable-find "echo"))
+  (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
+    (eshell-command-result-equal
+     "echo \"$eshell-test-value[${*echo 0}]\""
+     "zero")
+    ;; FIXME: These tests would use the 0th index like the other tests
+    ;; here, but see above.
+    (eshell-command-result-equal
+     "echo \"$eshell-test-value[${*echo 1} ${*echo 2}]\""
+     "(\"one\" \"two\")")))
+
 (ert-deftest esh-var-test/quoted-interp-var-split-indices ()
   "Interpolate string variable with indices inside double-quotes"
   (let ((eshell-test-value "zero one two three four"))