Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [Pkg-zsh-devel] Bug#793168: zsh: expand-substitution-on-TAB broke for $(()) in 5.0.8 [origin: adi@xxxxxxxxxxxxx]

On Sat, 25 Jul 2015 19:03:41 +0200
Axel Beckert <abe@xxxxxxxxxxxxxxx> 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,


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.


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
 		} 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, *

Messages sorted by: Reverse Date, Date, Thread, Author