diff options
| author | Jim Porter | 2023-03-20 17:25:24 -0700 |
|---|---|---|
| committer | Jim Porter | 2023-03-28 12:02:46 -0700 |
| commit | bb088885df7a8e8a32670286a8636db8c6fadcf4 (patch) | |
| tree | 41c49343ed8d074f3dac970dfd24bcbe4e83f641 | |
| parent | 5b005f26a831881b0509f05d3b28dafbbe5bad41 (diff) | |
| download | emacs-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.el | 14 | ||||
| -rw-r--r-- | lisp/eshell/esh-var.el | 95 | ||||
| -rw-r--r-- | test/lisp/eshell/esh-var-tests.el | 2 |
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 () |