aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Porter2023-03-20 17:25:24 -0700
committerJim Porter2023-03-28 12:02:46 -0700
commitbb088885df7a8e8a32670286a8636db8c6fadcf4 (patch)
tree41c49343ed8d074f3dac970dfd24bcbe4e83f641
parent5b005f26a831881b0509f05d3b28dafbbe5bad41 (diff)
downloademacs-bb088885df7a8e8a32670286a8636db8c6fadcf4.tar.gz
emacs-bb088885df7a8e8a32670286a8636db8c6fadcf4.zip
Simplify parsing subcommands slightly
This mainly reduces some overly-deep indentation, but also fixes some minor issues with the "$<subcmd>" form: it unnecessarily added " > TEMP" (we already set this later via 'eshell-create-handles'), and it didn't properly unescape inner double quotes. * lisp/eshell/esh-cmd.el (eshell-parse-subcommand-argument): Simplify. * lisp/eshell/esh-var.el (eshell-parse-variable-ref): Simplify and fix edge cases in "$<subcmd>". * test/lisp/eshell/esh-var-tests.el (esh-var-test/quoted-interp-temp-cmd): Adjust test to check behavior of inner double quotes.
-rw-r--r--lisp/eshell/esh-cmd.el14
-rw-r--r--lisp/eshell/esh-var.el95
-rw-r--r--test/lisp/eshell/esh-var-tests.el2
3 files changed, 56 insertions, 55 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index e0651b76249..1a458290dfe 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -675,13 +675,13 @@ This means an exit code of 0."
675 (or (= (point-max) (1+ (point))) 675 (or (= (point-max) (1+ (point)))
676 (not (eq (char-after (1+ (point))) ?\})))) 676 (not (eq (char-after (1+ (point))) ?\}))))
677 (let ((end (eshell-find-delimiter ?\{ ?\}))) 677 (let ((end (eshell-find-delimiter ?\{ ?\})))
678 (if (not end) 678 (unless end
679 (throw 'eshell-incomplete "{") 679 (throw 'eshell-incomplete "{"))
680 (when (eshell-arg-delimiter (1+ end)) 680 (when (eshell-arg-delimiter (1+ end))
681 (prog1 681 (prog1
682 `(eshell-as-subcommand 682 `(eshell-as-subcommand
683 ,(eshell-parse-command (cons (1+ (point)) end))) 683 ,(eshell-parse-command (cons (1+ (point)) end)))
684 (goto-char (1+ end)))))))) 684 (goto-char (1+ end)))))))
685 685
686(defun eshell-parse-lisp-argument () 686(defun eshell-parse-lisp-argument ()
687 "Parse a Lisp expression which is specified as an argument." 687 "Parse a Lisp expression which is specified as an argument."
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index 5d6299af564..7dcaff1e24f 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -507,55 +507,56 @@ Possible variable references are:
507 (cond 507 (cond
508 ((eq (char-after) ?{) 508 ((eq (char-after) ?{)
509 (let ((end (eshell-find-delimiter ?\{ ?\}))) 509 (let ((end (eshell-find-delimiter ?\{ ?\})))
510 (if (not end) 510 (unless end
511 (throw 'eshell-incomplete "${") 511 (throw 'eshell-incomplete "${"))
512 (forward-char) 512 (forward-char)
513 (prog1 513 (prog1
514 `(eshell-apply-indices 514 `(eshell-apply-indices
515 (eshell-convert 515 (eshell-convert
516 (eshell-command-to-value 516 (eshell-command-to-value
517 (eshell-as-subcommand 517 (eshell-as-subcommand
518 ,(let ((subcmd (or (eshell-unescape-inner-double-quote end) 518 ,(let ((subcmd (or (eshell-unescape-inner-double-quote end)
519 (cons (point) end))) 519 (cons (point) end)))
520 (eshell-current-quoted nil)) 520 (eshell-current-quoted nil))
521 (eshell-parse-command subcmd)))) 521 (eshell-parse-command subcmd))))
522 ;; If this is a simple double-quoted form like 522 ;; If this is a simple double-quoted form like
523 ;; "${COMMAND}" (i.e. no indices after the subcommand 523 ;; "${COMMAND}" (i.e. no indices after the subcommand and
524 ;; and no `#' modifier before), ensure we convert to a 524 ;; no `#' modifier before), ensure we convert to a single
525 ;; single string. This avoids unnecessary work 525 ;; string. This avoids unnecessary work (e.g. splitting
526 ;; (e.g. splitting the output by lines) when it would 526 ;; the output by lines) when it would just be joined back
527 ;; just be joined back together afterwards. 527 ;; together afterwards.
528 ,(when (and (not modifier-p) eshell-current-quoted) 528 ,(when (and (not modifier-p) eshell-current-quoted)
529 '(not indices))) 529 '(not indices)))
530 indices ,eshell-current-quoted) 530 indices ,eshell-current-quoted)
531 (goto-char (1+ end)))))) 531 (goto-char (1+ end)))))
532 ((eq (char-after) ?\<) 532 ((eq (char-after) ?\<)
533 (let ((end (eshell-find-delimiter ?\< ?\>))) 533 (let ((end (eshell-find-delimiter ?\< ?\>)))
534 (if (not end) 534 (unless end
535 (throw 'eshell-incomplete "$<") 535 (throw 'eshell-incomplete "$<"))
536 (let* ((temp (make-temp-file temporary-file-directory)) 536 (forward-char)
537 (cmd (concat (buffer-substring (1+ (point)) end) 537 (let* ((temp (make-temp-file temporary-file-directory))
538 " > " temp))) 538 (subcmd (or (eshell-unescape-inner-double-quote end)
539 (prog1 539 (cons (point) end))))
540 `(let ((eshell-current-handles 540 (prog1
541 (eshell-create-handles ,temp 'overwrite))) 541 `(let ((eshell-current-handles
542 (progn 542 (eshell-create-handles ,temp 'overwrite)))
543 (eshell-as-subcommand 543 (progn
544 ,(let ((eshell-current-quoted nil)) 544 (eshell-as-subcommand
545 (eshell-parse-command cmd))) 545 ,(let ((eshell-current-quoted nil))
546 (ignore 546 (eshell-parse-command subcmd)))
547 (nconc eshell-this-command-hook 547 (ignore
548 ;; Quote this lambda; it will be evaluated 548 (nconc eshell-this-command-hook
549 ;; by `eshell-do-eval', which requires very 549 ;; Quote this lambda; it will be evaluated by
550 ;; particular forms in order to work 550 ;; `eshell-do-eval', which requires very
551 ;; properly. See bug#54190. 551 ;; particular forms in order to work
552 (list (function 552 ;; properly. See bug#54190.
553 (lambda () 553 (list (function
554 (delete-file ,temp) 554 (lambda ()
555 (when-let ((buffer (get-file-buffer ,temp))) 555 (delete-file ,temp)
556 (kill-buffer buffer))))))) 556 (when-let ((buffer (get-file-buffer ,temp)))
557 (eshell-apply-indices ,temp indices ,eshell-current-quoted))) 557 (kill-buffer buffer)))))))
558 (goto-char (1+ end))))))) 558 (eshell-apply-indices ,temp indices ,eshell-current-quoted)))
559 (goto-char (1+ end))))))
559 ((eq (char-after) ?\() 560 ((eq (char-after) ?\()
560 (condition-case nil 561 (condition-case nil
561 `(eshell-apply-indices 562 `(eshell-apply-indices
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index 6767d9289f9..771bd5a419c 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -454,7 +454,7 @@ nil, use FUNCTION instead."
454 (let ((temporary-file-directory 454 (let ((temporary-file-directory
455 (file-name-as-directory (make-temp-file "esh-vars-tests" t)))) 455 (file-name-as-directory (make-temp-file "esh-vars-tests" t))))
456 (unwind-protect 456 (unwind-protect
457 (eshell-command-result-equal "cat \"$<echo hi>\"" "hi") 457 (eshell-command-result-equal "cat \"$<echo \\\"hi\\\">\"" "hi")
458 (delete-directory temporary-file-directory t)))) 458 (delete-directory temporary-file-directory t))))
459 459
460(ert-deftest esh-var-test/quoted-interp-concat-cmd () 460(ert-deftest esh-var-test/quoted-interp-concat-cmd ()