Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID
	autolearn=ham autolearn_force=no version=3.4.1
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=brasslantern-com.20150623.gappssmtp.com; s=20150623;
        h=from:message-id:date:in-reply-to:comments:references:to:subject
         :mime-version;
        bh=SZfZ0JZRFYEZaNk845q/4a3zsXGCxAemFjnxh+35kVc=;
        b=yLKJKolF+LnCSa2Wed4TbISu9Vi80cxORpaJVlXGW5ii9m58XZA7Lvalj+hhOaBX0m
         yfOYM0NtSQUtW8ibK2FKV3UayO+ToOahVT7l5zLbNhgr4PLpsfkcd8dYSyZwdt1D9Srr
         RIR/6rTUrPkIZqTWW1ra8hrqZlwh53Cyj95+ZaWdRrTjJh202STtrgoeKPInYsQqRUMq
         E0EfA1aHt/8XnMyw1iArQVJ190bZOgKsKAOerjaci7TQdtU3naCgc+3WCdC6roivtt/O
         e1CtwsLiJ/Fy3UAzP+IeJIjUvx9HvTjZxJEdMyANJ3GMUkeS99XcZ3UNIvHCzklnKSej
         UPEw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:message-id:date:in-reply-to:comments
         :references:to:subject:mime-version;
        bh=SZfZ0JZRFYEZaNk845q/4a3zsXGCxAemFjnxh+35kVc=;
        b=TUbvuiTzVL/nO0gCfgZA3HShEl7Ad5BtmCwe905yGbs04LDtfzy9NjcSXAzXtOyDSO
         XL6eFK7u4pvST3uybilCsBF69j+TwAjeAD83H/FABRHIQejFI3kNi3y1neOKw4OeZAJS
         Y1KjcgamYep4v3VUfMh3NoGgXGNht8rQKlf2wNdbO26nlZhXsGhYZz+duz/bn3dOsFXn
         BP9SMoKsTzqcgJLrC+i4K1DRd319uKApzuYSqmmnOcJAV5fnvOt4rBhfBnx6hyOJckzF
         jPjhGRenQw+BMCYeyv0jQEU29nSAxAqm5A/meIdaYbTuZFLd6Za/R1wXT0NjOuLsAECj
         f2GA==
X-Gm-Message-State: AD7BkJIQXDN3ERVDD0UtWdbBK7sQkweNXMzLCPMkjidWRv0/nxNSgBICqDOXPzUzRpPYeQ==
X-Received: by 10.98.86.28 with SMTP id k28mr40782354pfb.43.1459969792954;
        Wed, 06 Apr 2016 12:09:52 -0700 (PDT)
From: Bart Schaefer <schaefer@brasslantern.com>
Message-Id: <160406121053.ZM31877@torch.brasslantern.com>
Date: Wed, 6 Apr 2016 12:10:53 -0700
In-Reply-To: <160402111815.ZM1925@torch.brasslantern.com>
Comments: In reply to Bart Schaefer <schaefer@brasslantern.com>
        "Re: Completion in empty double-quotes generates error" (Apr  2, 11:18am)
References: <160330110652.ZM1432@torch.brasslantern.com> 
	<20160401053633.GA17993@tarsus.local2> 
	<160401181824.ZM23675@torch.brasslantern.com> 
	<20160402032950.GA10638@tarsus.local2> 
	<160401232021.ZM25900@torch.brasslantern.com> 
	<160402111815.ZM1925@torch.brasslantern.com>
X-Mailer: OpenZMail Classic (0.9.2 24April2005)
To: zsh-workers@zsh.org
Subject: Re: Completion in empty double-quotes generates error
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-Seq: zsh-workers 38248

On Apr 2, 11:18am, Bart Schaefer wrote:
} Subject: Re: Completion in empty double-quotes generates error
}
} What would one expect to be completed with the cursor on the "2"?  The
} -redirect- special context is for what comes *after* the operator.  I
} can think of only two choices:
} 
} 1.  Complete as if there were an implicit space to the right of the
}     cursor.  This makes some sense because "2>" is treated as the same
}     single token as ">" all alone.
} 
} 2.  Treat it as an error and simply fail.
} 
} Patch below does this

More specifically, it attempted to do (1).  However, this situation is
really nasty -- get_comp_string() repeatedly calls the lexer looking for
the word containing the cursor, but because the lexer treats redirections
as positionally insignficant, there literally is no word containing the
cursor, so get_comp_string() keeps looking and finds the NEXT word (or
the end of the input), which places both wb and we beyond zlemetacs.

It gets worse still with "{myfd}>", and worse again when completing in
the whitespace between a word and a redirection (because in that last
situation it's correct for the redirection token to be ignored).

I'm still not entirely sure that the below is correct, i.e. that the
right things would happen if the "Should" comments were replaced with
the appropriate actual code.  But this at least handles more cases than
the previous situation.

The change in gotword() is necessary but of a little concern.  AFAICT
we only care about wb when examining the word under the cursor, so it
shouldn't hurt to skip updating it when doing so would violate the
wb <= zlemetacs <= we constraint, but there may be some corner case I
haven't tried that depends on the old behavior.


diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index b1709c1..1d4e1d2 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1161,6 +1161,7 @@ get_comp_string(void)
     inpush(dupstrspace(linptr), 0, NULL);
     strinbeg(0);
     wordpos = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0;
+    we = wb = zlemetacs;
     tt0 = NULLTOK;
 
     /* This loop is possibly the wrong way to do this.  It goes through *
@@ -1238,6 +1239,20 @@ get_comp_string(void)
 	    /* Record if we haven't had the command word yet */
 	    if (wordpos == redirpos)
 		redirpos++;
+	    if (zlemetacs < (zlemetall - inbufct) &&
+		zlemetacs >= wordbeg && wb == we) {
+		/* Cursor is in the middle of a redirection, treat as a word */
+		we = zlemetall - (inbufct + addedx);
+		if (addedx && we > wb) {
+		    /* Assume we are in {param}> form, wb points at "{" */
+		    wb++;
+		    /* Should complete parameter names here */
+		} else {
+		    /* In "2>" form, zlemetacs points at "2" */
+		    wb = zlemetacs;
+		    /* Should insert a space under cursor here */
+		}
+	    }
         }
 	if (tok == DINPAR)
 	    tokstr = NULL;
diff --git a/Src/lex.c b/Src/lex.c
index d4132fe..25b372a 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -1789,9 +1789,13 @@ parse_subst_string(char *s)
 static void
 gotword(void)
 {
-    we = zlemetall + 1 - inbufct + (addedx == 2 ? 1 : 0);
-    if (zlemetacs <= we) {
-	wb = zlemetall - wordbeg + addedx;
+    int nwe = zlemetall + 1 - inbufct + (addedx == 2 ? 1 : 0);
+    if (zlemetacs <= nwe) {
+	int nwb = zlemetall - wordbeg + addedx;
+	if (zlemetacs >= nwb) {
+	    wb = nwb;
+	    we = nwe;
+	}
 	lexflags = 0;
     }
 }

