Skip to content

Commit 4fb6cf3

Browse files
committed
Add a new function 'shell-split-string'
* doc/lispref/processes.texi (Shell Arguments): Document it. * lisp/shell.el (shell-split-string): New function.
1 parent d4217b3 commit 4fb6cf3

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

doc/lispref/processes.texi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,16 @@ protected by @code{shell-quote-argument};
247247
@code{combine-and-quote-strings} is @emph{not} intended to protect
248248
special characters from shell evaluation.
249249

250+
@defun shell-split-string string
251+
This function splits @var{string} into substrings, respecting double
252+
and single quotes, as well as backslash quoting.
253+
254+
@smallexample
255+
(shell-split-string "ls /tmp/'foo bar'")
256+
@result{} ("ls" "/tmp/foo bar")
257+
@end smallexample
258+
@end defun
259+
250260
@defun split-string-and-unquote string &optional separators
251261
This function splits @var{string} into substrings at matches for the
252262
regular expression @var{separators}, like @code{split-string} does

etc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,6 +2970,11 @@ The former is now declared obsolete.
29702970

29712971
* Lisp Changes in Emacs 28.1
29722972

2973+
+++
2974+
*** New function 'shell-split-string'.
2975+
This splits a shell string into separate components, respecting single
2976+
and double quotes, as well as backslash quoting.
2977+
29732978
---
29742979
*** ':safe' settings in 'defcustom' are now propagated to the loaddefs files.
29752980

lisp/shell.el

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,15 @@ Useful for shells like zsh that has this feature."
459459
(push (mapconcat #'identity (nreverse arg) "") args)))
460460
(cons (nreverse args) (nreverse begins)))))
461461

462+
(defun shell-split-string (string)
463+
"Split STRING (a shell command) into a list of strings.
464+
General shell syntax, like single and double quoting, as well as
465+
backslash quoting, is respected."
466+
(with-temp-buffer
467+
(insert string)
468+
(let ((comint-file-name-quote-list shell-file-name-quote-list))
469+
(car (shell--parse-pcomplete-arguments)))))
470+
462471
(defun shell-command-completion-function ()
463472
"Completion function for shell command names.
464473
This is the value of `pcomplete-command-completion-function' for

test/lisp/shell-tests.el

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,18 @@
4545
(should (equal (shell--parse-pcomplete-arguments)
4646
'(("cd" "ba" "") 1 4 7)))))
4747

48+
(ert-deftest shell-tests-split-string ()
49+
(should (equal (shell-split-string "ls /tmp")
50+
'("ls" "/tmp")))
51+
(should (equal (shell-split-string "ls '/tmp/foo bar'")
52+
'("ls" "/tmp/foo bar")))
53+
(should (equal (shell-split-string "ls \"/tmp/foo bar\"")
54+
'("ls" "/tmp/foo bar")))
55+
(should (equal (shell-split-string "ls /tmp/'foo bar'")
56+
'("ls" "/tmp/foo bar")))
57+
(should (equal (shell-split-string "ls /tmp/'foo\\ bar'")
58+
'("ls" "/tmp/foo\\ bar")))
59+
(should (equal (shell-split-string "ls /tmp/foo\\ bar")
60+
'("ls" "/tmp/foo bar"))))
61+
4862
;;; shell-tests.el ends here

0 commit comments

Comments
 (0)