zsh-workers
 help / color / mirror / code / Atom feed
From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: "Jun T." <takimoto-j@kba.biglobe.ne.jp>
Cc: zsh-workers@zsh.org
Subject: __git_ignore_line positional argument (un)escaping (was: Re: _git-reset doesn't complete newly staged files)
Date: Thu, 10 Mar 2016 23:20:54 +0000	[thread overview]
Message-ID: <20160310232054.GA10995@tarsus.local2> (raw)
In-Reply-To: <F614B9C0-B219-43E4-9A82-519F57D3DC84@kba.biglobe.ne.jp>

I wrote this before I saw Mikael's post, but I'm sending it anyway,
since it may still be relevant.  [Search for "bQ" for the
non-_git-specific discussion.]

Jun T. wrote on Thu, Mar 10, 2016 at 21:03:59 +0900:
> On 2016/03/09, at 22:24, Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> > I think you're looking for «git diff-index --cached -z --name-only
> > $treeish».
> 
> What I was not sure was whether to offer conflicting files or not.
> 'git reset conflicting_file' leaves the working tree unmodified
> (so '<<<<<<< HEAD' etc. remain there) while the index becomes clean
> (conflict fixed) and you can commit it. I thought this would not
> be useful.
> 
> But it is not an error anyway, and maybe there are someone who
> really want to do that (if they are going to run 'git reset' while
> there is a conflict, they may well know what they are doing).
> 

Agreed: it wouldn't be a typical workflow, but it's admitted by the
tool.

I lean on the side of just offering all valid completions, including
conflicted files.  That:

- Keeps the completion interface simpler, with fewer exceptions for
  users to have to know about;

- Leaves issueing warnings about inadvisable usages to git(1) itself,
  which is better placed than compsys to decide when such warnings are
  warranted.

> > I took the liberty of changing the tag and description you used, since
> > "staged files" isn't exactly right for this syntax: files that are in
> > $treeish but not staged may also be completed.
> 
> I thought those files are 'staged for delete', but your more
> descriptive tag/description would be better.
> 

Okay, then I'll keep them when I commit that patch.

> > Incidentally, it would be nice to have a docstring for __git_ignore_line:
> 
> Yes, and
> 

Did you intend to type more words in that sentence?

> > Why does __git_ignore_line escape some characters with backslashes
> > before adding them to $ignored?
> 
> I'm rather confused. Isn't it better to UN-quote them?
> 
> % touch 'a b.txt'
> % git add <TAB>
> this completes a\ b.txt, and
> % git add a\ b.txt <TAB>
> this still completes a\ b.txt.
> 
> Using
>     ignored+=(${(Q)line[1,CURRENT-1]})
>     ignored+=(${(Q)line[CURRENT+1,-1]})
> fixes this.
> 
> Moreover,
>
> % git add *.txt <TAB>
> this does not complete a\ b.txt anymore.
> 
> Or there are something I've overlooked.

With just ${(Q)line[...}}, you lose the ability to distinguish «git add
f\[a-z\]o <TAB>» from «git add f[a-z]o <TAB>».  It took me a while to
find an incantation that works, but I think «${(bQ)line[...}}» is it:

    % ls -1
    [f]oo
    f[a-z]o
    foo
    % () { eval "echo ${(bQ)1}" } '\[f\]oo'
    [f]oo
    % () { eval "echo ${(bQ)1}" } '[f]oo'  
    foo
    % () { eval "echo ${(bQ)1}" } 'f[a-z]o' 
    foo
    % () { eval "echo ${(bQ)1}" } 'f\[a-z\]o'
    f[a-z]o

    % ls -1
    bar.txt
    baz.txt
    % () { eval "echo ${(bQ)1}" } '*.txt'
    bar.txt baz.txt

(The purpose of the "eval" is to force the result of parameter expansion
to be interpreted as a pattern, since elements of $ignored are
interpreted by compadd as patterns.)

With the argument to 'compadd -F' constructed using ${(bQ)}, all these
patterns do the right thing: they ignore exactly the files the anonymous
function prints and no others.  For example, «git add f[a-z]o <TAB>»
offers «f\[a-z\]o» but not «foo», and so on.

So, three questions:

1. Should regression tests be added for these uses of ${(bQ)}?

2. The ignore-line currently uses the following escaping:
.
   # Completion/Base/Core/_description
   50	  if zstyle -s ":completion:${curcontext}:$1" ignore-line hidden; then
   51	    local -a qwords
   52	    qwords=( ${words//(#m)[\[\]()\\*?#<>~\^\|]/\\$MATCH} )
.
Should the ignore-line style use ${(bQ)}?

3. Is the following patch correct?

diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 2dd9a80..e063a6f 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -4961,7 +4961,7 @@ __git_committish_range_last () {
 
 (( $+functions[__git_pattern_escape] )) ||
 __git_pattern_escape () {
-  print -r -n ${1//(#m)[\[\]()\\*?#<>~\^]/\\$MATCH}
+  print -r -n - ${(b)1}
 }
 
 (( $+functions[__git_is_type] )) ||
@@ -5053,8 +5053,8 @@ __git_ignore_line () {
   declare -a ignored
   ignored=()
   ((CURRENT > 1)) &&
-    ignored+=(${line[1,CURRENT-1]//(#m)[\[\]()\\*?#<>~\^]/\\$MATCH})
+    ignored+=(${(bQ)line[1,CURRENT-1]})
   ((CURRENT < $#line)) &&
-    ignored+=(${line[CURRENT+1,-1]//(#m)[\[\]()\\*?#<>~\^]/\\$MATCH})
+    ignored+=(${(bQ)line[CURRENT+1,-1]})
   $* -F ignored
 }

?

Cheers,

Daniel

P.S. I suppose a tree-wide grep for more of those hand-rolled
implementations of ${(b)}/${(q)} wouldn't be a bad thing...


  parent reply	other threads:[~2016-03-10 23:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-26  8:08 _git-reset doesn't complete newly staged files Jun T.
2016-03-03  5:07 ` Jun T.
2016-03-07  3:16   ` Jun T.
2016-03-09 13:24   ` Daniel Shahaf
2016-03-09 23:33     ` Daniel Shahaf
2016-03-10 23:15       ` [PATCH] _git: Fix completion of diffs against the index when treeish isn't shell-safe Daniel Shahaf
2016-03-10 12:03     ` _git-reset doesn't complete newly staged files Jun T.
2016-03-10 14:35       ` Mikael Magnusson
2016-03-10 23:20       ` Daniel Shahaf [this message]
2016-03-11  8:24         ` __git_ignore_line positional argument (un)escaping (was: Re: _git-reset doesn't complete newly staged files) Jun T.
2016-03-11 22:13           ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160310232054.GA10995@tarsus.local2 \
    --to=d.s@daniel.shahaf.name \
    --cc=takimoto-j@kba.biglobe.ne.jp \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).