unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Split string into shell words?
@ 2004-01-20 16:56 Kai Grossjohann
  2004-01-20 18:04 ` Stefan Monnier
  2004-01-20 23:19 ` Kevin Rodgers
  0 siblings, 2 replies; 5+ messages in thread
From: Kai Grossjohann @ 2004-01-20 16:56 UTC (permalink / raw)


Given a string as in the following line:

        foo "a b" 'c d' e\ f bar

I'd like a function that returns the following list:

        ("foo" "a b" "c d" "e f" "bar")

That is, the string should be split into words like a shell would
split it into words.

I thought there must be a function in comint*.el or shell*.el
somewhere, but couldn't find it.  Probably I'm blind.

Kai

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Split string into shell words?
  2004-01-20 16:56 Split string into shell words? Kai Grossjohann
@ 2004-01-20 18:04 ` Stefan Monnier
  2004-01-28  8:37   ` Kai Grossjohann
  2004-01-20 23:19 ` Kevin Rodgers
  1 sibling, 1 reply; 5+ messages in thread
From: Stefan Monnier @ 2004-01-20 18:04 UTC (permalink / raw)


> Given a string as in the following line:
>         foo "a b" 'c d' e\ f bar

> I'd like a function that returns the following list:

>         ("foo" "a b" "c d" "e f" "bar")

> That is, the string should be split into words like a shell would
> split it into words.

> I thought there must be a function in comint*.el or shell*.el
> somewhere, but couldn't find it.  Probably I'm blind.

It's pretty nasty to do it right:

  foo "bar $(baz "toto") titi"

should turn into "foo" "bar $(baz \"toto\") titi".
What do you need this for ?


        Stefan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Split string into shell words?
  2004-01-20 16:56 Split string into shell words? Kai Grossjohann
  2004-01-20 18:04 ` Stefan Monnier
@ 2004-01-20 23:19 ` Kevin Rodgers
  2004-01-20 23:47   ` Stefan Monnier
  1 sibling, 1 reply; 5+ messages in thread
From: Kevin Rodgers @ 2004-01-20 23:19 UTC (permalink / raw)


Kai Grossjohann wrote:

> Given a string as in the following line:
> 
>         foo "a b" 'c d' e\ f bar
> 
> I'd like a function that returns the following list:
> 
>         ("foo" "a b" "c d" "e f" "bar")
> 
> That is, the string should be split into words like a shell would
> split it into words.


As Stefan points out, this is hard because of things like command substitution.


> I thought there must be a function in comint*.el or shell*.el
> somewhere, but couldn't find it.  Probably I'm blind.

Shell Mode's completion mechanism seems to just ignore quoting.  E.g.

if you've typed

	cat /dev/nul""

on the command line, TAB doesn't complete it to

	cat /dev/nul""l


and it reports "No completions of /dev/nul\" for both

	cat /dev/nul\
and
	cat /dev/nul\\

Here's what I tried in the *scratch* buffer for your example, to see if the
Emacs Lisp reader could do most of the work:

(setq string "foo \"a b\" 'c d' e\\ f bar")
"foo \"a b\" 'c d' e\\ f bar"

;; Everything looks good:
(read-from-string string)
(foo . 3)

(read-from-string string 3)
("a b" . 9)

;; Until this:
(read-from-string string 9)
((quote c) . 12)

(read-from-string string 12)
(d . 14)

;; And now things are OK again:
(read-from-string string 14)
((quote e\ f) . 20)

(read-from-string string 20)
(bar . 24)

It might be nice if the 'form -> (quote form) implementation in
src/lread.c:read1() could be customized (e.g. by temporarily making the
single quote behave like a double quote), but Emacs Lisp doesn't have
the notion of reader macros and its semantics are hard-coded:

     case '\'':
       {
	return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
       }

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Split string into shell words?
  2004-01-20 23:19 ` Kevin Rodgers
@ 2004-01-20 23:47   ` Stefan Monnier
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Monnier @ 2004-01-20 23:47 UTC (permalink / raw)


> Shell Mode's completion mechanism seems to just ignore quoting.  E.g.

And I've found it convenient at times when typing things like

  foo "/a/b /a/c /a/d"

although I must admit being stumped as to what that `foo' command was that
required such a funny list of filenames.


        Stefan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Split string into shell words?
  2004-01-20 18:04 ` Stefan Monnier
@ 2004-01-28  8:37   ` Kai Grossjohann
  0 siblings, 0 replies; 5+ messages in thread
From: Kai Grossjohann @ 2004-01-28  8:37 UTC (permalink / raw)


Stefan Monnier <monnier@iro.umontreal.ca> writes:

> It's pretty nasty to do it right:
>
>   foo "bar $(baz "toto") titi"
>
> should turn into "foo" "bar $(baz \"toto\") titi".
> What do you need this for ?

I want to make it so that typing "vi foo" at the shell prompt (as in
M-x shell) does like C-x C-f foo RET.  Thus, I wrote
shell-integration.el (posted to gnu.emacs.sources).

The mode looks whether it knows the command typed as the first word on
the line and then invokes a lisp function, if so.  I thought it would
be good if that lisp function received a list of arguments.

That's why I wanted to split the current command line into words.

Now I have used the following workaround: each such lisp function
receives only a single string as its arg, which is the whole command
line.  The lisp functions then (normally) use the comint-arguments
function to extract the words they need.

Hm.  It seems that my approach was too simple-minded, as I can't say
"vi $(uname)" -- this will try to edit a file called "$(uname)" rather
than editing a file called "Linux".  So I guess I need to pass the
command to the shell for expansion first, then pass the result to the
Lisp function.

Kai

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-01-28  8:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-20 16:56 Split string into shell words? Kai Grossjohann
2004-01-20 18:04 ` Stefan Monnier
2004-01-28  8:37   ` Kai Grossjohann
2004-01-20 23:19 ` Kevin Rodgers
2004-01-20 23:47   ` Stefan Monnier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).