zsh-workers
 help / color / mirror / code / Atom feed
* Completion weirdity after `for'
@ 1999-01-18 17:20 Peter Stephenson
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Stephenson @ 1999-01-18 17:20 UTC (permalink / raw)
  To: Zsh hackers list

After

for f in <TAB>

completion takes place as if the command name is `in', not `for'.
This showed up because I have a function called `in' such that `in dir
cmdlist' executes cmdlist in directory dir, so I have the first word
after `in' complete directories, which is not what is wanted here.

The natural way to handle this would be such that everything up to and
including the list were treated as words of a fictitious `for'
command, so e.g. you can specify special behaviour for arguments 1 and
2 and default for the rest.  This is possible to fix, but like most
things to do with get_comp_string() the fix could be a little ad hoc.
Maybe other reserved words need some fix-up, but for and foreach are
the worst offenders since others tend to be followed by a specific
command which then works in the expected way.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


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

* Re:  Completion weirdity after `for'
@ 1999-01-20 11:12 Sven Wischnowsky
  0 siblings, 0 replies; 2+ messages in thread
From: Sven Wischnowsky @ 1999-01-20 11:12 UTC (permalink / raw)
  To: zsh-workers


Peter Stephenson wrote:

> 
> After
> 
> for f in <TAB>
> 
> completion takes place as if the command name is `in', not `for'.
> This showed up because I have a function called `in' such that `in dir
> cmdlist' executes cmdlist in directory dir, so I have the first word
> after `in' complete directories, which is not what is wanted here.
> 
> The natural way to handle this would be such that everything up to and
> including the list were treated as words of a fictitious `for'
> command, so e.g. you can specify special behaviour for arguments 1 and
> 2 and default for the rest.  This is possible to fix, but like most
> things to do with get_comp_string() the fix could be a little ad hoc.
> Maybe other reserved words need some fix-up, but for and foreach are
> the worst offenders since others tend to be followed by a specific
> command which then works in the expected way.

The patch below is my attempt at this. With it you can define things
like:

  compctl -v -x 'p[2]' -k '(in)' - 'p[3,-1]' -f -- for

(or whatever you like to complete).

This is done for `for', `foreach', `select', `repeat', and `case'. The 
thing for `repeat' was a bi more complicated to make completion after
`repeat x ' and after `repeat x do' work. For `case' I haven't done
any special handling yet, so this still fails utterly (try completion
after a pattern, you'll get default completion, not command
completion). Due to the way the lexer reports things for the `case'
construct making this work right may get a bit more complicated
(though I have the feeling that we should make this work, too, so I
may come back to this).

Anyway, I would like to hear about any problems you encounter with
patch...

Bye
 Sven

*** os/Zle/zle_tricky.c	Wed Jan 20 09:09:56 1999
--- Src/Zle/zle_tricky.c	Wed Jan 20 12:01:43 1999
***************
*** 890,896 ****
  static char *
  get_comp_string(void)
  {
!     int t0, tt0, i, j, k, cp, rd, sl, ocs;
      char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
  
      zsfree(brbeg);
--- 890,896 ----
  static char *
  get_comp_string(void)
  {
!     int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins;
      char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
  
      zsfree(brbeg);
***************
*** 950,956 ****
  	inpush(dupstrspace((char *) linptr), 0, NULL);
  	strinbeg();
  	stophist = 2;
! 	i = tt0 = cp = rd = 0;
  
  	/* This loop is possibly the wrong way to do this.  It goes through *
  	 * the previously massaged command line using the lexer.  It stores *
--- 950,956 ----
  	inpush(dupstrspace((char *) linptr), 0, NULL);
  	strinbeg();
  	stophist = 2;
! 	i = tt0 = cp = rd = ins = oins = 0;
  
  	/* This loop is possibly the wrong way to do this.  It goes through *
  	 * the previously massaged command line using the lexer.  It stores *
***************
*** 964,971 ****
  	 * this would be to pass the command line through the parser too,   *
  	 * and get the arguments that way.  Maybe in 3.1...                 */
  	do {
! 	    lincmd = incmdpos;
! 	    linredir = inredir;
  	    /* Get the next token. */
  	    ctxtlex();
  	    if (tok == DINPAR)
--- 964,973 ----
  	 * this would be to pass the command line through the parser too,   *
  	 * and get the arguments that way.  Maybe in 3.1...                 */
  	do {
! 	    lincmd = ((incmdpos && !ins) || (oins == 2 && i == 2) ||
! 		      (ins == 3 && i == 1));
! 	    linredir = (inredir && !ins);
! 	    oins = ins;
  	    /* Get the next token. */
  	    ctxtlex();
  	    if (tok == DINPAR)
***************
*** 974,980 ****
  	    /* We reached the end. */
  	    if (tok == ENDINPUT)
  		break;
! 	    if (tok == BAR    || tok == AMPER     ||
  		tok == BARAMP || tok == AMPERBANG ||
  		((tok == DBAR || tok == DAMPER) && !incond)) {
  		/* This is one of the things that separate commands.  If we  *
--- 976,984 ----
  	    /* We reached the end. */
  	    if (tok == ENDINPUT)
  		break;
! 	    if ((ins && (tok == DO || tok == SEPER)) ||
! 		(ins == 2 && i == 2) ||	(ins == 3 && i == 3) ||
! 		tok == BAR    || tok == AMPER     ||
  		tok == BARAMP || tok == AMPERBANG ||
  		((tok == DBAR || tok == DAMPER) && !incond)) {
  		/* This is one of the things that separate commands.  If we  *
***************
*** 983,993 ****
  		if (tt)
  		    break;
  		/* Otherwise reset the variables we are collecting data in. */
! 		i = tt0 = cp = rd = 0;
  	    }
! 	    if (lincmd && tok == STRING) {
  		/* The lexer says, this token is in command position, so *
  		 * store the token string (to find the right compctl).   */
  		zsfree(cmdstr);
  		cmdstr = ztrdup(tokstr);
  		i = 0;
--- 987,999 ----
  		if (tt)
  		    break;
  		/* Otherwise reset the variables we are collecting data in. */
! 		i = tt0 = cp = rd = ins = 0;
  	    }
! 	    if (lincmd && (tok == STRING || tok == FOR || tok == FOREACH ||
! 			   tok == SELECT || tok == REPEAT || tok == CASE)) {
  		/* The lexer says, this token is in command position, so *
  		 * store the token string (to find the right compctl).   */
+ 		ins = (tok == REPEAT ? 2 : (tok != STRING));
  		zsfree(cmdstr);
  		cmdstr = ztrdup(tokstr);
  		i = 0;
***************
*** 1008,1013 ****
--- 1014,1022 ----
  	    }
  	    if (!tokstr)
  		continue;
+ 	    /* Hack to allow completion after `repeat n do'. */
+ 	    if (oins == 2 && !i && !strcmp(tokstr, "do"))
+ 		ins = 3;
  	    /* We need to store the token strings of all words (for some of *
  	     * the more complicated compctl -x things).  They are stored in *
  	     * the clwords array.  Make this array big enough.              */

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


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

end of thread, other threads:[~1999-01-20 11:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-01-18 17:20 Completion weirdity after `for' Peter Stephenson
1999-01-20 11:12 Sven Wischnowsky

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