all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 60942@debbugs.gnu.org
Subject: bug#60942: 30.0.50; [PATCH] Indices in Eshell variable interpolation don't work with async subcommands
Date: Thu, 19 Jan 2023 11:31:24 -0800	[thread overview]
Message-ID: <c15efd71-1d2b-6ae9-486f-030a00271726@gmail.com> (raw)
In-Reply-To: <d5b6e127-9b79-2ef3-275e-ef274a953c7a@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 739 bytes --]

On 1/18/2023 11:37 PM, Jim Porter wrote:
> On 1/18/2023 10:49 PM, Eli Zaretskii wrote:
>> Why do you remove a non-internal function?  We cannot possibly do that
>> if this is going to be installed on the emacs-29 branch.  But even if
>> you are going to install on master, why not leave that function alone?
>> Some code somewhere could be using it, and we don't usually remove
>> functions before a period of deprecation.
> 
> I can keep 'eshell-eval-indices' around and mark it obsolete if you 
> prefer; it wouldn't hurt anything.

Here's a patch that does this. It doesn't try to fix 
'eshell-eval-indices', since people shouldn't use that anyway. (I also 
renamed the new 'eshell-indices' to 'eshell-prepare-indices' to be clearer.)

[-- Attachment #2: 0001-Fix-evaluation-of-asynchronous-expansions-in-Eshell-.patch --]
[-- Type: text/plain, Size: 4999 bytes --]

From 4cc14646a50b237d38cfb6643858cb379366141a Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Wed, 18 Jan 2023 19:15:38 -0800
Subject: [PATCH] Fix evaluation of asynchronous expansions in Eshell indices

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.

* 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            | 14 +++++++++-----
 test/lisp/eshell/esh-var-tests.el | 25 +++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index fd76a2c6f09..0998fc6b86a 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -467,9 +467,7 @@ eshell-parse-variable
 	  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 @@ eshell-parse-variable-ref
 
   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 @@ eshell-parse-indices
   "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 @@ eshell-parse-indices
 
 (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').
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index 0cc1b92266f..82324d72163 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -82,6 +82,17 @@ esh-var-test/interp-var-indices
     (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"))
@@ -271,6 +282,20 @@ esh-var-test/quoted-interp-var-indices
     (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"))
-- 
2.25.1


  reply	other threads:[~2023-01-19 19:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-19  3:36 bug#60942: 30.0.50; [PATCH] Indices in Eshell variable interpolation don't work with async subcommands Jim Porter
2023-01-19  6:49 ` Eli Zaretskii
2023-01-19  7:37   ` Jim Porter
2023-01-19 19:31     ` Jim Porter [this message]
2023-01-19 19:41       ` Eli Zaretskii
2023-01-19 20:20         ` Jim Porter
2023-01-20  1:54           ` Jim Porter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c15efd71-1d2b-6ae9-486f-030a00271726@gmail.com \
    --to=jporterbugs@gmail.com \
    --cc=60942@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.