Add a new function 'shell-split-string'

* doc/lispref/processes.texi (Shell Arguments): Document it.
* lisp/shell.el (shell-split-string): New function.
This commit is contained in:
Lars Ingebrigtsen 2021-07-15 10:25:41 +02:00
parent d4217b38d7
commit 4fb6cf3f38
4 changed files with 38 additions and 0 deletions

View file

@ -247,6 +247,16 @@ protected by @code{shell-quote-argument};
@code{combine-and-quote-strings} is @emph{not} intended to protect
special characters from shell evaluation.
@defun shell-split-string string
This function splits @var{string} into substrings, respecting double
and single quotes, as well as backslash quoting.
@smallexample
(shell-split-string "ls /tmp/'foo bar'")
@result{} ("ls" "/tmp/foo bar")
@end smallexample
@end defun
@defun split-string-and-unquote string &optional separators
This function splits @var{string} into substrings at matches for the
regular expression @var{separators}, like @code{split-string} does

View file

@ -2970,6 +2970,11 @@ The former is now declared obsolete.
* Lisp Changes in Emacs 28.1
+++
*** New function 'shell-split-string'.
This splits a shell string into separate components, respecting single
and double quotes, as well as backslash quoting.
---
*** ':safe' settings in 'defcustom' are now propagated to the loaddefs files.

View file

@ -459,6 +459,15 @@ Useful for shells like zsh that has this feature."
(push (mapconcat #'identity (nreverse arg) "") args)))
(cons (nreverse args) (nreverse begins)))))
(defun shell-split-string (string)
"Split STRING (a shell command) into a list of strings.
General shell syntax, like single and double quoting, as well as
backslash quoting, is respected."
(with-temp-buffer
(insert string)
(let ((comint-file-name-quote-list shell-file-name-quote-list))
(car (shell--parse-pcomplete-arguments)))))
(defun shell-command-completion-function ()
"Completion function for shell command names.
This is the value of `pcomplete-command-completion-function' for

View file

@ -45,4 +45,18 @@
(should (equal (shell--parse-pcomplete-arguments)
'(("cd" "ba" "") 1 4 7)))))
(ert-deftest shell-tests-split-string ()
(should (equal (shell-split-string "ls /tmp")
'("ls" "/tmp")))
(should (equal (shell-split-string "ls '/tmp/foo bar'")
'("ls" "/tmp/foo bar")))
(should (equal (shell-split-string "ls \"/tmp/foo bar\"")
'("ls" "/tmp/foo bar")))
(should (equal (shell-split-string "ls /tmp/'foo bar'")
'("ls" "/tmp/foo bar")))
(should (equal (shell-split-string "ls /tmp/'foo\\ bar'")
'("ls" "/tmp/foo\\ bar")))
(should (equal (shell-split-string "ls /tmp/foo\\ bar")
'("ls" "/tmp/foo bar"))))
;;; shell-tests.el ends here