]> git.eshelyaron.com Git - emacs.git/commitdiff
Add a new function 'shell-split-string'
authorLars Ingebrigtsen <larsi@gnus.org>
Thu, 15 Jul 2021 08:25:41 +0000 (10:25 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Thu, 15 Jul 2021 08:25:41 +0000 (10:25 +0200)
* doc/lispref/processes.texi (Shell Arguments): Document it.
* lisp/shell.el (shell-split-string): New function.

doc/lispref/processes.texi
etc/NEWS
lisp/shell.el
test/lisp/shell-tests.el

index 0dfdac71479e6d727af7040a5a29ec2afbadb32a..c8e9f0cea6e21b0c669a77e7df481afcfd8adf67 100644 (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
index 555b465e84b7fcedff6403fe1129f2b733763928..29c2d9db73f3c44e5d8be880d02097cd4424e16c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2970,6 +2970,11 @@ The former is now declared obsolete.
 \f
 * 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.
 
index 4339e8c0a3b9278f882654cda745f89b446bfc78..15783bb924629af533a724d5acc57eeaaaac6853 100644 (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
index d918de771b7c393ccd0b143b392df11f26fb06c1..ad54644e55684abcaba8f8905bba9eb96f795e1c 100644 (file)
     (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