Function: eshell-parse-variable-ref

eshell-parse-variable-ref is a byte-compiled function defined in esh-var.el.gz.

Signature

(eshell-parse-variable-ref &optional MODIFIER-P)

Documentation

Eval a variable reference.

Returns a Lisp form which, if evaluated, will return the value of the variable.

If MODIFIER-P is non-nil, the value of the variable will be modified by some function. If MODIFIER-P is nil, the value will be used as-is; this allows optimization of some kinds of variable references.

Possible variable references are:

  NAME an environment or Lisp variable value
  "LONG-NAME" disambiguates the length of the name
  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;
                result is the file name

Source Code

;; Defined in /usr/src/emacs/lisp/eshell/esh-var.el.gz
(defun eshell-parse-variable-ref (&optional modifier-p)
  "Eval a variable reference.
Returns a Lisp form which, if evaluated, will return the value of the
variable.

If MODIFIER-P is non-nil, the value of the variable will be
modified by some function.  If MODIFIER-P is nil, the value will be
used as-is; this allows optimization of some kinds of variable
references.

Possible variable references are:

  NAME          an environment or Lisp variable value
  \"LONG-NAME\"   disambiguates the length of the name
  `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;
                result is the file name"
  (cond
   ((eq (char-after) ?{)
    (let ((end (eshell-find-delimiter ?\{ ?\})))
      (if (not end)
          (throw 'eshell-incomplete ?\{)
        (forward-char)
        (prog1
            `(eshell-apply-indices
              (eshell-convert
               (eshell-command-to-value
                (eshell-as-subcommand
                 ,(let ((subcmd (or (eshell-unescape-inner-double-quote end)
                                    (cons (point) end)))
                        (eshell-current-quoted nil))
                    (eshell-parse-command subcmd))))
               ;; If this is a simple double-quoted form like
               ;; "${COMMAND}" (i.e. no indices after the subcommand
               ;; and no `#' modifier before), ensure we convert to a
               ;; single string.  This avoids unnecessary work
               ;; (e.g. splitting the output by lines) when it would
               ;; just be joined back together afterwards.
               ,(when (and (not modifier-p) eshell-current-quoted)
                  '(not indices)))
              indices ,eshell-current-quoted)
          (goto-char (1+ end))))))
   ((eq (char-after) ?\<)
    (let ((end (eshell-find-delimiter ?\< ?\>)))
      (if (not end)
          (throw 'eshell-incomplete ?\<)
        (let* ((temp (make-temp-file temporary-file-directory))
               (cmd (concat (buffer-substring (1+ (point)) end)
                            " > " temp)))
          (prog1
              `(let ((eshell-current-handles
                      (eshell-create-handles ,temp 'overwrite)))
                 (progn
                   (eshell-as-subcommand
                    ,(let ((eshell-current-quoted nil))
                       (eshell-parse-command cmd)))
                   (ignore
                    (nconc eshell-this-command-hook
                           ;; Quote this lambda; it will be evaluated
                           ;; by `eshell-do-eval', which requires very
                           ;; particular forms in order to work
                           ;; properly.  See bug#54190.
                           (list (function
                                  (lambda ()
                                    (delete-file ,temp)
                                    (when-let ((buffer (get-file-buffer ,temp)))
                                      (kill-buffer buffer)))))))
                   (eshell-apply-indices ,temp indices ,eshell-current-quoted)))
            (goto-char (1+ end)))))))
   ((eq (char-after) ?\()
    (condition-case nil
        `(eshell-apply-indices
          (eshell-command-to-value
           (eshell-lisp-command
            ',(read (or (eshell-unescape-inner-double-quote (point-max))
                        (current-buffer)))))
          indices ,eshell-current-quoted)
      (end-of-file
       (throw 'eshell-incomplete ?\())))
   ((looking-at (rx-to-string
                 `(or "'" ,(if eshell-current-quoted "\\\"" "\""))))
    (eshell-with-temp-command
        (or (eshell-unescape-inner-double-quote (point-max))
            (cons (point) (point-max)))
      (let ((name (if (eq (char-after) ?\')
                      (eshell-parse-literal-quote)
                    (eshell-parse-double-quote))))
        (when name
          `(eshell-get-variable ,(eval name) indices ,eshell-current-quoted)))))
   ((assoc (char-to-string (char-after))
           eshell-variable-aliases-list)
    (forward-char)
    `(eshell-get-variable ,(char-to-string (char-before)) indices
                          ,eshell-current-quoted))
   ((looking-at eshell-variable-name-regexp)
    (prog1
        `(eshell-get-variable ,(match-string 0) indices ,eshell-current-quoted)
      (goto-char (match-end 0))))
   (t
    (error "Invalid variable reference"))))