Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-08 Thread Simon Oosthoek

Hi Junio

I hope you found my patches, if not, I'll try to send them out again. 
(Unfortunately my current mail setup is a mess and I need time to figure 
out what to fix...)


As for the zsh support, I found out a little bit more.
ZSH doesn't have a variable like PROMPT_COMMAND in bash. The precmd name 
is a function the user has to define herself to have it called before 
the prompt is shown. Functionally this is almost, but not quite, the 
same as PROMPT_COMMAND. The subtle difference is that with 
PROMPT_COMMAND you can use parameters to customize the prompt, so in 
bash you can say:


PROMPT_COMMAND=__git_ps1 '\u@\[\e[1;34m\]\h\[\e[0m\]:\w' '\\\$ '

where in zsh, if you want the status in the prompt, you can either use 
$(__git_ps1 (%s)) or something like it in setting the PS1 (and forget 
about the color hints!) or you can copy the __git_ps1 function and 
modify and rename it as precmd to set PS1 via that function. Obviously 
it is probably even more complicated, but I'd have to try it to be certain.


An alternative way might be to set special variables from __git_set_vars 
function which may be used in a custom precmd to set the prompt.


e.g. say __git_set_vars sets __GIT_VAR_STATE=dirty|stage|clean

in precmd you could do
case $__GIT_VAR_STATE in
(dirty) PS1=$PS1 files modified in __GIT_VAR_BRANCHNAME
;;
(stage) PS1=$PS1 files staged in __GIT_VAR_BRANCHNAME
;;
(clean) PS1=$PS1 __GIT_VAR_BRANCHNAME clean
;;
esac

(more or less of course)..

In that way it would be possible to add the colors relatively easily 
based on the state of the tree in a custom precmd function of zsh.


/Simon



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-02 Thread Michael J Gruber
Junio C Hamano venit, vidit, dixit 01.10.2012 23:09:
 Simon Oosthoek s.oosth...@xs4all.nl writes:
 
 It's possible to set PS1 to nothing and print a string from
 PROMPT_COMMAND, but then you miss out on all the features of the PS1
 interpretation by bash and compared to the use of __git_ps1 at the
 moment, it has to put out quite a different string. Because if you like
 to see user@host+workdir (git-status)[$#]
 the current users of __git_ps1 say PS1=\u@host+\w $(__git_ps1 %s)\$
 , but all __git+ps1 has to put out is (branch) or (branch *), etc.

 If it has to print the same prompt in PC mode, it has to add all the
 user/host/workdir/[$#] data as well, withouth being able to use the bash
 internal interpretation (because that is only working when PS1 is set).
 
 The longer I read your explanation, the less useful the PC mode
 sounds like, at least to me.  So why does an user even want to use
 such a mechanism, instead of PS1?  And even if the user wants to use
 it by doing \w, \u etc. himself, she can do that with
 
   PROMPT_COMMAND='
   PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
 '
 
 just fine, no?
 
 So I still do not see the problem, even taking your Set PS1 in the
 command, without spitting anything out of the command use case into
 account.
 
 Confused
 

The problem (as far as I see) is only: What user interface do we want
to expose to the user, or rather, do we want to expose the user to ;)

So far, we say:

#1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
#2) Add the following line to your .bashrc/.zshrc:
#source ~/.git-prompt.sh
#3) Change your PS1 to also show the current branch:
# Bash: PS1='[\u@\h \W$(__git_ps1  (%s))]\$ '
# ZSH:  PS1='[%n@%m %c$(__git_ps1  (%s))]\$ '

(That's incomplete for zsh, but I'm digressing...). With the above, we
would change the bash instruction to

PROMPT_COMMAND='
PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
   '

which may look more complicated to some. I think we can aim for
something like

PROMPT_COMMAND='__git_ps1_color \u \h \w%s$   (%s)'

so that the first arg is a PS1 string, %s there gets replaced by the git
prompt (if any), and the second arg defines the formatting of the git
prompt. This makes the ui (what you have to set the shells vars to) as
simple as possible.

As I said, I had done some fixes and refactoring to that effect already,
but I'm not going to race Simon.

Michael
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-02 Thread Simon Oosthoek

On 10/02/2012 09:38 AM, Michael J Gruber wrote:

The longer I read your explanation, the less useful the PC mode
sounds like, at least to me.  So why does an user even want to use
such a mechanism, instead of PS1?  And even if the user wants to use
it by doing \w, \u etc. himself, she can do that with

PROMPT_COMMAND='
PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
 '

just fine, no?


Well, in that way, it doesn't work and setting PS1 directly would be 
better. But this way you cannot do colors.




Confused


I know the feeling ;-)



The problem (as far as I see) is only: What user interface do we want
to expose to the user, or rather, do we want to expose the user to ;)

So far, we say:

#1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
#2) Add the following line to your .bashrc/.zshrc:
#source ~/.git-prompt.sh
#3) Change your PS1 to also show the current branch:
# Bash: PS1='[\u@\h \W$(__git_ps1  (%s))]\$ '
# ZSH:  PS1='[%n@%m %c$(__git_ps1  (%s))]\$ '

(That's incomplete for zsh, but I'm digressing...). With the above, we
would change the bash instruction to

PROMPT_COMMAND='
PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
'

which may look more complicated to some. I think we can aim for
something like

PROMPT_COMMAND='__git_ps1_color \u \h \w%s$   (%s)'

so that the first arg is a PS1 string, %s there gets replaced by the git
prompt (if any), and the second arg defines the formatting of the git
prompt. This makes the ui (what you have to set the shells vars to) as
simple as possible.

As I said, I had done some fixes and refactoring to that effect already,
but I'm not going to race Simon.


I don't quite see how you're going to smurf the formatted string into 
the PS1 string at %s...


Wouldn't it be easier in this case to have the user provide 3 arguments:

PROMPT_COMMAND='__git_ps1 \u@\h:\w  (%s) \$ '

The first and last can be directly assigned to PS1 and the format string 
can be put in the middle.


BUT. In this way, it is still impossible to change the colors inside the 
format string, unless you ignore that when the user requested color 
hints. Because the output of printf will not be interpreted by bash when 
put in via command substitution.


The whole point of this exercise (for me at least) was to be able to 
color different parts of the bit that __git_ps1 put in, based on the 
current state of the tree.


I think the user interface could be something like:

use either:
PROMPT_COMMAND='__git_ps1 \u@\h:\w  \$ ' # 2 args!
or
PS1=\u@\h:\w $(__git_ps1 '(%s)')\$ 

(I just realised that I still need to handle the case where both PS1 and 
PROMPT_COMMAND contain __git_ps1 ;-)


Note that in the PS1 case, no color codes should be put into the string, 
as they will mangle the prompt length and wrapping problems start happening.


Cheers

Simon.




--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-02 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 Junio C Hamano venit, vidit, dixit 01.10.2012 23:09:

 Confused
 

 The problem (as far as I see) is only: What user interface do we want
 to expose to the user, or rather, do we want to expose the user to ;)

 So far, we say:

 #1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
 #2) Add the following line to your .bashrc/.zshrc:
 #source ~/.git-prompt.sh
 #3) Change your PS1 to also show the current branch:
 # Bash: PS1='[\u@\h \W$(__git_ps1  (%s))]\$ '
 # ZSH:  PS1='[%n@%m %c$(__git_ps1  (%s))]\$ '

 (That's incomplete for zsh, but I'm digressing...). With the above, we
 would change the bash instruction to

 PROMPT_COMMAND='
   PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
'

 which may look more complicated to some. I think we can aim for
 something like

 PROMPT_COMMAND='__git_ps1_color \u \h \w%s$   (%s)'

If your goal is to use PROMPT_COMMAND and not PS1, then yes between
the two definitions of PROMPT_COMMAND above, the latter may look
simpler.  But that does not explain why you want to prefer it over
PS1 in the first place, which was the central point of my question
that still has not been answered.

Even more confused...

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-02 Thread Simon Oosthoek
On 02/10/12 19:01, Junio C Hamano wrote:
 If your goal is to use PROMPT_COMMAND and not PS1, then yes between
 the two definitions of PROMPT_COMMAND above, the latter may look
 simpler.  But that does not explain why you want to prefer it over
 PS1 in the first place, which was the central point of my question
 that still has not been answered.
 
 Even more confused...
 

The specific answer to your question is that without using
PROMPT_COMMAND it doesn't seem to be possible to use colors based on the
state of the git tree. The reason being that in order to prevent
wrapping problems on the command line (specifically going up/down the
history list in bash or line wrapping on a long command). This is
prevented (and quite the norm in static PS1 strings) by enclosing the
terminal code for color inside \[ and \] so bash doesn't count these and
what is in between them in the length of the prompt string.

The only way to get the colors in without messing up normal functioning
of the prompt is to use PROMPT_COMMAND to set PS1, with colors based
dynamically on the state of the tree.

In my current version (which I haven't had time to properly send out,
sorry!) it can do both using the same __git_ps1 function. But only color
in the PROMPT_COMMAND mode for the reason laid out above.

Having said that, I think there's another benefit to using
PROMPT_COMMAND; I think it is more elegant to use a function via
PROMPT_COMMAND (now that I know of it), than using a function via
command substitution inside the PS1.

I guess your (and my) confusion is more caused by unfamiliarity with
this feature of bash than it being used. Is that correct?

*desperately trying to get out of confused mode*

Cheers

Simon



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-02 Thread Junio C Hamano
Simon Oosthoek s.oosth...@xs4all.nl writes:

 ... This is
 prevented (and quite the norm in static PS1 strings) by enclosing the
 terminal code for color inside \[ and \] so bash doesn't count these and
 what is in between them in the length of the prompt string.

Ah, OK, and these \[ things \] behave like other magics like \h and \W
in PS1 in that PS1='\h $(echo_bs_w)' will not work as expected with

echo_bs_w () {
printf %s \\W
}

hence cannot be used in __git_ps1 function that is called as $(command
substitution).

That was what I was missing.

 The only way to get the colors in without messing up normal functioning
 of the prompt is to use PROMPT_COMMAND to set PS1, with colors based
 dynamically on the state of the tree.

OK.  Thanks for explanation.


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Simon Oosthoek

On 09/28/2012 07:58 PM, Junio C Hamano wrote:

Simon Oosthoek soosth...@nieuwland.nl writes:


+# __git_ps1_pc accepts 0 arguments (for now)
+# It is meant to be used as PROMPT_COMMAND, it sets PS1
+__git_ps1_pc ()
+{
+   local g=$(__gitdir)
+   if [ -n $g ]; then
+...
+   fi
+}


This looks awfully similar to the existing code in __git_ps1
function.  Without refactoring to share the logic between them, it
won't be maintainable.



I agree that it's ugly. How about the following:

I modified __git_ps1 to work both in PROMPT_COMMAND mode and in that 
mode support color hints.


This way there's one function, so no overlap.

Shall I send patches for the two changes separately (to support 
PROMPT_COMMAND mode and another to support color hints) or in one?


And what about zsh support? I doubt the PROMPT_COMMAND thing is 
compatible with zsh, but the command substitution mode should probably 
work, unless it is already broken by the use of % to indicate untracked 
files (when GIT_PS1_SHOWUNTRACKEDFILES is set). Unless it is tested 
further in zsh, I'd say it might be better not to claim zsh is supported.


Cheers

Simon
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Simon Oosthoek
On 01/10/12 19:16, Junio C Hamano wrote:
 Simon Oosthoek soosth...@nieuwland.nl writes:
 
 On 09/28/2012 07:58 PM, Junio C Hamano wrote:
 Simon Oosthoek soosth...@nieuwland.nl writes:

 +# __git_ps1_pc accepts 0 arguments (for now)
 +# It is meant to be used as PROMPT_COMMAND, it sets PS1
 +__git_ps1_pc ()
 +{
 +  local g=$(__gitdir)
 +  if [ -n $g ]; then
 +...
 +  fi
 +}

 This looks awfully similar to the existing code in __git_ps1
 function.  Without refactoring to share the logic between them, it
 won't be maintainable.


 I agree that it's ugly. How about the following:

 I modified __git_ps1 to work both in PROMPT_COMMAND mode and in that
 mode support color hints.

 This way there's one function, so no overlap.
 
 I think the logical progression would be
 
  - there are parts of __git_ps1 you want to reuse for your
__git_ps1_pc; separate that part out as a helper function,
and make __git_ps1 call it, without changing what __git_ps1
does (i.e. no colors, etc.)
 
  - add __git_ps1_pc that uses the helper function you separated
out.
 
  - add whatever bells and whistles that are useful for users of
either __git_ps1 or __git_ps1_pc to that helper function.
 
 

Since this is the shell, it could turn out to be ugly this way:

function ps1_common {
set global variable (branchname, dirty state, untracked files,
divergence from upstream, etc.)
}

function __git_ps1 {
call ps1_common
print PS1 string based on format string or default (color in prompt
isn't an option) and include global variables where necessary
}

function __git_ps1_pc {
call ps1_common
set PS1=
based on hardcoded PS1 definition, expand the PS1 using global
variables (add color if requested)
}

The problem I see is that it would involve a lot of global variables
visible in the shell (OTOH, they could be used by other scripts, but
only when using this prompt ;-).
Or you could print a string, which can be caught in the relevant _ps1
function, but then this string needs to be chopped up and processed (by
a bunch of awk oneliners or bash-voodoo)

The latter introduces so much overhead (in processing and
maintainability) that I think it should not be considered.

That leaves passing the variables from one function to another using
globally scoped variables in the shell.

It can be done, but the current combined implementation has only the
global variables set by the user (GIT_PS1_SHOWDIRTYSTATE and so on) and
the rest remains local to the function.

The main obstacle to better code here is the need to work around the
shell's oddities. :-(

Cheers

Simon


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 I agree that it's ugly. How about the following:

 I modified __git_ps1 to work both in PROMPT_COMMAND mode and in that
 mode support color hints.

 This way there's one function, so no overlap.

 I think the logical progression would be

  - there are parts of __git_ps1 you want to reuse for your
__git_ps1_pc; separate that part out as a helper function,
and make __git_ps1 call it, without changing what __git_ps1
does (i.e. no colors, etc.)

  - add __git_ps1_pc that uses the helper function you separated
out.

  - add whatever bells and whistles that are useful for users of
either __git_ps1 or __git_ps1_pc to that helper function.

Hrm, let me ask a stupid question.  Why do we even need __git_ps1_pc
in the first place?  Wouldn't it be just the matter of

PROMPT_COMMAND='__git_ps1 %s'

once you have __git_ps1 that works?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Simon Oosthoek
On 01/10/12 21:13, Junio C Hamano wrote:

 Hrm, let me ask a stupid question.  Why do we even need __git_ps1_pc
 in the first place?  Wouldn't it be just the matter of
 
   PROMPT_COMMAND='__git_ps1 %s'
 
 once you have __git_ps1 that works?

Apart from one small detail, PS1 must be set directly when __git_ps1 is
called as a PROMPT_COMMAND, while in command substitution mode,
__git_ps1 needs to put out a string value to substitute...

This is the way it works now (I'll send the patch later this week, I
want to test it some more...)

/Simon
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Junio C Hamano
Simon Oosthoek soosth...@nieuwland.nl writes:

 On 01/10/12 21:13, Junio C Hamano wrote:

 Hrm, let me ask a stupid question.  Why do we even need __git_ps1_pc
 in the first place?  Wouldn't it be just the matter of
 
  PROMPT_COMMAND='__git_ps1 %s'
 
 once you have __git_ps1 that works?

 Apart from one small detail, PS1 must be set directly when __git_ps1 is
 called as a PROMPT_COMMAND, while in command substitution mode,
 __git_ps1 needs to put out a string value to substitute...

Now you lost me.  The documentation of PROMPT_COMMAND in man bash
says this:

   PROMPT_COMMAND
  If set, the value is executed as a command prior to
  issuing each primary prompt.

So yes, if you say PROMPT_COMMAND='whatever', you will get output
from 'whatever' followed by what $PS1 would normally give you.  
If you do not want to see PS1 after 'whatever' gives you, you have
to set it to an empty string.

On the other hand, they way people have been using __git_ps1 is (as
described in the prompt script) to do something like this:

PS1='...cruft... $(__git_ps1 %s) ...cruft...'

To keep supporting them, __git_ps1 has to be a function that writes
the prompt string to its standard output.  The external interface of
PROMPT_COMMAND also is that it wants a command that emits the string
desired for the prompt to its standard output.  I do not see any
when it is used like this, X, but when it is used like that, Y
kind of issue around it, either.

So what is the problem
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Simon Oosthoek
On 01/10/12 21:54, Junio C Hamano wrote:
 Now you lost me.  The documentation of PROMPT_COMMAND in man bash
 says this:
 
PROMPT_COMMAND
   If set, the value is executed as a command prior to
   issuing each primary prompt.
 
 So yes, if you say PROMPT_COMMAND='whatever', you will get output
 from 'whatever' followed by what $PS1 would normally give you.  
 If you do not want to see PS1 after 'whatever' gives you, you have
 to set it to an empty string.
 
 On the other hand, they way people have been using __git_ps1 is (as
 described in the prompt script) to do something like this:
 
   PS1='...cruft... $(__git_ps1 %s) ...cruft...'
 
 To keep supporting them, __git_ps1 has to be a function that writes
 the prompt string to its standard output.  The external interface of
 PROMPT_COMMAND also is that it wants a command that emits the string
 desired for the prompt to its standard output.  I do not see any
 when it is used like this, X, but when it is used like that, Y
 kind of issue around it, either.
 
 So what is the problem
 

Well, I hadn't thought about that way of using it. It works in a way...

But PS1 is set and interpreted in a special way by bash (I gather from
examples, I'm kind of confused by it).

It's possible to set PS1 to nothing and print a string from
PROMPT_COMMAND, but then you miss out on all the features of the PS1
interpretation by bash and compared to the use of __git_ps1 at the
moment, it has to put out quite a different string. Because if you like
to see user@host+workdir (git-status)[$#]
the current users of __git_ps1 say PS1=\u@host+\w $(__git_ps1 %s)\$
, but all __git+ps1 has to put out is (branch) or (branch *), etc.

If it has to print the same prompt in PC mode, it has to add all the
user/host/workdir/[$#] data as well, withouth being able to use the bash
internal interpretation (because that is only working when PS1 is set).

The example(s) I found when googling for a solution were to set PS1
inside the PC function, in a way that it was possible to add color
encodings, without messing up the wrapping. This is _impossible_ using
command substitution, because then bash doesn't interpret the \[ and \]
around the color codes, and that messes up the accounting of how long
the prompt string is.

/Simon

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-10-01 Thread Junio C Hamano
Simon Oosthoek s.oosth...@xs4all.nl writes:

 It's possible to set PS1 to nothing and print a string from
 PROMPT_COMMAND, but then you miss out on all the features of the PS1
 interpretation by bash and compared to the use of __git_ps1 at the
 moment, it has to put out quite a different string. Because if you like
 to see user@host+workdir (git-status)[$#]
 the current users of __git_ps1 say PS1=\u@host+\w $(__git_ps1 %s)\$
 , but all __git+ps1 has to put out is (branch) or (branch *), etc.

 If it has to print the same prompt in PC mode, it has to add all the
 user/host/workdir/[$#] data as well, withouth being able to use the bash
 internal interpretation (because that is only working when PS1 is set).

The longer I read your explanation, the less useful the PC mode
sounds like, at least to me.  So why does an user even want to use
such a mechanism, instead of PS1?  And even if the user wants to use
it by doing \w, \u etc. himself, she can do that with

PROMPT_COMMAND='
PS1=$(printf \u \h \w %s$  $(__git_ps1 %s))
'

just fine, no?

So I still do not see the problem, even taking your Set PS1 in the
command, without spitting anything out of the command use case into
account.

Confused
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add __git_ps1_pc to use as PROMPT_COMMAND

2012-09-28 Thread Junio C Hamano
Simon Oosthoek soosth...@nieuwland.nl writes:

 +# __git_ps1_pc accepts 0 arguments (for now)
 +# It is meant to be used as PROMPT_COMMAND, it sets PS1
 +__git_ps1_pc ()
 +{
 + local g=$(__gitdir)
 + if [ -n $g ]; then
 +...
 + fi
 +}

This looks awfully similar to the existing code in __git_ps1
function.  Without refactoring to share the logic between them, it
won't be maintainable.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html