From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3280 invoked by alias); 11 Mar 2016 22:13:42 -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: 38135 Received: (qmail 22878 invoked from network); 11 Mar 2016 22:13:40 -0000 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 autolearn=ham autolearn_force=no version=3.4.1 Date: Fri, 11 Mar 2016 22:13:35 +0000 From: Daniel Shahaf To: "Jun T." Cc: zsh-workers@zsh.org Subject: Re: __git_ignore_line positional argument (un)escaping (was: Re: _git-reset doesn't complete newly staged files) Message-ID: <20160311221335.GA6922@tarsus.local2> References: <20160309132444.GA2428@tarsus.local2> <20160310232054.GA10995@tarsus.local2> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) Jun T. wrote on Fri, Mar 11, 2016 at 17:24:02 +0900: > On 2016/03/11, at 8:20, Daniel Shahaf wrote: > > > > With just ${(Q)line[...}}, you lose the ability to distinguish «git add > > f\[a-z\]o » from «git add f[a-z]o ». > (snip) > > With the following style: > zstyle ':completion:*:*:ls:*' ignore-line true > > With the current git HEAD: > [1]% touch foo 'f[a-z]o' '[f]oo' > [2]% ls f\[a-z\]o # OK: f\[a-z\]o not offered > [3]% git add f\[a-z\] # no: f\[a-z\]o is offered again > [4]% ls f[a-z]o # no: foo is offered > [5]% git add f[a-z]o # no: foo is offered > > With ${(bQ)..} in __git_ignore_line and _description: > [6]% ls f\[a-z\]o # no: f\[a-z\]o is offered again > [7]% git add f\[a-z\] # OK: f\[a-z\]o is not offered > [8]% ls f[a-z]o # OK: foo is not offered > [9]% git add f[a-z]o # OK: foo is not offered > > I don't know why the behavior is different between ls and git add > in the first two cases ([2][3]/[6][7]), because _description and > __git_ignore_line uses virtually the same escaping method. > I don't understand the difference either, and I'm afraid I don't have the brainwidth to look into the 'ls'/_description issue at the moment. However, since using (bQ) in _git seems to have no adverse effect, I'll go ahead and commit 38129. (We can always back it out if we find it introduces a regression.) > If I have > zstyle ':completion:*:*:(^rm):*:*files' ignored-patterns '*?.o' '*?.old' > then '-F _comp_ignore' is passed to compadd, and the '-F ignored' added > by __git_ignore_line has no effect. Of course I can use > zstyle ':completion:*:*:(^(rm|git*)):*:*files' ... > but ... Seems like the easy fix would be to make compadd take multiple -F options, so «compadd -F foo -F bar» would use both 'foo' and 'bar'. Implementing this would consist of changing this piece of code ('sp' is the place to append to, 'p' is a pointer into 'argv' which are the arguments of compadd; the «if (!*sp)» will need to grow an 'else' branch): diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index ee4e5b0..30fab54 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -704,15 +704,18 @@ bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func)) } if (sp) { if (p[1]) { + /* Pasted argument: -Xfoo. */ if (!*sp) *sp = p + 1; p = "" - 1; } else if (argv[1]) { + /* Argument in a separate word: -X foo. */ argv++; if (!*sp) *sp = *argv; p = "" - 1; } else { + /* Missing argument: argv[N] == "-X", argv[N+1] == NULL. */ zwarnnam(name, e, *p); zsfree(mstr); return 1; Cheers, Daniel