zsh-workers
 help / color / mirror / code / Atom feed
From: "Miroslav Koškár" <mk@mkoskar.com>
To: Daniel Shahaf <d.s@daniel.shahaf.name>
Cc: zsh-workers@zsh.org
Subject: Re: _git: Improve handling of aliases
Date: Fri, 26 Jun 2020 12:17:04 +0200	[thread overview]
Message-ID: <20200626101704.lhzsaqrdov5rhbr7@mkoskar.com> (raw)
In-Reply-To: <20200624115630.GA25495@tarpaulin.shahaf.local2>

Hi Daniel,

thanks for your feedback!

> > -    local -a aliases
> > -    local -A git_aliases
> > -    local a k v
> > -    local endopt='!(-)--end-of-options'
> > -    aliases=(${(0)"$(_call_program aliases git config -z --get-regexp '\^alias\.')"})
> 
> This (preëxisting) line is wrong.  The arguments to _call_program are as
> to «eval»: joined with spaces and then one layer of quoting removed.
> That means the backslash that protects the dot doesn't make it through
> to git.  (If that weren't so, the backslash before the caret would have
> caused the regexp to never match.)

True. Noted.

> You moved the surrounding block code further down the function
> unchanged.  I'd recommend to split the patch into two parts: one that
> just moves the code without changing it, and one that adds new
> functionality.  That'll make it much easier to review.

Hmm, ok how about this:

1) fixing up for nested aliases and preceding options
2) basic parsing of shell aliases for completing of last simple command
   (this would be the "new functionality" bit then)

For 1) I'm thinking about this:

    a) keep it as is more/less (fixing the small _call_program issue above):

        ...
        local -A git_aliases
        local a
        for a in ${(0)"$(_call_program aliases git config -z --get-regexp \^alias\\.)"}; do
          git_aliases[${${a/$'\n'*}/alias.}]=${a#*$'\n'}
        done
        local git_alias=git_aliases[\$words[1]]
        if (( ${(P)+git_alias} && !$+commands[git-$words[1]] && !$+functions[_git-$words[1]] )); then
          git_alias=${(P)git_alias}
        ...

        * I've got rid of "aliases", "k" and "v" to shorten it a bit

    b) much shorter and IMO cleaner:

        ...
        local git_alias
        if git_alias=${"$(git config -z --get alias.$words[1] 2>/dev/null)"/$'\0'*} \
          && (( !$+commands[git-$words[1]] && !$+functions[_git-$words[1]] )); then
        ...

        * basically the difference is that we don't ask for all aliases
          but only for the one we're interested in
        * it loses configurability of _call_program, which IMO is
          rather pointless anyway

> > +        local git_alias=git_aliases[\$words[1]]
> > +        if (( ${(P)+git_alias} && !$+commands[git-$words[1]] && !$+functions[_git-$words[1]] )); then
> > +          git_alias=${(P)git_alias}
> > +          local len=$#words
> > +          if [[ $git_alias = \!* ]]; then
> > +            local i
> > +            local -a git_alias_tail
> > +            for i in "${(z)git_alias##\!}"; do
> > +              git_alias_tail+=("$i")
> > +              [[ $i = \| ]] && git_alias_tail=()
> 
> Would it be possible to add support to everything that could be used
> there, in addition to pipes?  I think you just need to call whatever «sh
> -c <TAB>» does, i.e., _cmdstring.  That would add support for comments
> and for a bunch of things other than «|» that can be followed by the
> start of a simple command (for example, the tokens and reserved words
> in https://github.com/zsh-users/zsh-syntax-highlighting/blob/91d2eeaf23c47341e8dc7ad66dbf85e38c2674de/highlighters/main/main-highlighter.zsh#L391-L416).
> 
> Adding support for comments specifically could also be done by using
> the ${(Z)} flag, but I don't know how common that is.  If «foo = bar # baz»
> lines in .gitconfig pass the «#» sign through to sh, then support for
> comments should probably be added, one way or another.

I agree, I've hastily put only split on '|' there. I've looked into
_cmdstring and I don't believe this will be of any help here as it's
completing single command argument only. It seems to me most sane here
is to complete using _normal on last simple command contained in that
alias. So something like this should work fine:

    local i
    local -a git_alias_tail
    for i in "${(z)git_alias##\!}"; do
      git_alias_tail+=("$i")
      case $i in ';' | $'\n' | '||' | '&&' | '|' | '|&' | '&' | '&!' | '&|') git_alias_tail=() ;; esac
    done
    words=("$git_alias_tail[@]" "${words[@]:1}")

Let me know what you think and I'll re-roll the patch/es.

Regards,
Miro


  reply	other threads:[~2020-06-26 10:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-24 11:12 [PATCH] " Miroslav Koškár
2020-06-24 11:56 ` Daniel Shahaf
2020-06-26 10:17   ` Miroslav Koškár [this message]
2020-06-26 17:00     ` Daniel Shahaf
2020-06-27  6:12       ` [PATCH 0/4] " Miroslav Koškár
2020-06-27  6:12         ` [PATCH 1/4] _git: Remove hanging whitespaces Miroslav Koškár
2020-06-27  6:12         ` [PATCH 2/4] _git: Fix insufficiently quoted pattern Miroslav Koškár
2020-06-27  6:12         ` [PATCH 3/4] _git: Fix handling of aliases Miroslav Koškár
2020-06-27  6:12         ` [PATCH 4/4] _git: Don't shadow global aliases Miroslav Koškár
2020-06-27  9:04       ` _git: Improve handling of aliases Miroslav Koškár
2020-06-27 20:39         ` 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=20200626101704.lhzsaqrdov5rhbr7@mkoskar.com \
    --to=mk@mkoskar.com \
    --cc=d.s@daniel.shahaf.name \
    --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).