From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10977 invoked by alias); 25 Jul 2015 19:15:17 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 35908 Received: (qmail 17528 invoked from network); 25 Jul 2015 19:15:14 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.0 X-Originating-IP: [80.3.228.158] X-Spam: 0 X-Authority: v=2.1 cv=TNS4MARa c=1 sm=1 tr=0 a=P+FLVI8RzFchTbbqTxIDRw==:117 a=P+FLVI8RzFchTbbqTxIDRw==:17 a=q_dBH0nAAAAA:8 a=NLZqzBF-AAAA:8 a=kj9zAlcOel0A:10 a=sJHWTmtfAAAA:8 a=qzO_oeFnfyYS96oJpnAA:9 a=CjuIK1q_8ugA:10 Date: Sat, 25 Jul 2015 20:15:09 +0100 From: Peter Stephenson To: Zsh hackers list Subject: Re: [Pkg-zsh-devel] Bug#793168: zsh: expand-substitution-on-TAB broke for $(()) in 5.0.8 [origin: adi@hexapodia.org] Message-ID: <20150725201509.42d34c1d@ntlworld.com> In-Reply-To: <20150725170340.GY2433@sym.noone.org> References: <20150725170340.GY2433@sym.noone.org> X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Sat, 25 Jul 2015 19:03:41 +0200 Axel Beckert wrote: > with zsh 5.0.7 and earlier versions, if I type $((5*8)) and then hit TAB, > the expression is replaced with its evaluation ("40" in this case). The > same feature works with many different substitutions. > > as of 5.0.8 TAB-substituting does not work with $(()) anymore. > > It does still work right with "${VAR}" and "$[5+8]". There are two things here: the _expand completer and the expand-or-complete widget. The expand-word widget still works. I think the patch below fixes the expand-or-complete case. The _expand case is in shell code. The difference apparently comes from the fact that in the new code $(( ... )) gets tokenised such that the outer parentheses become Inparmath and Outparmath, while the inner parentheses don't get tokenised. That means that at line 25 of _expand, word="$IPREFIX$PREFIX$SUFFIX$ISUFFIX" becomes (from ^X?) +_expand:25> word='$(\(3\*4\))' so that the expansion thinks the inner parentheses should be treated literally. (I think $PREFIX is the only relevant word in the normal case, but I think the same rules apply to all the variables.) One fix might be to attempt to replace (\(...\)) globally with ((...)). That might be OK in most cases, but as we're doing it in shell code it's not perfect syntactically. It might be possible to detect this at the point where we introduce the backslashes, but I don't actually know where that is. Does anyone? I'll think about one of these anyone else can see a better alternative (pontificating about the possbility of a better alternative doesn't count :-)). It *might* be OK to tokenise the inner parentheses in lex.c, but I don't really want to tinker with the main shell unless I have to. pws diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 2104ca1..3bf8d45 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -721,11 +721,12 @@ docomplete(int lst) } } } - if (lst == COMP_EXPAND_COMPLETE) + if (lst == COMP_EXPAND_COMPLETE) { do { /* Check if there is a parameter expression. */ for (; *q && *q != String; q++); - if (*q == String && q[1] != Inpar && q[1] != Inbrack) { + if (*q == String && q[1] != Inpar && q[1] != Inparmath && + q[1] != Inbrack) { if (*++q == Inbrace) { if (! skipparens(Inbrace, Outbrace, &q) && q == s + zlemetacs - wb) @@ -769,6 +770,7 @@ docomplete(int lst) } else break; } while (q < s + zlemetacs - wb); + } if (lst == COMP_EXPAND_COMPLETE) { /* If it is still not clear if we should use expansion or * * completion and there is a `$' or a backtick in the word, *