aboutsummaryrefslogtreecommitdiffstats
path: root/test/lisp/eshell
diff options
context:
space:
mode:
authorJim Porter2022-11-08 22:49:23 -0800
committerJim Porter2022-12-15 21:41:03 -0800
commite63ef66c57ee74b24998a16b34949f67bbb73d8d (patch)
treed41fe6c0405a02f78f025284a245e1c4735a6a1b /test/lisp/eshell
parent66ac920b0c233e472c7f54d108503dfe9236d3c0 (diff)
downloademacs-e63ef66c57ee74b24998a16b34949f67bbb73d8d.tar.gz
emacs-e63ef66c57ee74b24998a16b34949f67bbb73d8d.zip
Add support for the "splice operator" in Eshell
This allows splicing lists in-place in argument lists, which is particularly important when defining aliases using the '$*' special variable (bug#59960). * lisp/eshell/esh-var.el (eshell-parse-variable): Add support for the splice operator. (eshell-interpolate-variable): Let 'eshell-parse-variable' handle adding 'eshell-escape-arg'. (eshell-complete-variable-reference): Handle the splice operator. * lisp/eshell/esh-arg.el (eshell-concat-groups) (eshell-prepare-splice): New functions... (eshell-resolve-current-argument): ... use them. (eshell-splice-args): New function. * lisp/eshell/esh-cmd.el (eshell-rewrite-named-command): Handle 'eshell-splice-args'. * lisp/eshell/esh-util.el (eshell-list-to-string): New function... (eshell-flatten-and-stringify): ... use it. * lisp/eshell/em-cmpl.el (eshell-complete-parse-arguments): Remove 'eshell-splice-args' sigils in Eshell command forms so that we can perform completion on splice-expansions. * lisp/eshell/em-unix.el (eshell-complete-host-reference): Don't try to complete arguments containing "$@". * test/lisp/eshell/esh-var-tets.el (esh-var-test/interp-list-var) (esh-var-test/interp-list-var-concat, esh-var-test/interp-var-splice) (esh-var-test/interp-var-splice-concat) (esh-var-test/quoted-interp-list-var) (esh-var-test/quoted-interp-list-var-concat) (esh-var-test/quoted-interp-var-splice) (esh-var-test/quoted-interp-var-splice-concat): New tests. * test/lisp/eshell/em-alias-tests.el (em-alias-test/alias-all-args-var-splice): New test. * doc/misc/eshell.texi (Dollars Expansion): Explain the splice operator. (Aliases): Expand documentation and use '$@*'. (Built-ins, Bugs and Ideas): Use '$@*' where appropriate. * etc/NEWS: Announce this change.
Diffstat (limited to 'test/lisp/eshell')
-rw-r--r--test/lisp/eshell/em-alias-tests.el9
-rw-r--r--test/lisp/eshell/esh-var-tests.el74
2 files changed, 83 insertions, 0 deletions
diff --git a/test/lisp/eshell/em-alias-tests.el b/test/lisp/eshell/em-alias-tests.el
index aca622220e3..0a26e8d2011 100644
--- a/test/lisp/eshell/em-alias-tests.el
+++ b/test/lisp/eshell/em-alias-tests.el
@@ -72,6 +72,15 @@
72 (eshell-match-command-output "show-all-args a" "a\n") 72 (eshell-match-command-output "show-all-args a" "a\n")
73 (eshell-match-command-output "show-all-args a b c" "a\nb\nc\n"))) 73 (eshell-match-command-output "show-all-args a b c" "a\nb\nc\n")))
74 74
75(ert-deftest em-alias-test/alias-all-args-var-splice ()
76 "Test alias with splicing the $* variable"
77 (with-temp-eshell
78 (eshell-insert-command "alias show-all-args 'echo args: $@*'")
79 (eshell-match-command-output "show-all-args" "args:\n")
80 (eshell-match-command-output "show-all-args a" "(\"args:\" \"a\")\n")
81 (eshell-match-command-output "show-all-args a b c"
82 "(\"args:\" \"a\" \"b\" \"c\")\n")))
83
75(ert-deftest em-alias-test/alias-all-args-var-indices () 84(ert-deftest em-alias-test/alias-all-args-var-indices ()
76 "Test alias with the $* variable using indices" 85 "Test alias with the $* variable using indices"
77 (with-temp-eshell 86 (with-temp-eshell
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index 96fde026a54..d95669fdaf8 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -60,6 +60,18 @@
60 (eshell-command-result-equal "echo $\"user-login-name\"-foo" 60 (eshell-command-result-equal "echo $\"user-login-name\"-foo"
61 (concat user-login-name "-foo"))) 61 (concat user-login-name "-foo")))
62 62
63(ert-deftest esh-var-test/interp-list-var ()
64 "Interpolate list variable"
65 (let ((eshell-test-value '(1 2 3)))
66 (eshell-command-result-equal "echo $eshell-test-value"
67 '(1 2 3))))
68
69(ert-deftest esh-var-test/interp-list-var-concat ()
70 "Interpolate and concat list variable"
71 (let ((eshell-test-value '(1 2 3)))
72 (eshell-command-result-equal "echo a$'eshell-test-value'z"
73 '("a1" 2 "3z"))))
74
63(ert-deftest esh-var-test/interp-var-indices () 75(ert-deftest esh-var-test/interp-var-indices ()
64 "Interpolate list variable with indices" 76 "Interpolate list variable with indices"
65 (let ((eshell-test-value '("zero" "one" "two" "three" "four"))) 77 (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
@@ -131,6 +143,26 @@
131 (eshell-command-result-equal "echo $#eshell-test-value" 1) 143 (eshell-command-result-equal "echo $#eshell-test-value" 1)
132 (eshell-command-result-equal "echo $#eshell-test-value[foo]" 3))) 144 (eshell-command-result-equal "echo $#eshell-test-value[foo]" 3)))
133 145
146(ert-deftest esh-var-test/interp-var-splice ()
147 "Splice-interpolate list variable"
148 (let ((eshell-test-value '(1 2 3)))
149 (eshell-command-result-equal "echo a $@eshell-test-value z"
150 '("a" 1 2 3 "z"))))
151
152(ert-deftest esh-var-test/interp-var-splice-concat ()
153 "Splice-interpolate and concat list variable"
154 (let ((eshell-test-value '(1 2 3)))
155 (eshell-command-result-equal "echo it is a$@'eshell-test-value'z"
156 '("it" "is" "a1" 2 "3z"))
157 ;; This is a tricky case. We're concatenating a spliced list and
158 ;; a non-spliced list. The general rule is that splicing should
159 ;; work as though the user typed "$X[0] $X[1] ... $X[N]". That
160 ;; means that the last value of our splice should get concatenated
161 ;; into the first value of the non-spliced list.
162 (eshell-command-result-equal
163 "echo it is $@'eshell-test-value'$eshell-test-value"
164 '("it" "is" 1 2 (31 2 3)))))
165
134(ert-deftest esh-var-test/interp-lisp () 166(ert-deftest esh-var-test/interp-lisp ()
135 "Interpolate Lisp form evaluation" 167 "Interpolate Lisp form evaluation"
136 (eshell-command-result-equal "+ $(+ 1 2) 3" 6)) 168 (eshell-command-result-equal "+ $(+ 1 2) 3" 6))
@@ -197,6 +229,9 @@
197 (eshell-match-command-output "echo ${echo hi}-${*echo there}" 229 (eshell-match-command-output "echo ${echo hi}-${*echo there}"
198 "hi-there\n"))) 230 "hi-there\n")))
199 231
232
233;; Quoted variable interpolation
234
200(ert-deftest esh-var-test/quoted-interp-var () 235(ert-deftest esh-var-test/quoted-interp-var ()
201 "Interpolate variable inside double-quotes" 236 "Interpolate variable inside double-quotes"
202 (eshell-command-result-equal "echo \"$user-login-name\"" 237 (eshell-command-result-equal "echo \"$user-login-name\""
@@ -209,6 +244,18 @@
209 (eshell-command-result-equal "echo \"hi, $\\\"user-login-name\\\"\"" 244 (eshell-command-result-equal "echo \"hi, $\\\"user-login-name\\\"\""
210 (concat "hi, " user-login-name))) 245 (concat "hi, " user-login-name)))
211 246
247(ert-deftest esh-var-test/quoted-interp-list-var ()
248 "Interpolate list variable inside double-quotes"
249 (let ((eshell-test-value '(1 2 3)))
250 (eshell-command-result-equal "echo \"$eshell-test-value\""
251 "(1 2 3)")))
252
253(ert-deftest esh-var-test/quoted-interp-list-var-concat ()
254 "Interpolate and concat list variable inside double-quotes"
255 (let ((eshell-test-value '(1 2 3)))
256 (eshell-command-result-equal "echo \"a$'eshell-test-value'z\""
257 "a(1 2 3)z")))
258
212(ert-deftest esh-var-test/quoted-interp-var-indices () 259(ert-deftest esh-var-test/quoted-interp-var-indices ()
213 "Interpolate string variable with indices inside double-quotes" 260 "Interpolate string variable with indices inside double-quotes"
214 (let ((eshell-test-value '("zero" "one" "two" "three" "four"))) 261 (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
@@ -291,6 +338,18 @@ inside double-quotes"
291 (eshell-command-result-equal "echo \"$#eshell-test-value[foo]\"" 338 (eshell-command-result-equal "echo \"$#eshell-test-value[foo]\""
292 "3"))) 339 "3")))
293 340
341(ert-deftest esh-var-test/quoted-interp-var-splice ()
342 "Splice-interpolate list variable inside double-quotes"
343 (let ((eshell-test-value '(1 2 3)))
344 (eshell-command-result-equal "echo a \"$@eshell-test-value\" z"
345 '("a" "1 2 3" "z"))))
346
347(ert-deftest esh-var-test/quoted-interp-var-splice-concat ()
348 "Splice-interpolate and concat list variable inside double-quotes"
349 (let ((eshell-test-value '(1 2 3)))
350 (eshell-command-result-equal "echo \"a$@'eshell-test-value'z\""
351 "a1 2 3z")))
352
294(ert-deftest esh-var-test/quoted-interp-lisp () 353(ert-deftest esh-var-test/quoted-interp-lisp ()
295 "Interpolate Lisp form evaluation inside double-quotes" 354 "Interpolate Lisp form evaluation inside double-quotes"
296 (eshell-command-result-equal "echo \"hi $(concat \\\"the\\\" \\\"re\\\")\"" 355 (eshell-command-result-equal "echo \"hi $(concat \\\"the\\\" \\\"re\\\")\""
@@ -325,6 +384,21 @@ inside double-quotes"
325 "foo\nbar baz")) 384 "foo\nbar baz"))
326 385
327 386
387;; Interpolating commands
388
389(ert-deftest esh-var-test/command-interp ()
390 "Interpolate a variable as a command name"
391 (let ((eshell-test-value "printnl"))
392 (eshell-command-result-equal "$eshell-test-value hello there"
393 "hello\nthere\n")))
394
395(ert-deftest esh-var-test/command-interp-splice ()
396 "Interpolate a splice variable as a command name with arguments"
397 (let ((eshell-test-value '("printnl" "hello" "there")))
398 (eshell-command-result-equal "$@eshell-test-value"
399 "hello\nthere\n")))
400
401
328;; Interpolated variable conversion 402;; Interpolated variable conversion
329 403
330(ert-deftest esh-var-test/interp-convert-var-number () 404(ert-deftest esh-var-test/interp-convert-var-number ()