zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)
@ 2000-05-03 12:20 Sven Wischnowsky
  2000-05-03 12:38 ` Andrej Borsenkow
  2000-05-03 12:54 ` Peter Stephenson
  0 siblings, 2 replies; 5+ messages in thread
From: Sven Wischnowsky @ 2000-05-03 12:20 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On May 3,  9:16am, Sven Wischnowsky wrote:
> } Subject: Re: Shell-word splitting (was: Re: Proposed _history completer)
> }
> } > Bart Schaefer wrote:
> } > 
> } > > Hrm, again; maybe the way to do this is with a modifier rather than a
> } > > flag.  :S is available, and it'd be kinda fun to be able to apply this
> } > > to history as well as to parameters.  Or maybe it wouldn't ...
> } 
> } I should have thought more about this yesterday...
> 
> So should I, apparently.
> 
> } Erm, the history modifier code only ever works on single words
> 
> Right.  Ah, well.  I still think a modifier might be less confusing than
> a flag, particularly if we have to use a character like `=' for the flag,
> but ...

I still agree that :S would be nice, but even in parameter expansions
do the modifiers work only per-element. In the code, too, and that's
what held me back. But enough people start shouting at me, I'll modify
modify() to allow it to return an array and so on...


Anyway, here's the patch, implementing the (z) flag which makes the
parameter value be zplitted uzing zsh zhell zyntax. This works a bit
like the (s) flag (or the `=' before the name) and is done at the very
end, so to access words resulting from the splitting:

  % foo='it says: "hello world"'
  % echo ${${(z)foo}[3]}
  "hello world"

We could probably move the code that does the splitting up somewhere
but it would then behave more differently from (s) and = than it does
now, so that would probably be a bad idea.


Most of the hunks have to do with bufferwords() which now can get the
string to split as an argument.

Bye
 Sven

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.7
diff -u -r1.7 expn.yo
--- Doc/Zsh/expn.yo	2000/04/17 10:57:48	1.7
+++ Doc/Zsh/expn.yo	2000/05/03 12:18:48
@@ -676,6 +676,10 @@
 Split the result of the expansion to lines. This is a shorthand
 for `tt(ps:\n:)'.
 )
+item(tt(z))(
+Split the result of the expansion into words using shell parsing to
+find the words, i.e. taking into account any quoting in the value.
+)
 item(tt(t))(
 Use a string describing the type of the parameter where the value
 of the parameter would usually appear. This string consists of keywords
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.2
diff -u -r1.2 hist.c
--- Src/hist.c	2000/04/12 08:24:16	1.2
+++ Src/hist.c	2000/05/03 12:18:48
@@ -2037,17 +2037,28 @@
 
 /**/
 mod_export LinkList
-bufferwords(int *index)
+bufferwords(LinkList list, char *buf, int *index)
 {
-    LinkList list = newlinklist();
     int num = 0, cur = -1, got = 0, ne = noerrs, ocs = cs;
     char *p;
 
+    if (!list)
+	list = newlinklist();
+
     zleparse = 1;
     addedx = 0;
     noerrs = 1;
     lexsave();
-    if (!isfirstln && chline) {
+    if (buf) {
+	int l = strlen(buf);
+
+	p = (char *) zhalloc(l + 2);
+	memcpy(p, buf, l);
+	p[l] = ' ';
+	p[l + 1] = '\0';
+	inpush(p, 0, NULL);
+	cs = 0;
+    } else if (!isfirstln && chline) {
 	p = (char *) zhalloc(hptr - chline + ll + 2);
 	memcpy(p, chline, hptr - chline);
 	memcpy(p + (hptr - chline), line, ll);
@@ -2074,6 +2085,17 @@
 	    untokenize((p = dupstring(tokstr)));
 	    addlinknode(list, p);
 	    num++;
+	} else if (buf) {
+	    if (IS_REDIROP(tok) && tokfd >= 0) {
+		char b[20];
+
+		sprintf(b, "%d%s", tokfd, tokstrings[tok]);
+		addlinknode(list, dupstring(b));
+		num++;
+	    } else if (tok != NEWLIN) {
+		addlinknode(list, dupstring(tokstrings[tok]));
+		num++;
+	    }
 	}
 	if (!got && !zleparse) {
 	    got = 1;
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.2
diff -u -r1.2 subst.c
--- Src/subst.c	2000/04/06 18:44:01	1.2
+++ Src/subst.c	2000/05/03 12:18:49
@@ -750,6 +750,7 @@
     int casmod = 0;
     int quotemod = 0, quotetype = 0, quoteerr = 0;
     int visiblemod = 0;
+    int shsplit = 0;
     char *sep = NULL, *spsep = NULL;
     char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
     char *replstr = NULL;	/* replacement string for /orig/repl */
@@ -971,6 +972,10 @@
 		    presc++;
 		    break;
 
+		case 'z':
+		    shsplit = 1;
+		    break;
+
 		default:
 		  flagerr:
 		    zerr("error in flags", NULL, 0);
@@ -1747,6 +1752,34 @@
 		val = dupstring(val), copied = 1;
 	    val = nicedupstring(val);
 	}
+    }
+    if (shsplit) {
+	LinkList list = NULL;
+
+	if (isarr) {
+	    char **ap;
+	    for (ap = aval; *ap; ap++)
+		list = bufferwords(list, *ap, NULL);
+	    isarr = 0;
+	} else
+	    list = bufferwords(NULL, val, NULL);
+
+	if (!firstnode(list))
+	    val = dupstring("");
+	else if (!nextnode(firstnode(list)))
+	    val = getdata(firstnode(list));
+	else {
+	    char **ap;
+	    LinkNode node;
+
+	    aval = ap = (char **) zhalloc((countlinknodes(list) + 1) *
+					  sizeof(char *));
+	    for (node = firstnode(list); node; incnode(node))
+		*ap++ = (char *) getdata(node);
+	    *ap = NULL;
+	    mult_isarr = isarr = 2;
+	}
+	copied = 1;
     }
     if (isarr) {
 	char *x;
Index: Src/Modules/parameter.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v
retrieving revision 1.4
diff -u -r1.4 parameter.c
--- Src/Modules/parameter.c	2000/04/12 08:24:16	1.4
+++ Src/Modules/parameter.c	2000/05/03 12:18:49
@@ -1098,7 +1098,7 @@
     int i = addhistnum(curhist, -1, HIST_FOREIGN), iw;
     Histent he = quietgethistent(i, GETHIST_UPWARD);
 
-    ll = bufferwords(NULL);
+    ll = bufferwords(NULL, NULL, NULL);
     for (n = firstnode(ll); n; incnode(n))
 	pushnode(l, getdata(n));
 
Index: Src/Zle/zle_misc.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v
retrieving revision 1.2
diff -u -r1.2 zle_misc.c
--- Src/Zle/zle_misc.c	2000/04/12 08:24:16	1.2
+++ Src/Zle/zle_misc.c	2000/05/03 12:18:50
@@ -549,7 +549,7 @@
     int i;
     char *p = NULL;
 
-    l = bufferwords(&i);
+    l = bufferwords(NULL, NULL, &i);
 
     for (n = firstnode(l); n; incnode(n))
 	if (!i--) {

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

* RE: PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)
  2000-05-03 12:20 PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer) Sven Wischnowsky
@ 2000-05-03 12:38 ` Andrej Borsenkow
  2000-05-03 12:54 ` Peter Stephenson
  1 sibling, 0 replies; 5+ messages in thread
From: Andrej Borsenkow @ 2000-05-03 12:38 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

>
> Anyway, here's the patch, implementing the (z) flag which makes the
> parameter value be zplitted uzing zsh zhell zyntax. This works a bit
> like the (s) flag (or the `=' before the name) and is done at the very
> end, so to access words resulting from the splitting:
>

Why is it so similar ... is it not the same as was implemented for
copy-prev-shell-word? I mean, in this case c-p-s-w may well be
implemented as pure shell-level widget ... may be, it is not worth it
now ...

The only problem is, what happens if current line is incomplete? That
is, is this modifier useful in widgets that deal with current line?
Suppose, we have something like ``echo "foo '' - what will be the result
of (z) modifier?

-andrej


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

* Re: PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)
  2000-05-03 12:20 PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer) Sven Wischnowsky
  2000-05-03 12:38 ` Andrej Borsenkow
@ 2000-05-03 12:54 ` Peter Stephenson
  1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2000-05-03 12:54 UTC (permalink / raw)
  To: Zsh hackers list

> Anyway, here's the patch, implementing the (z) flag which makes the
> parameter value be zplitted uzing zsh zhell zyntax. This works a bit
> like the (s) flag (or the `=' before the name) and is done at the very
> end, so to access words resulting from the splitting:
> 
>   % foo='it says: "hello world"'
>   % echo ${${(z)foo}[3]}
>   "hello world"
> 
> We could probably move the code that does the splitting up somewhere
> but it would then behave more differently from (s) and = than it does
> now, so that would probably be a bad idea.

This is probably right, but it could do with mentioning explicitly,
including in the rules for parameter substitution, otherwise it's a little
non-obvious that you can't do e.g. ${(Qz)foo} to get rid of the quotes.
You can do ${(Q)${(z)foo}}, so it's no problem as long as you know about
it.

-- 
Peter Stephenson <pws@cambridgesiliconradio.com>
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


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

* Re: PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)
  2000-05-03 13:03 Sven Wischnowsky
@ 2000-05-03 15:06 ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2000-05-03 15:06 UTC (permalink / raw)
  To: Zsh hackers list

> Index: Doc/Zsh/expn.yo
> +Note that this is done very lately, as for the `tt((s))' flag. So to
> +access single words in the result, one has to use nested expansions as 
> +in `tt(${${(z)foo}[2]}'.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.9
diff -u -r1.9 expn.yo
--- Doc/Zsh/expn.yo     2000/05/03 13:05:40     1.9
+++ Doc/Zsh/expn.yo     2000/05/03 15:05:06
@@ -680,9 +680,9 @@
 Split the result of the expansion into words using shell parsing to
 find the words, i.e. taking into account any quoting in the value.
 
-Note that this is done very lately, as for the `tt((s))' flag. So to
+Note that this is done very late, as for the `tt((s))' flag. So to
 access single words in the result, one has to use nested expansions as 
-in `tt(${${(z)foo}[2]}'. Likewise, to remove the quotes in the
+in `tt(${${(z)foo}[2]})'. Likewise, to remove the quotes in the
 resulting words one would do: `tt(${(Q)${(z)foo}})'.
 )
 item(tt(t))(

-- 
Peter Stephenson <pws@cambridgesiliconradio.com>
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


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

* RE: PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)
@ 2000-05-03 13:03 Sven Wischnowsky
  2000-05-03 15:06 ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Sven Wischnowsky @ 2000-05-03 13:03 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> > Anyway, here's the patch, implementing the (z) flag which makes the
> > parameter value be zplitted uzing zsh zhell zyntax. This works a bit
> > like the (s) flag (or the `=' before the name) and is done at the very
> > end, so to access words resulting from the splitting:
> 
> Why is it so similar ... is it not the same as was implemented for
> copy-prev-shell-word? I mean, in this case c-p-s-w may well be
> implemented as pure shell-level widget ... may be, it is not worth it
> now ...

For c-p-s-w bufferwords() does a bit more and a bit less. It also
reports the word the cursor is on (so that we can find the previous
word), but it doesn't add simple words like the special tokens (`;',
`&&' etc.).

> The only problem is, what happens if current line is incomplete? That
> is, is this modifier useful in widgets that deal with current line?
> Suppose, we have something like ``echo "foo '' - what will be the result
> of (z) modifier?

[hand hits forehead]

I had forgotten about this. It now includes the partial word in such a 
case. Different from c-p-s-w.


Peter Stephenson wrote:

> > Anyway, here's the patch, implementing the (z) flag which makes the
> > parameter value be zplitted uzing zsh zhell zyntax. This works a bit
> > like the (s) flag (or the `=' before the name) and is done at the very
> > end, so to access words resulting from the splitting:
> > 
> >   % foo='it says: "hello world"'
> >   % echo ${${(z)foo}[3]}
> >   "hello world"
> > 
> > We could probably move the code that does the splitting up somewhere
> > but it would then behave more differently from (s) and = than it does
> > now, so that would probably be a bad idea.
> 
> This is probably right, but it could do with mentioning explicitly,
> including in the rules for parameter substitution, otherwise it's a little
> non-obvious that you can't do e.g. ${(Qz)foo} to get rid of the quotes.
> You can do ${(Q)${(z)foo}}, so it's no problem as long as you know about
> it.

Ok.

Bye
 Sven

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.8
diff -u -r1.8 expn.yo
--- Doc/Zsh/expn.yo	2000/05/03 12:21:56	1.8
+++ Doc/Zsh/expn.yo	2000/05/03 13:03:02
@@ -679,6 +679,11 @@
 item(tt(z))(
 Split the result of the expansion into words using shell parsing to
 find the words, i.e. taking into account any quoting in the value.
+
+Note that this is done very lately, as for the `tt((s))' flag. So to
+access single words in the result, one has to use nested expansions as 
+in `tt(${${(z)foo}[2]}'. Likewise, to remove the quotes in the
+resulting words one would do: `tt(${(Q)${(z)foo}})'.
 )
 item(tt(t))(
 Use a string describing the type of the parameter where the value
@@ -839,7 +844,7 @@
 manner.
 )
 item(tt(8.) em(Forced Splitting))(
-If one of the `tt((s))' or `tt((f))' flags are present, or the `tt(=)'
+If one of the `tt((s))', `tt((f))' or `tt((z))' flags are present, or the `tt(=)'
 specifier was present (e.g. tt(${=)var(var)tt(})), the word is split on
 occurrences of the specified string, or (for tt(=) with neither of the two
 flags present) any of the characters in tt($IFS).
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.3
diff -u -r1.3 hist.c
--- Src/hist.c	2000/05/03 12:21:56	1.3
+++ Src/hist.c	2000/05/03 13:03:02
@@ -2102,6 +2102,11 @@
 	    cur = num - 1;
 	}
     } while (tok != ENDINPUT && tok != LEXERR);
+    if (buf && tok == LEXERR && tokstr && *tokstr) {
+	untokenize((p = dupstring(tokstr)));
+	addlinknode(list, p);
+	num++;
+    }
     if (cur < 0 && num)
 	cur = num - 1;
     noaliases = 0;

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


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

end of thread, other threads:[~2000-05-03 15:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-03 12:20 PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer) Sven Wischnowsky
2000-05-03 12:38 ` Andrej Borsenkow
2000-05-03 12:54 ` Peter Stephenson
2000-05-03 13:03 Sven Wischnowsky
2000-05-03 15:06 ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

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 NNTP newsgroup(s).