From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22124 invoked from network); 17 Mar 2009 11:00:50 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 17 Mar 2009 11:00:50 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 61972 invoked from network); 17 Mar 2009 11:00:41 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 17 Mar 2009 11:00:41 -0000 Received: (qmail 18394 invoked by alias); 17 Mar 2009 11:00:34 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 26747 Received: (qmail 18378 invoked from network); 17 Mar 2009 11:00:33 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 17 Mar 2009 11:00:33 -0000 Received: from cluster-d.mailcontrol.com (cluster-d.mailcontrol.com [85.115.60.190]) by bifrost.dotsrc.org (Postfix) with ESMTPS id 7D3D4801E294 for ; Tue, 17 Mar 2009 12:00:20 +0100 (CET) Received: from cameurexb01.EUROPE.ROOT.PRI ([193.128.72.68]) by rly51d.srv.mailcontrol.com (MailControl) with ESMTP id n2HAxF7s032351 for ; Tue, 17 Mar 2009 11:00:08 GMT Received: from news01 ([10.103.143.38]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Mar 2009 11:00:04 +0000 Date: Tue, 17 Mar 2009 11:00:03 +0000 From: Peter Stephenson To: zsh-workers@sunsite.dk Subject: Re: Bug#519535: history expansion: modifier completion missing Message-ID: <20090317110003.6c676a4d@news01> In-Reply-To: <20090317095717.02bedf7e@news01> References: <20090313105555.GA19025@piper.oerlikon.madduck.net> <20090315062253.GB14010@scru.org> <20090316181852.27e9420d@news01> <090316194434.ZM16487@torch.brasslantern.com> <20090317095717.02bedf7e@news01> Organization: CSR X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.8; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 17 Mar 2009 11:00:04.0351 (UTC) FILETIME=[86AAE0F0:01C9A6EF] X-Scanned-By: MailControl A_08_51_00 (www.mailcontrol.com) on 10.68.0.161 X-Virus-Scanned: ClamAV 0.92.1/9118/Tue Mar 17 11:15:01 2009 on bifrost X-Virus-Status: Clean On Tue, 17 Mar 2009 09:57:17 +0000 Peter Stephenson wrote: > On Mon, 16 Mar 2009 19:44:34 -0700 > Bart Schaefer wrote: > > torch% echo foo > > torch% !!:a > > /usr/local/src/zsh/zsh-build/echo foo > > zsh: no such file or directory: /usr/local/src/zsh/zsh-build/echo > > > > That's almost certainly not the intended behavior ... is it? > > It depends what you mean by "intended": Michael did say the operation > didn't take account of whether the file existed (but I didn't document > this), and there was never any special behaviour for command words. You > could make it work like "=", I suppose, but that's an extension. I'm not sure if the change below is what you had in mind. Maybe you were pointing out that applying :a to the entire expression "echo foo", which is what happened, didn't make sense, but that's the way modifiers have always worked: % /bin/echo hello % !!:h -> /bin % !!:t -> echo hello so yes, it would be intended that a and A work the same. Maybe it's not clear (or is actually confusing) in the change below that the expansion depends not where the original has come from, but where the expansion is being used on the command line. I'm not even sure this change is useful. Suppose you had: % script arg and that didn't work because script was in the current directory rather than the path, so you ran % !:0:a !:* to ensure you ran the script from the current directory. With the change below, that wouldn't work any more. I've a mind to leave a and A as they were, note that they don't care if the file doesn't exist (which is also entirely consistent with h, t, etc.), and add c to do the following. You could then stack :c:A if you really wanted. Index: Doc/Zsh/expn.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v retrieving revision 1.103 diff -u -r1.103 expn.yo --- Doc/Zsh/expn.yo 15 Mar 2009 01:17:06 -0000 1.103 +++ Doc/Zsh/expn.yo 17 Mar 2009 10:44:41 -0000 @@ -219,6 +219,18 @@ item(tt(a))( Turn a file name into an absolute path: prepends the current directory, if necessary, and resolves any use of `tt(..)' and `tt(.)' in the path. +If used in history substitution at the start of a command line and the name +does not contain a tt(/), it is resolved as an external command by +searching the command path given by the tt(PATH) parameter. For example, +assuming the current directory is tt(/home/pwd) and the external command +tt(echo) exists in tt(/bin), then the following: +example(echo file +!:0:a !:1:a +) +becomes `tt(/bin/echo /home/pwd/file)', while +example(./script file +!:0:a !:1:a) +becomes `tt(/home/pwd/script /home/pwd/file)'. ) item(tt(A))( As `tt(a)', but also resolve use of symbolic links where possible. Index: Src/hist.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/hist.c,v retrieving revision 1.90 diff -u -r1.90 hist.c --- Src/hist.c 15 Mar 2009 01:17:06 -0000 1.90 +++ Src/hist.c 17 Mar 2009 10:44:42 -0000 @@ -624,7 +624,9 @@ histdone = HISTFLAG_DONE | HISTFLAG_NOEXEC; break; case 'a': - if (!chabspath(&sline)) { + if ((incmdpos && !strchr(sline, '/') && + !(sline = equalsubstr(sline, 0, 0))) || + !chabspath(&sline)) { herrflush(); zerr("modifier failed: a"); return -1; @@ -632,7 +634,9 @@ break; case 'A': - if (!chrealpath(&sline)) { + if ((incmdpos && !strchr(sline, '/') && + !(sline = equalsubstr(sline, 0, 0))) || + !chrealpath(&sline)) { herrflush(); zerr("modifier failed: A"); return -1; Index: Src/subst.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/subst.c,v retrieving revision 1.96 diff -u -r1.96 subst.c --- Src/subst.c 15 Mar 2009 01:17:06 -0000 1.96 +++ Src/subst.c 17 Mar 2009 10:44:42 -0000 @@ -539,12 +539,43 @@ } } +#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') ) +#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') ) + +/* + * do =foo substitution, or equivalent. + * on entry, str should point to the "foo". + * if assign, this is in an assignment + * if nomatch, report hard error on failure. + * if successful, returns the expansion, else NULL. + */ + +/**/ +char * +equalsubstr(char *str, int assign, int nomatch) +{ + char *pp, *cnam, *cmdstr, *ret; + + for (pp = str; !isend2(*pp); pp++) + ; + cmdstr = dupstrpfx(str, pp-str); + untokenize(cmdstr); + remnulargs(cmdstr); + if (!(cnam = findcmd(cmdstr, 1))) { + if (nomatch) + zerr("%s not found", cmdstr); + return NULL; + } + ret = dupstring(cnam); + if (*pp) + ret = dyncat(ret, pp); + return ret; +} + /**/ mod_export int filesubstr(char **namptr, int assign) { -#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') ) -#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') ) char *str = *namptr; if (*str == Tilde && str[1] != '=' && str[1] != Equals) { @@ -606,27 +637,17 @@ return 1; } } else if (*str == Equals && isset(EQUALS) && str[1]) { /* =foo */ - char *pp, *cnam, *cmdstr, *str1 = str+1; - - for (pp = str1; !isend2(*pp); pp++) - ; - cmdstr = dupstrpfx(str1, pp-str1); - untokenize(cmdstr); - remnulargs(cmdstr); - if (!(cnam = findcmd(cmdstr, 1))) { - if (isset(NOMATCH)) - zerr("%s not found", cmdstr); - return 0; + char *expn = equalsubstr(str+1, assign, isset(NOMATCH)); + if (expn) { + *namptr = expn; + return 1; } - *namptr = dupstring(cnam); - if (*pp) - *namptr = dyncat(*namptr, pp); - return 1; } return 0; +} + #undef isend #undef isend2 -} /**/ static char * -- Peter Stephenson Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070