zsh-workers
 help / color / mirror / code / Atom feed
* 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-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-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-05-03  9:25 Completion in braces limitation Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
1999-04-28  7:19 Sven Wischnowsky
1999-04-28 16:43 ` Bart Schaefer
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).