zsh-workers
 help / color / mirror / code / Atom feed
* Re: Completion in braces limitation
@ 1999-04-28  7:19 Sven Wischnowsky
  1999-04-28 16:43 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Sven Wischnowsky @ 1999-04-28  7:19 UTC (permalink / raw)
  To: zsh-workers


Oliver Kiddle wrote:

> One thing which I did notice while testing a few things out with
> completion in braces is that it doesn't work quite as I'd like with
> things of the form $(...).
> Try:
> zsh -f
> sw() { echo /home/native_rs6000 }
> cd $(sw)/{<tab>
> 
> This expands $(sw) and quotes the brace. There may be a reason for doing
> this but I can't think of one.
> 
> Also (not using a brace), typing a bit more before the tab:
> cd $(sw)/tes<tab>
> will expand $(sw), leave '/tes' on the end and add a space. What would
> be nice is if it had completed to the 'test' directory which I have
> there. Back quotes behave in the same way.
> 
> Another way that $(...) is treated differently to a variable regards
> when zsh expands it:
> cd $PWD<tab> - expands the value of $PWD
> cd $PWD/<tab> - does not expand $PWD. I find this useful.
> cd $(sw)/<tab> - this will expand $(sw).

This is (again) intentional. To get rid of it, use complete-word
instead of expand-or-complete.
I vaguely remember a discussion about this (several years ago), where, 
if I remember correctly, most people said that one sometimes want to
complete after a parameter expansion, but almost never after a command 
substitution.
So, I'm reluctant to change this behavior (even more so, because it
would be a rather serious incompatibility).

The patch at least tries to make brace-handling after command
substitutions work, with $(...), that is, it may have problems with
braces inside backticks. But there are other constructs that are too
complicated for it anyway.

> Finally, I noticed this behaviour:
> 
> bindkey "^G" list-expand
> cd $PWD/<tab><^G><tab>
> This lists directories in $PWD after the first tab. I then listed the
> value of PWD with Ctrl-G, then wanting to go back to the list of
> directories, I pressed tab again. This started menu completion instead
> of returning to the list. I suppose I should remember to use Ctrl-D
> instead of tab again but if it's a simple change, it might be useful if
> things which overwrite the list (such as list-expand) revert things as
> if the original tab had not been pressed.

Hm. I wouldn't like it to completely ignore the current completion
state (you may be in a menucompletion and that shouldn't be
stopped). But the patch makes a completion list be displayed again if
it was displayed before one of the widgets showing another kind of
list was invoked.

Bye
 Sven

diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- os/Zle/zle_tricky.c	Tue Apr 27 18:11:30 1999
+++ Src/Zle/zle_tricky.c	Wed Apr 28 09:05:13 1999
@@ -87,6 +87,10 @@
 
 static int oldlist, oldins;
 
+/* Non-zero if we have to redisplay the list of matches. */
+
+static int showagain = 0;
+
 /* The match and group number to insert when starting menucompletion.   */
 
 static int insmnum, insgnum, insgroup;
@@ -758,6 +762,10 @@
     char *s, *ol;
     int olst = lst, chl = 0, ne = noerrs, ocs;
 
+    if (showagain && validlist)
+	showinglist = -2;
+    showagain = 0;
+
     /* If we are doing a menu-completion... */
 
     if (menucmp && lst != COMP_LIST_EXPAND && 
@@ -872,7 +880,7 @@
 	    }
 	    if (lst == COMP_EXPAND_COMPLETE)
 		do {
-		    /* check if there is a parameter expresiion. */
+		    /* Check if there is a parameter expression. */
 		    for (; *q && *q != String; q++);
 		    if (*q == String && q[1] != Inpar && q[1] != Inbrack) {
 			if (*++q == Inbrace) {
@@ -1519,9 +1527,11 @@
 		 * but this may fail sometimes. sorry.
 		 */
 		if (*p == String || *p == Qstring) {
-		    if (p[1] == Inbrace) {
+		    if (p[1] == Inbrace || p[1] == Inpar || p[1] == Inbrack) {
 			char *tp = p + 1;
-			if (skipparens(Inbrace, Outbrace, &tp)) {
+			if (skipparens(*tp, (*tp == Inbrace ? Outbrace :
+					     (*tp == Inpar ? Outpar : Outbrack)),
+				       &tp)) {
 			    tt = NULL;
 			    break;
 			}
@@ -1530,6 +1540,11 @@
 		    } else {
 			char *tp = p + 1;
 
+			for (; *tp == '^' || *tp == Hat ||
+				 *tp == '=' || *tp == Equals ||
+				 *tp == '~' || *tp == Tilde ||
+				 *tp == '#' || *tp == Pound || *tp == '+';
+			     tp++);
 			if (*tp == Quest || *tp == Star || *tp == String ||
 			    *tp == Qstring || *tp == '?' || *tp == '*' ||
 			    *tp == '$' || *tp == '-' || *tp == '!' ||
@@ -4175,6 +4190,7 @@
 				(unset(ALWAYSLASTPROMPT) && zmult != 1)) ?
 				"yes" : "");
 	movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1);
+	showinglist = 0;
 
 	/* Make sure we have the completion list and compctl. */
 	if (makecomplist(s, incmd, lst)) {
@@ -7546,6 +7562,9 @@
     struct cmgroup dg;
     Cmgroup am = amatches;
     int vl = validlist, sm = smatches;
+
+    if (listshown)
+	showagain = 1;
 
     smatches = 1;
     validlist = 1;

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


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

* Re: Completion in braces limitation
  1999-04-28  7:19 Completion in braces limitation Sven Wischnowsky
@ 1999-04-28 16:43 ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 1999-04-28 16:43 UTC (permalink / raw)
  To: zsh-workers

On Apr 28,  9:19am, Sven Wischnowsky wrote:
} Subject: Re: Completion in braces limitation
}
} > cd $(sw)/{<tab>
} > 
} > This expands $(sw) and quotes the brace. There may be a reason for doing
} > this but I can't think of one.
} 
} This is (again) intentional. To get rid of it, use complete-word
} instead of expand-or-complete.

Right; the "reason for it" is that you implicitly asked zsh to attempt
expansion before completion.

} I vaguely remember a discussion about this (several years ago), where, 
} if I remember correctly, most people said that one sometimes want to
} complete after a parameter expansion, but almost never after a command 
} substitution.

The problem with completing after a command substitution is that it has
to actually execute the command to figure out what to complete.  There's
no way to predict the side effects of executing the command multiple
times (at least twice -- once when completing and once when executing
the whole command line) so it's better to never start down the road.

Dunno if this is frequently-asked enough to be worthy of a FAQ entry ...

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* Re: Completion in braces limitation
@ 1999-05-03  9:25 Sven Wischnowsky
  0 siblings, 0 replies; 6+ messages in thread
From: Sven Wischnowsky @ 1999-05-03  9:25 UTC (permalink / raw)
  To: zsh-workers


Oliver Kiddle wrote:

> Another feature which would be useful is if completion of variables was
> extended to
> properly handle associative arrays. So for example, if I have an
> associative array named 'test',
> cd $test[<tab>
> would complete from the list of keys in $test.

The patch below should do this.

Bye
 Sven

diff -u oos/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- oos/Zle/zle_tricky.c	Mon May  3 11:21:43 1999
+++ Src/Zle/zle_tricky.c	Mon May  3 11:22:03 1999
@@ -578,6 +578,10 @@
 
 static int insubscr;
 
+/* Parameter pointer for completing keys of an assoc array. */
+
+static Param keypm;
+
 /* 1 if we are completing in a quoted string (or inside `...`) */
 
 /**/
@@ -1364,9 +1368,15 @@
 	    zsfree(varname);
 	    varname = ztrdup(tt);
 	    *s = sav;
-	    if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb)
-		s = NULL, inwhat = IN_MATH, insubscr = 1;
-	    else if (*s == '=' && cs > wb + (s - tt)) {
+	    if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb) {
+		s = NULL;
+		inwhat = IN_MATH;
+		if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
+		    (keypm->flags & PM_HASHED))
+		    insubscr = 2;
+		else
+		    insubscr = 1;
+	    } else if (*s == '=' && cs > wb + (s - tt)) {
 		s++;
 		wb += s - tt;
 		t0 = STRING;
@@ -1424,11 +1434,15 @@
 		    zsfree(varname);
 		    varname = ztrdup(nb);
 		    *ne = sav;
+		    if ((keypm = (Param) paramtab->getnode(paramtab,
+							   varname)) &&
+			(keypm->flags & PM_HASHED))
+			insubscr = 2;
 		}
 	    }
 	}
 	if (inwhat == IN_MATH) {
-	    if (compfunc) {
+	    if (compfunc || insubscr == 2) {
 		int lev;
 		char *p;
 
@@ -1472,7 +1486,11 @@
 		zsfree(varname);
 		varname = ztrdup((char *) line + i + 1);
 		line[wb - 1] = sav;
-		insubscr = 1;
+		if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
+		    (keypm->flags & PM_HASHED))
+		    insubscr = 2;
+		else
+		    insubscr = 1;
 	    }
 	}
 	/* This variable will hold the current word in quoted form. */
@@ -4829,13 +4847,22 @@
     char *s;
 
     ccont = CC_CCCONT;
+    cc_dummy.suffix = NULL;
 
     if (linwhat == IN_ENV) {
         /* Default completion for parameter values. */
         cc = &cc_default;
+	keypm = NULL;
     } else if (linwhat == IN_MATH) {
-        /* Parameter names inside mathematical expression. */
-        cc_dummy.mask = CC_PARAMS;
+	if (insubscr == 2) {
+	    /* Inside subscript of assoc array, complete keys. */
+	    cc_dummy.mask = 0;
+	    cc_dummy.suffix = "]";
+	} else {
+	    /* Other math environment, complete paramete names. */
+	    keypm = NULL;
+	    cc_dummy.mask = CC_PARAMS;
+	}
 	cc = &cc_dummy;
 	cc_dummy.refc = 10000;
     } else if (linwhat == IN_COND) {
@@ -4851,13 +4878,16 @@
 	    (CC_FILES | CC_PARAMS);
 	cc = &cc_dummy;
 	cc_dummy.refc = 10000;
-    } else if (linredir)
+	keypm = NULL;
+    } else if (linredir) {
 	/* In redirections use default completion. */
 	cc = &cc_default;
-    else
+	keypm = NULL;
+    } else {
 	/* Otherwise get the matches for the command. */
+	keypm = NULL;
 	return makecomplistcmd(os, incmd, flags);
-
+    }
     if (cc) {
 	/* First, use the -T compctl. */
 	if (!(flags & CFN_FIRST)) {
@@ -5971,7 +6001,12 @@
     if ((t = cc->mask & (CC_ALREG | CC_ALGLOB)))
 	/* Add the two types of aliases. */
 	dumphashtable(aliastab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
-
+    if (keypm && cc == &cc_dummy) {
+	/* Add the keys of the parameter in keypm. */
+	scanhashtable(keypm->gets.hfn(keypm), 0, 0, PM_UNSET, addhnmatch, 0);
+	keypm = NULL;
+	cc_dummy.suffix = NULL;
+    }
     if (!errflag && cc->ylist) {
 	/* generate the user-defined display list: if anything fails, *
 	 * we silently allow the normal completion list to be used.   */

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


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

* Re: Completion in braces limitation
  1999-04-27 13:37 Sven Wischnowsky
@ 1999-04-27 15:45 ` Oliver Kiddle
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Kiddle @ 1999-04-27 15:45 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

Sven Wischnowsky wrote:

> This was intentional, the completion gave up as soon as it found the `$'.
> The patch below makes it try a little harder by looking at what comes

> I would be thankful if someone (you?) could test this more thoroughly,
> though.

Brilliant. That seems to work well. I've tested it quite thoroughly but
will do some more testing of it later (when I'm not at work).
 
> Well, the new style completion can do this, of course...

I really ought to find some time to try this new completion.

One thing which I did notice while testing a few things out with
completion in braces is that it doesn't work quite as I'd like with
things of the form $(...).
Try:
zsh -f
sw() { echo /home/native_rs6000 }
cd $(sw)/{<tab>

This expands $(sw) and quotes the brace. There may be a reason for doing
this but I can't think of one.

Also (not using a brace), typing a bit more before the tab:
cd $(sw)/tes<tab>
will expand $(sw), leave '/tes' on the end and add a space. What would
be nice is if it had completed to the 'test' directory which I have
there. Back quotes behave in the same way.

Another way that $(...) is treated differently to a variable regards
when zsh expands it:
cd $PWD<tab> - expands the value of $PWD
cd $PWD/<tab> - does not expand $PWD. I find this useful.
cd $(sw)/<tab> - this will expand $(sw).

Finally, I noticed this behaviour:

bindkey "^G" list-expand
cd $PWD/<tab><^G><tab>
This lists directories in $PWD after the first tab. I then listed the
value of PWD with Ctrl-G, then wanting to go back to the list of
directories, I pressed tab again. This started menu completion instead
of returning to the list. I suppose I should remember to use Ctrl-D
instead of tab again but if it's a simple change, it might be useful if
things which overwrite the list (such as list-expand) revert things as
if the original tab had not been pressed.

Thanks

Oliver Kiddle


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

* Re: Completion in braces limitation
@ 1999-04-27 13:37 Sven Wischnowsky
  1999-04-27 15:45 ` Oliver Kiddle
  0 siblings, 1 reply; 6+ messages in thread
From: Sven Wischnowsky @ 1999-04-27 13:37 UTC (permalink / raw)
  To: zsh-workers


Oliver Kiddle wrote:

> Completion in braces doesn't seem to work in combination with variables:
> 
> zsh -f
> less $PWD/<tab>  - beep and lists files
> less $PWD/{<tab> - just beeps

This was intentional, the completion gave up as soon as it found the `$'.
The patch below makes it try a little harder by looking at what comes
after the `$'. If there is a complete parameter expansion and the
opening brace from the brace expansion comes after it, this should
work now.
I would be thankful if someone (you?) could test this more thoroughly, 
though.

> Another feature which would be useful is if completion of variables was
> extended to
> properly handle associative arrays. So for example, if I have an
> associative array named 'test',
> cd $test[<tab>
> would complete from the list of keys in $test.

Well, the new style completion can do this, of course...

And: I /think/ I already mentioned this some time ago (I knew someone
would say that he would like to have it). I don't remember exactly,
but I think I foresaw some problem there (mainly due to the code, I
think, not in what the user sees). There might be some ugly
interaction with normal subscripts...

So, no patch for this now. Sorry.

Bye
 Sven

diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- os/Zle/zle_tricky.c	Tue Apr 27 13:06:22 1999
+++ Src/Zle/zle_tricky.c	Tue Apr 27 15:29:04 1999
@@ -1515,12 +1515,46 @@
 	     */
 	    for (i = 0, p = s; *p; p++, i++) {
 		/* careful, ${... is not a brace expansion...
-		 * in fact, if it's got a substitution in it's too
-		 * hard for us anyway.  sorry.
+		 * we try to get braces after a parameter expansion right,
+		 * but this may fail sometimes. sorry.
 		 */
 		if (*p == String || *p == Qstring) {
-		    tt = NULL;
-		    break;
+		    if (p[1] == Inbrace) {
+			char *tp = p + 1;
+			if (skipparens(Inbrace, Outbrace, &tp)) {
+			    tt = NULL;
+			    break;
+			}
+			i += tp - p;
+			p = tp;
+		    } else {
+			char *tp = p + 1;
+
+			if (*tp == Quest || *tp == Star || *tp == String ||
+			    *tp == Qstring || *tp == '?' || *tp == '*' ||
+			    *tp == '$' || *tp == '-' || *tp == '!' ||
+			    *tp == '@')
+			    p++, i++;
+			else {
+			    if (idigit(*tp))
+				while (idigit(*tp))
+				    tp++;
+			    else if (iident(*tp))
+				while (iident(*tp))
+				    tp++;
+			    else {
+				tt = NULL;
+				break;
+			    }
+			    if (*tp == Inbrace) {
+				tt = NULL;
+				break;
+			    }
+			    tp--;
+			    i += tp - p;
+			    p = tp;
+			}
+		    }
 		} else if (*p == Inbrace) {
 		    if (tt) {
 			/* too many inbraces */

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


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

* Completion in braces limitation
@ 1999-04-27 12:56 Oliver Kiddle
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Kiddle @ 1999-04-27 12:56 UTC (permalink / raw)
  To: zsh-workers

Completion in braces doesn't seem to work in combination with variables:

zsh -f
less $PWD/<tab>  - beep and lists files
less $PWD/{<tab> - just beeps

Another feature which would be useful is if completion of variables was
extended to
properly handle associative arrays. So for example, if I have an
associative array named 'test',
cd $test[<tab>
would complete from the list of keys in $test.

Thanks

Oliver Kiddle


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

end of thread, other threads:[~1999-05-03  9:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-04-28  7:19 Completion in braces limitation Sven Wischnowsky
1999-04-28 16:43 ` Bart Schaefer
  -- strict thread matches above, loose matches on Subject: below --
1999-05-03  9:25 Sven Wischnowsky
1999-04-27 13:37 Sven Wischnowsky
1999-04-27 15:45 ` Oliver Kiddle
1999-04-27 12:56 Oliver Kiddle

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).