From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1574 invoked from network); 20 Jan 1999 11:18:52 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 20 Jan 1999 11:18:52 -0000 Received: (from list@localhost) by math.gatech.edu (8.9.1/8.9.1) id GAA21285; Wed, 20 Jan 1999 06:13:43 -0500 (EST) Resent-Date: Wed, 20 Jan 1999 06:13:43 -0500 (EST) Date: Wed, 20 Jan 1999 12:12:27 +0100 (MET) Message-Id: <199901201112.MAA11360@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@math.gatech.edu In-reply-to: Peter Stephenson's message of Mon, 18 Jan 1999 18:20:06 +0100 Subject: Re: Completion weirdity after `for' Resent-Message-ID: <"bopO33.0.WC5.cfRfs"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/4930 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu Peter Stephenson wrote: > > After > > for f in > > 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