{"thread":{"id":"25600","subject":"Add colors to the prompt for status indicators","startedAt":"2010-10-31T04:14:08Z","lastAt":"2010-11-16T10:49:02Z","messageCount":9,"participants":["Sebastien Douche","Kevin Ballard","Andrew Sayers","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"154864","messageId":"AANLkTi=ZdR4_reQgxL+xRaFE=SaqBYAWTrEuGEbLGynt@mail.gmail.com","threadId":"25600","inReplyTo":null,"subject":"Add colors to the prompt for status indicators","fromName":"Sebastien Douche","fromEmail":"sdouche@gmail.com","sentAt":"2010-10-31T04:14:08Z","receivedAt":"2010-10-31T04:14:08Z","isPatch":false,"sender":{"key":"sdouche@gmail.com","avatar":"https://gravatar.com/avatar/1b4a6cb11f6237ff9dc78b953ce48e416afa42e947143e14273cdc2c7f6f9c1a?d=mp&s=160"},"body":"Hi,\nthe prompt (git-completion.bash) bundled with git is the most\n\"advanced\" I found on the web. But I would add colors for \"status\".\nExample show: * (unstaged) in blue, + (staged in red), $ (stashed) in\ngreen, % (untracked) in bold blue and < > <> (upstream indicator) in\nred.\n\nHow make this?\n\nCheers\n\n-- \nSebastien Douche <sdouche@gmail.com>\nTwitter: http://bit.ly/afkrK (agile, lean, python, git, open source)\n"},{"id":"154867","messageId":"334DB5BC-BE36-4D83-B358-3982DBA38EA1@sb.org","threadId":"25600","inReplyTo":"AANLkTi=ZdR4_reQgxL+xRaFE=SaqBYAWTrEuGEbLGynt@mail.gmail.com","subject":"Re: Add colors to the prompt for status indicators","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-10-31T06:26:21Z","receivedAt":"2010-10-31T06:26:21Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"You could write a shell function that takes a string as an argument and inserts the appropriate color codes based on string substitution, and then just pass the results of __git_ps1 to that function.\n\nSomething like the following might work:\n\nfunction __my_git_colorize_ps1 () {\n    echo \"$1\" | while read -N 1 char; do\n        case \"$char\" in\n            \\*) echo -n $'\\e[34m*\\e[m';;\n            +) echo -n $'\\e[31m+\\e[m';;\n            $) echo -n $'\\e[32m$\\e[m';;\n            %) echo -n $'\\e[1;34m%\\e[m';;\n            \\<|\\>) echo -n $'\\e[31m'\"$char\"$'\\e[m';;\n            *) echo -n \"$char\";;\n        esac\n    done\n}\n\n-Kevin Ballard\n\nOn Oct 30, 2010, at 9:14 PM, Sebastien Douche wrote:\n\n> Hi,\n> the prompt (git-completion.bash) bundled with git is the most\n> \"advanced\" I found on the web. But I would add colors for \"status\".\n> Example show: * (unstaged) in blue, + (staged in red), $ (stashed) in\n> green, % (untracked) in bold blue and < > <> (upstream indicator) in\n> red.\n> \n> How make this?\n> \n> Cheers\n> \n> -- \n> Sebastien Douche <sdouche@gmail.com>\n> Twitter: http://bit.ly/afkrK (agile, lean, python, git, open source)\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"155874","messageId":"4CE04B82.1040804@pileofstuff.org","threadId":"25600","inReplyTo":"AANLkTi=ZdR4_reQgxL+xRaFE=SaqBYAWTrEuGEbLGynt@mail.gmail.com","subject":"Re: Add colors to the prompt for status indicators","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-11-14T20:50:10Z","receivedAt":"2010-11-14T20:50:10Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"Sorry for the delayed response to this one - I'm afraid it's the usual\nwork excuse :)\n\nNon-printing characters need to be surrounded by \\[ and \\] for bash to\ncalculate line lengths correctly.  So far as I can tell, this has to be\nin PS1 itself - bash doesn't recognise it if it's included in a script.\n\nTo see the problem, do this:\n\nOLD_PS1=\"$PS1\"\nPS1=\"\\033[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0m>\"\n\nThen hold down any key - you should see some weird line-wrapping\nbehaviour a little way before the edge of your terminal.  To get your\nold terminal back:\n\nPS1=\"$OLD_PS1\"\n\nTo see what happens when the \"\\[\" characters are embedded in a script:\n\nfoo() {\n echo -e \"\\[\\033[;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0m\\]\"\n}\nPS1='$(foo)>'\n\nThe \"\\[\" and \"\\]\" are represented literally in your terminal, and the\nline-wrapping still occurs.\n\nIt's possible to work around this for a whole script:\n\nfoo() {\n echo -e \"\\033[;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0m\"\n}\nPS1='\\[$(foo)'\\]>'\n\nAs a fan of colourful prompts, I'd be very happy if you found a way\naround this for parts of a script.  But as a fan of fast prompts, I'd\nprefer not to call __git_ps1 more than once :)\n\n\t- Andrew\n"},{"id":"155955","messageId":"19363118-D147-4946-8973-B5DDA4B00985@sb.org","threadId":"25600","inReplyTo":"4CE04B82.1040804@pileofstuff.org","subject":"Re: Add colors to the prompt for status indicators","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-11-15T22:52:47Z","receivedAt":"2010-11-15T22:52:47Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Nov 14, 2010, at 12:50 PM, Andrew Sayers wrote:\n\n> It's possible to work around this for a whole script:\n> \n> foo() {\n> echo -e \"\\033[;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0m\"\n> }\n> PS1='\\[$(foo)'\\]>'\n\nIf $(foo) were to emit some actual printable characters, won't this make\nbash ignore them when calculating line lengths?\n\n> As a fan of colourful prompts, I'd be very happy if you found a way\n> around this for parts of a script.  But as a fan of fast prompts, I'd\n> prefer not to call __git_ps1 more than once :)\n\nI don't think there is any way around this, besides patching bash to be\nintelligent and determine which PS1 characters are printable itself without\nrelying on \\[ and \\].\n\n-Kevin Ballard\n"},{"id":"155959","messageId":"F7A9874A-738C-4BEA-8EDF-0ED1FA7D6ACF@sb.org","threadId":"25600","inReplyTo":"19363118-D147-4946-8973-B5DDA4B00985@sb.org","subject":"Re: Add colors to the prompt for status indicators","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-11-15T23:14:53Z","receivedAt":"2010-11-15T23:14:53Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Nov 15, 2010, at 2:52 PM, Kevin Ballard wrote:\n\n>> As a fan of colourful prompts, I'd be very happy if you found a way\n>> around this for parts of a script.  But as a fan of fast prompts, I'd\n>> prefer not to call __git_ps1 more than once :)\n> \n> I don't think there is any way around this, besides patching bash to be\n> intelligent and determine which PS1 characters are printable itself without\n> relying on \\[ and \\].\n\nI take it back. We can use PROMPT_COMMAND for this, to set up variables\ncontaining what you want.\n\nSomething like the following should work:\n\nfunction __populate_git_ps1_vars () {\n    # this relies on a bashism, so make sure you're actually using bash.\n    # specifically it relies on <<<\"word\".\n    local status\n    local prompt=\"$(__git_ps1 \"%s\")\"\n    # empty out the vars\n    __git_ps1_branch=\"\"\n    __git_ps1_staged=\"\"\n    __git_ps1_unstaged=\"\"\n    __git_ps1_stash=\"\"\n    __git_ps1_untracked=\"\"\n    __git_ps1_upstream=\"\"\n    __git_ps1_left=\"\"\n    __git_ps1_right=\"\"\n    if test -z \"$prompt\"; then\n        # return now\n        return\n    fi\n    __git_ps1_left=\" (\"\n    __git_ps1_right=\")\"\n    __git_ps1_branch=\"$(git rev-parse --symbolic-full-name --abbrev-ref=loose HEAD)\"\n    status=\"${prompt#$__git_ps1_branch}\"\n    while read -N 1 char; do\n        case \"$char\" in\n            \\*) __git_ps1_unstaged=\"$char\" ;;\n            +) __git_ps1_staged=\"$char\" ;;\n            $) __git_ps1_stash=\"$char\" ;;\n            %) __git_ps1_untracked=\"$char\" ;;\n            \\<|\\>) __git_ps1_upstream=\"${__git_ps1_upstream}$char\" ;;\n        esac\n    done <<<\"$status\"\n}\n\nPROMPT_COMMAND=__populate_git_ps1_vars\n\nPS1='\\w${__git_ps1_left}${__git_ps1_branch}\\[\\e[31m\\]${__git_ps1_staged}\\[\\e[34m\\]${__git_ps1_unstaged}\\[\\e[32m\\]${__git_ps1_stash}\\[\\e[1;34m\\]${__git_ps1_untracked}\\[\\e[31m\\]${__git_ps1_upstream}\\[\\e[m\\]${__git_ps1_right}> '\n\n-Kevin Ballard"},{"id":"155983","messageId":"AANLkTimpyug867ccsKA+fLjzDJ8NukQXcPnVJw3Uk4LD@mail.gmail.com","threadId":"25600","inReplyTo":"F7A9874A-738C-4BEA-8EDF-0ED1FA7D6ACF@sb.org","subject":"Re: Add colors to the prompt for status indicators","fromName":"Sebastien Douche","fromEmail":"sdouche@gmail.com","sentAt":"2010-11-16T08:11:14Z","receivedAt":"2010-11-16T08:11:14Z","isPatch":false,"sender":{"key":"sdouche@gmail.com","avatar":"https://gravatar.com/avatar/1b4a6cb11f6237ff9dc78b953ce48e416afa42e947143e14273cdc2c7f6f9c1a?d=mp&s=160"},"body":"On Tue, Nov 16, 2010 at 00:14, Kevin Ballard <kevin@sb.org> wrote:\n> I take it back. We can use PROMPT_COMMAND for this, to set up variables\n> containing what you want.\n>\n> Something like the following should work:\n\nHi Kevin,\ngood job! I looked the git prompt and I'm a bit disappointed with the\ncombination, ps1 can show many items:\n\n#\n%\n+\n*\n$\nREBASE-i|\nREBASE-m|\nMERGING|\nBISECTING|\n< > <> (or u+count u-count u+countu-count)\n\nEach item is \"optional\", so you can have REBASE-i| with * and +, or\nonly *. It seems to complicated to wrap all items (I think of the\nverbose mode for upstream branches). Maybe coding a lua (or Python)\nprompt with a config file.\n\n\n-- \nSebastien Douche <sdouche@gmail.com>\nTwitter: @sdouche (agile, lean, python, git, open source)\n"},{"id":"155984","messageId":"C43669C9-CD42-4D51-BFB9-567AAA422C06@sb.org","threadId":"25600","inReplyTo":"AANLkTimpyug867ccsKA+fLjzDJ8NukQXcPnVJw3Uk4LD@mail.gmail.com","subject":"Re: Add colors to the prompt for status indicators","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-11-16T09:07:19Z","receivedAt":"2010-11-16T09:07:19Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Nov 16, 2010, at 12:11 AM, Sebastien Douche wrote:\n\n> On Tue, Nov 16, 2010 at 00:14, Kevin Ballard <kevin@sb.org> wrote:\n>> I take it back. We can use PROMPT_COMMAND for this, to set up variables\n>> containing what you want.\n>> \n>> Something like the following should work:\n> \n> Hi Kevin,\n> good job! I looked the git prompt and I'm a bit disappointed with the\n> combination, ps1 can show many items:\n> \n> #\n> %\n> +\n> *\n> $\n> REBASE-i|\n> REBASE-m|\n> MERGING|\n> BISECTING|\n> < > <> (or u+count u-count u+countu-count)\n> \n> Each item is \"optional\", so you can have REBASE-i| with * and +, or\n> only *. It seems to complicated to wrap all items (I think of the\n> verbose mode for upstream branches). Maybe coding a lua (or Python)\n> prompt with a config file.\n\nIn the end you need to stuff everything that needs a distinct color into its\nown shell variable. You could just extend the shell function that's doing that\nright now, or you could write a script in another language that emits a\nshell-quoted set of variables suitable for evaling by the shell.\n\n-Kevin Ballard"},{"id":"155990","messageId":"4CE2603D.8080209@drmicha.warpmail.net","threadId":"25600","inReplyTo":"C43669C9-CD42-4D51-BFB9-567AAA422C06@sb.org","subject":"Re: Add colors to the prompt for status indicators","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2010-11-16T10:43:09Z","receivedAt":"2010-11-16T10:43:09Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Kevin Ballard venit, vidit, dixit 16.11.2010 10:07:\n> On Nov 16, 2010, at 12:11 AM, Sebastien Douche wrote:\n> \n>> On Tue, Nov 16, 2010 at 00:14, Kevin Ballard <kevin@sb.org> wrote:\n>>> I take it back. We can use PROMPT_COMMAND for this, to set up variables\n>>> containing what you want.\n>>>\n>>> Something like the following should work:\n>>\n>> Hi Kevin,\n>> good job! I looked the git prompt and I'm a bit disappointed with the\n>> combination, ps1 can show many items:\n>>\n>> #\n>> %\n>> +\n>> *\n>> $\n>> REBASE-i|\n>> REBASE-m|\n>> MERGING|\n>> BISECTING|\n>> < > <> (or u+count u-count u+countu-count)\n>>\n>> Each item is \"optional\", so you can have REBASE-i| with * and +, or\n>> only *. It seems to complicated to wrap all items (I think of the\n>> verbose mode for upstream branches). Maybe coding a lua (or Python)\n>> prompt with a config file.\n> \n> In the end you need to stuff everything that needs a distinct color into its\n> own shell variable. You could just extend the shell function that's doing that\n> right now, or you could write a script in another language that emits a\n> shell-quoted set of variables suitable for evaling by the shell.\n\nAlso, you should get away from parsing individual characters in\n__git_ps1. Characters like + and - are valid in branch names. Coloring\nthem within the name is not quite intended.\n\nI guess the only way is to produce colors within __git_ps1 (based on an\noption). Also, colors would allow to use the same status letters as \"git\nstatus -s\".\n\nMichael\n"},{"id":"155992","messageId":"5FCB4CFB-65F1-4694-AFB4-36A9612BE4F3@sb.org","threadId":"25600","inReplyTo":"4CE2603D.8080209@drmicha.warpmail.net","subject":"Re: Add colors to the prompt for status indicators","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2010-11-16T10:49:02Z","receivedAt":"2010-11-16T10:49:02Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On Nov 16, 2010, at 2:43 AM, Michael J Gruber wrote:\n\n> Kevin Ballard venit, vidit, dixit 16.11.2010 10:07:\n>> On Nov 16, 2010, at 12:11 AM, Sebastien Douche wrote:\n>> \n>>> On Tue, Nov 16, 2010 at 00:14, Kevin Ballard <kevin@sb.org> wrote:\n>>>> I take it back. We can use PROMPT_COMMAND for this, to set up variables\n>>>> containing what you want.\n>>>> \n>>>> Something like the following should work:\n>>> \n>>> Hi Kevin,\n>>> good job! I looked the git prompt and I'm a bit disappointed with the\n>>> combination, ps1 can show many items:\n>>> \n>>> #\n>>> %\n>>> +\n>>> *\n>>> $\n>>> REBASE-i|\n>>> REBASE-m|\n>>> MERGING|\n>>> BISECTING|\n>>> < > <> (or u+count u-count u+countu-count)\n>>> \n>>> Each item is \"optional\", so you can have REBASE-i| with * and +, or\n>>> only *. It seems to complicated to wrap all items (I think of the\n>>> verbose mode for upstream branches). Maybe coding a lua (or Python)\n>>> prompt with a config file.\n>> \n>> In the end you need to stuff everything that needs a distinct color into its\n>> own shell variable. You could just extend the shell function that's doing that\n>> right now, or you could write a script in another language that emits a\n>> shell-quoted set of variables suitable for evaling by the shell.\n> \n> Also, you should get away from parsing individual characters in\n> __git_ps1. Characters like + and - are valid in branch names. Coloring\n> them within the name is not quite intended.\n\nThat's actually handled with the PROMPT_COMMAND version. It uses\n\n  git rev-parse --symbolic-full-name --abbrev-ref=loose HEAD\n\nto get a copy of the branch name, and then removes that from the __git_ps1 output.\nEverything that's left is part of the status.\n\n> I guess the only way is to produce colors within __git_ps1 (based on an\n> option). Also, colors would allow to use the same status letters as \"git\n> status -s\".\n\nThat's how my original version worked (though it had the flaw you mentioned above).\nThe PROMPT_COMMAND version was motivated by the fact that the color escapes need to\nbe embedded directly in PS1 so \\[ and \\] can be used to instruct bash to treat them\nas non-printable characters. If the color codes are emitted by __git_ps1 directly, then\nbash will incorrectly treat them as printable characters and wrap at the wrong spot.\n\nWhat would be nice is a mode for __git_ps1 that emits a string suitable for eval by\nbash that gives every status indicator its own variable. This could be enabled by\nusing something like $(__git_ps1 --shell-quote \" (%s)\"). In this case, __git_ps1 would\nbreak the format string into two parts, by splitting around the %s, and put those in\nthe left/right guard variables.\n\n-Kevin Ballard"}]}