emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 18d83b9452 3/3: Ensure Eshell variable aliases properly handle in


From: Lars Ingebrigtsen
Subject: master 18d83b9452 3/3: Ensure Eshell variable aliases properly handle indexing
Date: Tue, 12 Jul 2022 09:12:05 -0400 (EDT)

branch: master
commit 18d83b94528c503f2cd6d0a89f2c5db2d5d48165
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Ensure Eshell variable aliases properly handle indexing
    
    * lisp/eshell/em-dirs.el (eshell-dirs-initialize): Properly handle
    indexing for variable aliases.
    
    * lisp/eshell/esh-var (eshell-variable-aliases-list): Properly handle
    indexing for variable aliases, and add SIMPLE-FUNCTION entry for
    aliases.
    (eshell-get-variable): Update how variable alias functions are called.
    
    * test/lisp/eshell/em-alias-tests.el
    (em-alias-test/alias-arg-vars-indices)
    (em-alias-test/alias-arg-vars-split-indices)
    (em-alias-test/alias-all-args-var-split-indices):
    * test/lisp/eshell/em-dirs-tests.el (em-dirs-test/pwd-var-indices)
    (em-dirs-test/oldpwd-var-indices)
    (em-dirs-test/directory-ring-var-indices):
    * test/lisp/eshell/esh-var-tests.el
    (esh-var-test/inside-emacs-var-split-indices)
    (esh-var-test/last-result-var-split-indices): New tests.
    (esh-var-test/last-arg-var-split-indices): Expand test to check
    conversion behavior inside double quotes (bug#56509).
---
 lisp/eshell/em-dirs.el             | 36 ++++++++++---------
 lisp/eshell/esh-var.el             | 73 ++++++++++++++++++++++----------------
 test/lisp/eshell/em-alias-tests.el | 23 ++++++++++++
 test/lisp/eshell/em-dirs-tests.el  | 28 +++++++++++++++
 test/lisp/eshell/esh-var-tests.el  | 22 ++++++++++--
 5 files changed, 134 insertions(+), 48 deletions(-)

diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el
index a3cf0b9131..00880b9f28 100644
--- a/lisp/eshell/em-dirs.el
+++ b/lisp/eshell/em-dirs.el
@@ -175,22 +175,26 @@ Thus, this does not include the current directory.")
   (setq-local eshell-variable-aliases-list
        (append
         eshell-variable-aliases-list
-         `(("-" ,(lambda (indices)
-                  (if (not indices)
-                      (unless (ring-empty-p eshell-last-dir-ring)
-                        (expand-file-name
-                         (ring-ref eshell-last-dir-ring 0)))
-                    (expand-file-name
-                     (eshell-apply-indices eshell-last-dir-ring indices)))))
-          ("+" "PWD")
-          ("PWD" ,(lambda (_indices)
-                    (expand-file-name (eshell/pwd)))
-            t)
-          ("OLDPWD" ,(lambda (_indices)
-                       (unless (ring-empty-p eshell-last-dir-ring)
-                         (expand-file-name
-                          (ring-ref eshell-last-dir-ring 0))))
-            t))))
+         `(("-" ,(lambda (indices quoted)
+                   (if (not indices)
+                       (unless (ring-empty-p eshell-last-dir-ring)
+                         (expand-file-name
+                          (ring-ref eshell-last-dir-ring 0)))
+                     ;; Apply the first index, expand the file name,
+                     ;; and then apply the rest of the indices.
+                     (eshell-apply-indices
+                      (expand-file-name
+                       (eshell-apply-indices eshell-last-dir-ring
+                                             (list (car indices)) quoted))
+                      (cdr indices) quoted))))
+           ("+" "PWD")
+           ("PWD" ,(lambda () (expand-file-name (eshell/pwd)))
+            t t)
+           ("OLDPWD" ,(lambda ()
+                       (unless (ring-empty-p eshell-last-dir-ring)
+                         (expand-file-name
+                          (ring-ref eshell-last-dir-ring 0))))
+            t t))))
 
   (when eshell-cd-on-directory
     (setq-local eshell-interpreter-alist
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index e1535c1c5d..cbd7942de4 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -152,59 +152,63 @@ if they are quoted with a backslash."
 
 (defcustom eshell-variable-aliases-list
   `(;; for eshell.el
-    ("COLUMNS" ,(lambda (_indices) (window-body-width nil 'remap)) t)
-    ("LINES" ,(lambda (_indices) (window-body-height nil 'remap)) t)
+    ("COLUMNS" ,(lambda () (window-body-width nil 'remap)) t t)
+    ("LINES" ,(lambda () (window-body-height nil 'remap)) t t)
     ("INSIDE_EMACS" eshell-inside-emacs t)
 
     ;; for eshell-cmd.el
-    ("_" ,(lambda (indices)
+    ("_" ,(lambda (indices quoted)
            (if (not indices)
                (car (last eshell-last-arguments))
              (eshell-apply-indices eshell-last-arguments
-                                   indices))))
+                                   indices quoted))))
     ("?" eshell-last-command-status)
     ("$" eshell-last-command-result)
 
     ;; for em-alias.el and em-script.el
     ("0" eshell-command-name)
-    ("1" ,(lambda (_indices) (nth 0 eshell-command-arguments)))
-    ("2" ,(lambda (_indices) (nth 1 eshell-command-arguments)))
-    ("3" ,(lambda (_indices) (nth 2 eshell-command-arguments)))
-    ("4" ,(lambda (_indices) (nth 3 eshell-command-arguments)))
-    ("5" ,(lambda (_indices) (nth 4 eshell-command-arguments)))
-    ("6" ,(lambda (_indices) (nth 5 eshell-command-arguments)))
-    ("7" ,(lambda (_indices) (nth 6 eshell-command-arguments)))
-    ("8" ,(lambda (_indices) (nth 7 eshell-command-arguments)))
-    ("9" ,(lambda (_indices) (nth 8 eshell-command-arguments)))
-    ("*" ,(lambda (indices)
-           (if (not indices)
-               eshell-command-arguments
-             (eshell-apply-indices eshell-command-arguments
-                                   indices)))))
+    ("1" ,(lambda () (nth 0 eshell-command-arguments)) nil t)
+    ("2" ,(lambda () (nth 1 eshell-command-arguments)) nil t)
+    ("3" ,(lambda () (nth 2 eshell-command-arguments)) nil t)
+    ("4" ,(lambda () (nth 3 eshell-command-arguments)) nil t)
+    ("5" ,(lambda () (nth 4 eshell-command-arguments)) nil t)
+    ("6" ,(lambda () (nth 5 eshell-command-arguments)) nil t)
+    ("7" ,(lambda () (nth 6 eshell-command-arguments)) nil t)
+    ("8" ,(lambda () (nth 7 eshell-command-arguments)) nil t)
+    ("9" ,(lambda () (nth 8 eshell-command-arguments)) nil t)
+    ("*" eshell-command-arguments))
   "This list provides aliasing for variable references.
-Each member defines the name of a variable, and a Lisp value used to
+Each member is of the following form:
+
+  (NAME VALUE [COPY-TO-ENVIRONMENT] [SIMPLE-FUNCTION])
+
+NAME defines the name of the variable, VALUE is a Lisp value used to
 compute the string value that will be returned when the variable is
 accessed via the syntax `$NAME'.
 
-If the value is a function, call that function with one argument: the
-list of the indices that was used in the reference.  For example, if
+If VALUE is a function, its behavior depends on the value of
+SIMPLE-FUNCTION.  If SIMPLE-FUNCTION is nil, call VALUE with two
+arguments: the list of the indices that was used in the reference and
+whether the variable was used within double quotes.  For example, if
 `NAME' were aliased to a function, a reference of `$NAME[10][20]'
-would result in that function being called with the argument
-`((\"10\") (\"20\"))'.  (For more details, see `eshell-apply-indices').
+would result in that function being called with the arguments
+`((\"10\") (\"20\"))' and nil.  If SIMPLE-FUNCTION is non-nil, call
+the function with no arguments and then pass its result to
+`eshell-apply-indices'.
 
-If the value is a string, return the value for the variable with that
+If VALUE is a string, return the value for the variable with that
 name in the current environment.  If no variable with that name exists
 in the environment, but if a symbol with that same name exists and has
 a value bound to it, return its value instead.  You can prioritize
 symbol values over environment values by setting
 `eshell-prefer-lisp-variables' to t.
 
-If the value is a symbol, return the value bound to it.
+If VALUE is a symbol, return the value bound to it.
 
-If the value has any other type, signal an error.
+If VALUE has any other type, signal an error.
 
-Additionally, each member may specify if it should be copied to the
-environment of created subprocesses."
+Additionally, if COPY-TO-ENVIRONMENT is non-nil, the alias should be
+copied to the environment of created subprocesses."
   :type '(repeat (list string sexp
                       (choice (const :tag "Copy to environment" t)
                                (const :tag "Use only in Eshell" nil))))
@@ -550,10 +554,19 @@ For example, \"[0 1][2]\" becomes:
 INDICES is a list of index-lists (see `eshell-parse-indices').
 If QUOTED is non-nil, this was invoked inside double-quotes."
   (if-let ((alias (assoc name eshell-variable-aliases-list)))
-      (let ((target (cadr alias)))
+      (let ((target (nth 1 alias)))
         (cond
          ((functionp target)
-          (funcall target indices))
+          (if (nth 3 alias)
+              (eshell-apply-indices (funcall target) indices quoted)
+            (condition-case nil
+               (funcall target indices quoted)
+              (wrong-number-of-arguments
+               (display-warning
+                :warning (concat "Function for `eshell-variable-aliases-list' "
+                                 "entry should accept two arguments: INDICES "
+                                 "and QUOTED.'"))
+               (funcall target indices)))))
          ((symbolp target)
           (eshell-apply-indices (symbol-value target) indices quoted))
          (t
diff --git a/test/lisp/eshell/em-alias-tests.el 
b/test/lisp/eshell/em-alias-tests.el
index 762f125a78..497159e346 100644
--- a/test/lisp/eshell/em-alias-tests.el
+++ b/test/lisp/eshell/em-alias-tests.el
@@ -47,6 +47,23 @@
    (eshell-insert-command "alias show-args 'printnl $0 \"$1 $2\"'")
    (eshell-command-result-p "show-args one two" "show-args\none two\n")))
 
+(ert-deftest em-alias-test/alias-arg-vars-indices ()
+  "Test alias with $1, $2, ... variables using indices"
+  (with-temp-eshell
+   (eshell-insert-command "alias funny-sum '+ $1[0] $2[1]'")
+   (eshell-command-result-p "funny-sum (list 1 2) (list 3 4)"
+                            "5\n")))
+
+(ert-deftest em-alias-test/alias-arg-vars-split-indices ()
+  "Test alias with $0, $1, ... variables using split indices"
+  (with-temp-eshell
+   (eshell-insert-command "alias my-prefix 'echo $0[- 0]'")
+   (eshell-command-result-p "my-prefix"
+                            "my\n")
+   (eshell-insert-command "alias funny-sum '+ $1[: 0] $2[: 1]'")
+   (eshell-command-result-p "funny-sum 1:2 3:4"
+                            "5\n")))
+
 (ert-deftest em-alias-test/alias-all-args-var ()
   "Test alias with the $* variable"
   (with-temp-eshell
@@ -61,4 +78,10 @@
    (eshell-insert-command "alias add-pair '+ $*[0] $*[1]'")
    (eshell-command-result-p "add-pair 1 2" "3\n")))
 
+(ert-deftest em-alias-test/alias-all-args-var-split-indices ()
+  "Test alias with the $* variable using split indices"
+  (with-temp-eshell
+   (eshell-insert-command "alias add-funny-pair '+ $*[0][: 0] $*[1][: 1]'")
+   (eshell-command-result-p "add-funny-pair 1:2 3:4" "5\n")))
+
 ;; em-alias-tests.el ends here
diff --git a/test/lisp/eshell/em-dirs-tests.el 
b/test/lisp/eshell/em-dirs-tests.el
index 69480051e4..8e96cc0747 100644
--- a/test/lisp/eshell/em-dirs-tests.el
+++ b/test/lisp/eshell/em-dirs-tests.el
@@ -40,6 +40,14 @@
     (should (equal (eshell-test-command-result "echo $PWD")
                    (expand-file-name default-directory)))))
 
+(ert-deftest em-dirs-test/pwd-var-indices ()
+  "Test using the $PWD variable with indices."
+  (let ((default-directory "/some/path/here"))
+    (should (equal (eshell-test-command-result "echo $PWD[/ 1]")
+                   "some"))
+    (should (equal (eshell-test-command-result "echo $PWD[/ 1 3]")
+                   '("some" "here")))))
+
 (ert-deftest em-dirs-test/short-pwd-var ()
   "Test using the $+ (current directory) variable."
   (let ((default-directory "/some/path"))
@@ -56,6 +64,16 @@
      (eshell-command-result-p "echo $OLDPWD"
                               "/some/path\n"))))
 
+(ert-deftest em-dirs-test/oldpwd-var-indices ()
+  "Test using the $OLDPWD variable with indices."
+  (let (eshell-last-dir-ring-file-name)
+    (with-temp-eshell
+     (ring-insert eshell-last-dir-ring "/some/path/here")
+     (eshell-command-result-p "echo $OLDPWD[/ 1]"
+                              "some\n")
+     (eshell-command-result-p "echo $OLDPWD[/ 1 3]"
+                              "(\"some\" \"here\")\n"))))
+
 (ert-deftest em-dirs-test/directory-ring-var ()
   "Test using the $- (directory ring) variable."
   (let (eshell-last-dir-ring-file-name)
@@ -71,4 +89,14 @@
      (eshell-command-result-p "echo $-[1]"
                               "/some/path\n"))))
 
+(ert-deftest em-dirs-test/directory-ring-var-indices ()
+  "Test using the $- (directory ring) variable with multiple indices."
+  (let (eshell-last-dir-ring-file-name)
+    (with-temp-eshell
+     (ring-insert eshell-last-dir-ring "/some/path/here")
+     (eshell-command-result-p "echo $-[0][/ 1]"
+                              "some\n")
+     (eshell-command-result-p "echo $-[1][/ 1 3]"
+                              "(\"some\" \"here\")\n"))))
+
 ;; em-dirs-tests.el ends here
diff --git a/test/lisp/eshell/esh-var-tests.el 
b/test/lisp/eshell/esh-var-tests.el
index 955190aee0..54e701a6aa 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -494,6 +494,12 @@ inside double-quotes"
                             (format "INSIDE_EMACS=%s,eshell"
                                     emacs-version))))
 
+(ert-deftest esh-var-test/inside-emacs-var-split-indices ()
+  "Test using \"INSIDE_EMACS\" with split indices"
+  (with-temp-eshell
+   (eshell-command-result-p "echo $INSIDE_EMACS[, 1]"
+                            "eshell")))
+
 (ert-deftest esh-var-test/last-result-var ()
   "Test using the \"last result\" ($$) variable"
   (with-temp-eshell
@@ -506,6 +512,16 @@ inside double-quotes"
    (eshell-command-result-p "+ 1 2; + $$ $$"
                             "3\n6\n")))
 
+(ert-deftest esh-var-test/last-result-var-split-indices ()
+  "Test using the \"last result\" ($$) variable with split indices"
+  (with-temp-eshell
+   (eshell-command-result-p
+    "string-join (list \"01\" \"02\") :; + $$[: 1] 3"
+    "01:02\n5\n")
+   (eshell-command-result-p
+    "string-join (list \"01\" \"02\") :; echo \"$$[: 1]\""
+    "01:02\n02\n")))
+
 (ert-deftest esh-var-test/last-arg-var ()
   "Test using the \"last arg\" ($_) variable"
   (with-temp-eshell
@@ -523,7 +539,9 @@ inside double-quotes"
 (ert-deftest esh-var-test/last-arg-var-split-indices ()
   "Test using the \"last arg\" ($_) variable with split indices"
   (with-temp-eshell
-   (eshell-command-result-p "concat 01:02 03:04; echo $_[0][: 1]"
-                            "01:0203:04\n2\n")))
+   (eshell-command-result-p "concat 01:02 03:04; + $_[0][: 1] 5"
+                            "01:0203:04\n7\n")
+   (eshell-command-result-p "concat 01:02 03:04; echo \"$_[0][: 1]\""
+                            "01:0203:04\n02\n")))
 
 ;; esh-var-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]