git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
Cc: Karthik Nayak <karthik.188@gmail.com>, Git <git@vger.kernel.org>,
	Christian Couder <christian.couder@gmail.com>
Subject: Re: [PATCH v12 03/13] ref-filter: introduce the ref_formatting_state stack machinery
Date: Thu, 20 Aug 2015 09:47:48 -0700	[thread overview]
Message-ID: <xmqqvbc97vpn.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <vpq7foq1kpe.fsf@anie.imag.fr> (Matthieu Moy's message of "Thu, 20 Aug 2015 09:29:49 +0200")

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Speaking of quote_value, The quote doesn't work well with color's
>> for e.g.
>> git for-each-ref --shell --format="%(color:green)%(refname)"
>> '''refs/heads/allow-unknown-type'''
>> Seems like an simple fix, probably after GSoC I'll do this :)
>
> Anyway, the %(color) is really meant to be displayed on-screen, and the
> quoting is really meant to feed the value to another program, so I can
> hardly imagine a use-case where you would want both.
>
> But the current behavior seems fine to me: the color escape sequence is
> quoted, which is good. For example, you can
>
> x=$(git for-each-ref --shell --format="nocolor%(color:green)%(refname)" | head -n 1)
> sh -c "echo $x"
>
> it will actually display "nocolor" without color, then a green refname.
> I'm not sure the quoting is really necessary, but it doesn't harm and it
> makes sense since the escape sequence contains a '[' which is a shell
> metacharacter.

The point of --shell/--tcl/... is so that you can have --format
safely write executable scripts in the specified language.  Your
format string might look like this:

        --format="short=%(refname:short) long=%(refname)"

and one entry in the output in "--shell" mode would expand to

        short='master' long='refs/heads/master'

that can be eval'ed as a script safely without having to worry about
expanded atom values having characters that have special meanings in
the target language.  Your "nocolor" example works the same way:

        --format="var=%(color:green)%(refname)" --shell

would scan 'var=', emit it as literal, see %(color:green) atom, show
it quoted, see %(refname), show it quoted, notice that color is not
terminated and pretend as if it saw %(color:reset) and show it
quoted, which would result in something like:

        var='ESC[32m''master''ESC[m'

Note that the example _knows_ that the quoting rule of the target
language, namely, two 'quoted' 'strings' next to each other are
simply concatenated.  When using a hypothetical target language
whose quoting rule is different, e.g. "type two single-quotes inside
a pair of single-quote to represent a literal single-quote", then
you would write something like this to produce a script in that
language:

        --format="
            var1=%(color:green);
            var2=%(refname);
            var=var1+var2;
        "

as your format string (and it will not be used with --shell).  And
the atom-quoting code that knows the language specific rules would
quote %(atom) properly.  Perhaps the language uses `' for its string
quoting, in which case one entry of the output might look like

	var1=`ESC[32m';
        var2=`refs/heads/master';
        var=var1+var2;

which would be in the valid syntax of that hypothetical language.

Maybe you have an atom %(headstar) that expands to an asterisk for
the currently checked out branch, in order to mimick 'git branch -l'.

Using that, you might use --shell --format to invent a shorter output
format that does not show the asterisk but indicates the current
branch only with color, like so:

        --format='
            if test -z %(headstar)
            then
                echo %(refname:short)
            else
                echo %(color:green)%(refname:short)%(color:reset)
            fi
        '

and you would want %(headstar)'s expansion to be '*' or ''.

If we introduce %(if:empty)%(then)%(else)%(end), the above may
become something like this, removing the need for --shell
altogether:

        %(if:empty)%(headstar)%(then
        )%(refname:short)%(else
        )%(color:green)%(refname:short)%(color:reset)%(end)

With the current implementation, it is likely that this needs to be
a single long line; we may want to extend parsing of atoms to allow
a LF+whitespace before the close parenthesis to make the string more
readable like the above example, but that is an unrelated tangent.

But you should still be able to use "--shell" this way, assigning
the whole thing to a variable:
    
        --format='
                line=%(if:empty)%(headstar)%(then
                )%(refname:short)%(else
                )%(color:green)%(refname:short)%(color:reset)%(end)
                echo "$line"
        '

So I think 'quote' should apply only to the top-level atoms in the
nested %(magic)...%(end) world.  Expand %(if:empty)...%(end) and
then apply the quoting rule specific to the target language to make
the result safe to use as the RHS of the target language.  None of
the atoms that appear internally (e.g. %(headstar) that is being
tested for emptyness) must NOT be quoted.

If you have %(align:40)%(atom) and string%(end), the same logic
applies.  %(atom) is not a top level item (it is inside %(align))
so you would expand "%(atom) and string" without quoting, measure
its display width, align to 40-cols and then if --shell or any
quoting is in effect, applyl that, so that the user can do:

	--format='
            right=%(align:40)%(refname)%(end)
            left=%(align:20,right)%(refname:short)%(end)
            echo "$left $right"
	'

one entry of the output from which would expand to

	right='refs/heads/master                       '
        left='              master'
        echo "$left $right"

because the rule is to quote the whole %(align)...%(end) construct
only once.

  parent reply	other threads:[~2015-08-20 16:47 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-18 18:37 [PATCH v12 00/13] port tag.c to use ref-filter.c APIs Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 01/13] ref-filter: move `struct atom_value` to ref-filter.c Karthik Nayak
2015-08-19 14:56   ` Matthieu Moy
2015-08-19 15:29     ` Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 02/13] ref-filter: introduce ref_formatting_state Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 03/13] ref-filter: introduce the ref_formatting_state stack machinery Karthik Nayak
2015-08-19 14:56   ` Matthieu Moy
2015-08-19 15:39     ` Karthik Nayak
2015-08-19 15:44       ` Matthieu Moy
2015-08-19 15:54         ` Karthik Nayak
2015-08-19 16:10           ` Karthik Nayak
2015-08-20  7:29             ` Matthieu Moy
2015-08-20 10:29               ` Karthik Nayak
2015-08-20 16:47               ` Junio C Hamano [this message]
2015-08-20 17:19                 ` Matthieu Moy
2015-08-20 18:29                   ` Junio C Hamano
2015-08-19 18:52     ` Junio C Hamano
2015-08-20 10:31       ` Karthik Nayak
2015-08-20 16:51       ` Junio C Hamano
2015-08-18 18:37 ` [PATCH v12 04/13] utf8: add function to align a string into given strbuf Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 05/13] ref-filter: implement an `align` atom Karthik Nayak
2015-08-18 19:28   ` Karthik Nayak
2015-08-20 20:23   ` Eric Sunshine
2015-08-21  1:55     ` Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 06/13] ref-filter: add option to filter out tags, branches and remotes Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 07/13] ref-filter: support printing N lines from tag annotation Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 08/13] ref-filter: add support to sort by version Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 09/13] ref-filter: add option to match literal pattern Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 10/13] tag.c: use 'ref-filter' data structures Karthik Nayak
2015-08-19 14:56   ` Matthieu Moy
2015-08-19 15:51     ` Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 11/13] tag.c: use 'ref-filter' APIs Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 12/13] tag.c: implement '--format' option Karthik Nayak
2015-08-19 14:53   ` Matthieu Moy
2015-08-20 15:50     ` Karthik Nayak
2015-08-18 18:37 ` [PATCH v12 13/13] tag.c: implement '--merged' and '--no-merged' options Karthik Nayak
2015-08-18 19:18 ` [PATCH v12 00/13] port tag.c to use ref-filter.c APIs Eric Sunshine
2015-08-18 19:25   ` Karthik Nayak

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=xmqqvbc97vpn.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.com \
    /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://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).