Return a list of numbers if all lines of an Eshell subcommand are numeric
* lisp/eshell/esh-util.el (eshell-convertible-to-number-p) (eshell-convert-to-number): New functions... (eshell-convert): ... use them. * test/lisp/eshell/esh-var-tests.el (esh-var-test/interp-convert-cmd-string-newline): Add checks for numeric output. * doc/misc/eshell.texi (Dollars Expansion): Document the new behavior. * etc/NEWS: Announce the change (bug#55236).
This commit is contained in:
parent
f7a82699d6
commit
06423b5d1e
4 changed files with 44 additions and 15 deletions
|
@ -1061,9 +1061,11 @@ when on its own, but the @code{$} allows it to be used inside double
|
|||
quotes or as part of a string.
|
||||
|
||||
Normally, the output is split line-by-line, returning a list (or the
|
||||
first element if there's only one line of output). However, when this
|
||||
expansion is surrounded by double quotes, it returns the output as a
|
||||
single string instead.
|
||||
first element if there's only one line of output); if
|
||||
@code{eshell-convert-numeric-arguments} is non-@code{nil} and every
|
||||
line of output looks like a number, convert each line to a number.
|
||||
However, when this expansion is surrounded by double quotes, it
|
||||
returns the output as a single string instead.
|
||||
|
||||
@item $<@var{command}>
|
||||
As with @samp{$@{@var{command}@}}, evaluates the Eshell command invocation
|
||||
|
|
7
etc/NEWS
7
etc/NEWS
|
@ -1396,6 +1396,13 @@ If an Eshell expansion like '$FOO' is surrounded by double quotes, the
|
|||
result will always be a single string, no matter the type that would
|
||||
otherwise be returned.
|
||||
|
||||
+++
|
||||
*** Eshell subcommands with multiline numeric output return lists of numbers.
|
||||
If every line of the output of an Eshell subcommand like '${COMMAND}'
|
||||
is numeric, the result will be a list of numbers (or a single number
|
||||
if only one line of output). Previously, this only converted numbers
|
||||
when there was a single line of output.
|
||||
|
||||
---
|
||||
*** Built-in Eshell commands now follow POSIX/GNU argument syntax conventions.
|
||||
Built-in commands in Eshell now accept command-line options with
|
||||
|
|
|
@ -198,6 +198,23 @@ doubling it up."
|
|||
(when (= depth 0)
|
||||
(if reverse-p (point) (1- (point)))))))
|
||||
|
||||
(defun eshell-convertible-to-number-p (string)
|
||||
"Return non-nil if STRING can be converted to a number.
|
||||
If `eshell-convert-numeric-aguments', always return nil."
|
||||
(and eshell-convert-numeric-arguments
|
||||
(string-match
|
||||
(concat "\\`\\s-*" eshell-number-regexp "\\s-*\\'")
|
||||
string)))
|
||||
|
||||
(defun eshell-convert-to-number (string)
|
||||
"Try to convert STRING to a number.
|
||||
If STRING doesn't look like a number (or
|
||||
`eshell-convert-numeric-aguments' is nil), just return STRING
|
||||
unchanged."
|
||||
(if (eshell-convertible-to-number-p string)
|
||||
(string-to-number string)
|
||||
string))
|
||||
|
||||
(defun eshell-convert (string &optional to-string)
|
||||
"Convert STRING into a more-native Lisp object.
|
||||
If TO-STRING is non-nil, always return a single string with
|
||||
|
@ -207,8 +224,8 @@ trailing newlines removed. Otherwise, this behaves as follows:
|
|||
|
||||
* Split multiline strings by line.
|
||||
|
||||
* If `eshell-convert-numeric-aguments' is non-nil, convert
|
||||
numeric strings to numbers."
|
||||
* If `eshell-convert-numeric-aguments' is non-nil and every line
|
||||
of output looks like a number, convert them to numbers."
|
||||
(cond
|
||||
((not (stringp string))
|
||||
(if to-string
|
||||
|
@ -220,15 +237,12 @@ trailing newlines removed. Otherwise, this behaves as follows:
|
|||
string
|
||||
(when (eq (aref string (1- len)) ?\n)
|
||||
(setq string (substring string 0 (1- len))))
|
||||
(cond
|
||||
((string-search "\n" string)
|
||||
(split-string string "\n"))
|
||||
((and eshell-convert-numeric-arguments
|
||||
(string-match
|
||||
(concat "\\`\\s-*" eshell-number-regexp "\\s-*\\'")
|
||||
string))
|
||||
(string-to-number string))
|
||||
(t string)))))))
|
||||
(if (string-search "\n" string)
|
||||
(let ((lines (split-string string "\n")))
|
||||
(if (seq-every-p #'eshell-convertible-to-number-p lines)
|
||||
(mapcar #'string-to-number lines)
|
||||
lines))
|
||||
(eshell-convert-to-number string)))))))
|
||||
|
||||
(defvar-local eshell-path-env (getenv "PATH")
|
||||
"Content of $PATH.
|
||||
|
|
|
@ -366,7 +366,13 @@ inside double-quotes"
|
|||
(ert-deftest esh-var-test/interp-convert-cmd-multiline ()
|
||||
"Interpolate multi-line command result"
|
||||
(should (equal (eshell-test-command-result "echo ${echo \"foo\nbar\"}")
|
||||
'("foo" "bar"))))
|
||||
'("foo" "bar")))
|
||||
;; Numeric output should be converted to numbers...
|
||||
(should (equal (eshell-test-command-result "echo ${echo \"01\n02\n03\"}")
|
||||
'(1 2 3)))
|
||||
;; ... but only if every line is numeric.
|
||||
(should (equal (eshell-test-command-result "echo ${echo \"01\n02\nhi\"}")
|
||||
'("01" "02" "hi"))))
|
||||
|
||||
(ert-deftest esh-var-test/interp-convert-cmd-number ()
|
||||
"Interpolate numeric command result"
|
||||
|
|
Loading…
Add table
Reference in a new issue