mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-02-21 02:55:37 -08:00
feat: git segment branch context color
This commit is contained in:
parent
4e27952b3f
commit
c41866171d
|
@ -68,5 +68,15 @@ Local changes can also shown by default using the following syntax for both the
|
||||||
|
|
||||||
- working_color: `string` [hex color code][colors] - foreground color for the working area status - defaults to segment foreground
|
- working_color: `string` [hex color code][colors] - foreground color for the working area status - defaults to segment foreground
|
||||||
- staging_color: `string` [hex color code][colors] - foreground color for the staging area status - defaults to segment foreground
|
- staging_color: `string` [hex color code][colors] - foreground color for the staging area status - defaults to segment foreground
|
||||||
|
- status_colors_enabled: `boolean` - color the segment based on the repository status - defaults to `false`
|
||||||
|
- color_background: `boolean` - color background or foreground - defaults to `true`
|
||||||
|
- local_changes_color: `string` [hex color code][colors] - segment color when there are local changes - defaults to segment
|
||||||
|
foreground/background (see `color_background`)
|
||||||
|
- ahead_and_behind_color: `string` [hex color code][colors] - segment color when the branch is ahead and behind -
|
||||||
|
defaults to segment foreground/background (see `color_background`)
|
||||||
|
- behind_color: `string` [hex color code][colors] - segment color when the branch is behind - defaults to segment
|
||||||
|
foreground/background (see `color_background`)
|
||||||
|
- ahead_color: `string` [hex color code][colors] - segment color when the branch is ahead - defaults to segment
|
||||||
|
foreground/background (see `color_background`)
|
||||||
|
|
||||||
[colors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
|
[colors]: https://htmlcolorcodes.com/color-chart/material-design-color-chart/
|
||||||
|
|
|
@ -25,6 +25,7 @@ type gitStatus struct {
|
||||||
added int
|
added int
|
||||||
modified int
|
modified int
|
||||||
untracked int
|
untracked int
|
||||||
|
changed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *gitStatus) string(prefix string, color string) string {
|
func (s *gitStatus) string(prefix string, color string) string {
|
||||||
|
@ -99,6 +100,16 @@ const (
|
||||||
WorkingColor Property = "working_color"
|
WorkingColor Property = "working_color"
|
||||||
//StagingColor if set, the color to use on the staging area
|
//StagingColor if set, the color to use on the staging area
|
||||||
StagingColor Property = "staging_color"
|
StagingColor Property = "staging_color"
|
||||||
|
//StatusColorsEnabled enables status colors
|
||||||
|
StatusColorsEnabled Property = "status_colors_enabled"
|
||||||
|
//LocalChangesColor if set, the color to use when there are local changes
|
||||||
|
LocalChangesColor Property = "local_changes_color"
|
||||||
|
//AheadAndBehindColor if set, the color to use when the branch is ahead and behind the remote
|
||||||
|
AheadAndBehindColor Property = "ahead_and_behind_color"
|
||||||
|
//BehindColor if set, the color to use when the branch is ahead and behind the remote
|
||||||
|
BehindColor Property = "behind_color"
|
||||||
|
//AheadColor if set, the color to use when the branch is ahead and behind the remote
|
||||||
|
AheadColor Property = "ahead_color"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *git) enabled() bool {
|
func (g *git) enabled() bool {
|
||||||
|
@ -111,6 +122,10 @@ func (g *git) enabled() bool {
|
||||||
|
|
||||||
func (g *git) string() string {
|
func (g *git) string() string {
|
||||||
g.setGitStatus()
|
g.setGitStatus()
|
||||||
|
if g.props.getBool(StatusColorsEnabled, false) {
|
||||||
|
g.SetStatusColor()
|
||||||
|
}
|
||||||
|
// g.getGitColor()
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
// branchName
|
// branchName
|
||||||
if g.repo.upstream != "" && g.props.getBool(DisplayUpstreamIcon, false) {
|
if g.repo.upstream != "" && g.props.getBool(DisplayUpstreamIcon, false) {
|
||||||
|
@ -134,13 +149,17 @@ func (g *git) string() string {
|
||||||
} else if g.repo.upstream == "" {
|
} else if g.repo.upstream == "" {
|
||||||
fmt.Fprintf(buffer, " %s", g.props.getString(BranchGoneIcon, "\u2262"))
|
fmt.Fprintf(buffer, " %s", g.props.getString(BranchGoneIcon, "\u2262"))
|
||||||
}
|
}
|
||||||
staging := g.repo.staging.string(g.props.getString(LocalStagingIcon, "\uF046"), g.props.getColor(StagingColor, g.props.foreground))
|
if g.repo.staging.changed {
|
||||||
working := g.repo.working.string(g.props.getString(LocalWorkingIcon, "\uF044"), g.props.getColor(WorkingColor, g.props.foreground))
|
staging := g.repo.staging.string(g.props.getString(LocalStagingIcon, "\uF046"), g.props.getColor(StagingColor, g.props.foreground))
|
||||||
fmt.Fprint(buffer, staging)
|
fmt.Fprint(buffer, staging)
|
||||||
if staging != "" && working != "" {
|
}
|
||||||
|
if g.repo.staging.changed && g.repo.working.changed {
|
||||||
fmt.Fprint(buffer, g.props.getString(StatusSeparatorIcon, " |"))
|
fmt.Fprint(buffer, g.props.getString(StatusSeparatorIcon, " |"))
|
||||||
}
|
}
|
||||||
fmt.Fprint(buffer, working)
|
if g.repo.working.changed {
|
||||||
|
working := g.repo.working.string(g.props.getString(LocalWorkingIcon, "\uF044"), g.props.getColor(WorkingColor, g.props.foreground))
|
||||||
|
fmt.Fprint(buffer, working)
|
||||||
|
}
|
||||||
if g.props.getBool(DisplayStashCount, false) && g.repo.stashCount != "" {
|
if g.props.getBool(DisplayStashCount, false) && g.repo.stashCount != "" {
|
||||||
fmt.Fprintf(buffer, " %s%s", g.props.getString(StashCountIcon, "\uF692"), g.repo.stashCount)
|
fmt.Fprintf(buffer, " %s%s", g.props.getString(StashCountIcon, "\uF692"), g.repo.stashCount)
|
||||||
}
|
}
|
||||||
|
@ -185,6 +204,27 @@ func (g *git) setGitStatus() {
|
||||||
g.repo.stashCount = g.getStashContext()
|
g.repo.stashCount = g.getStashContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *git) SetStatusColor() {
|
||||||
|
if g.props.getBool(ColorBackground, true) {
|
||||||
|
g.props.background = g.getStatusColor(g.props.background)
|
||||||
|
} else {
|
||||||
|
g.props.foreground = g.getStatusColor(g.props.foreground)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *git) getStatusColor(defaultValue string) string {
|
||||||
|
if g.repo.staging.changed || g.repo.working.changed {
|
||||||
|
return g.props.getColor(LocalChangesColor, defaultValue)
|
||||||
|
} else if g.repo.ahead > 0 && g.repo.behind > 0 {
|
||||||
|
return g.props.getColor(AheadAndBehindColor, defaultValue)
|
||||||
|
} else if g.repo.ahead > 0 {
|
||||||
|
return g.props.getColor(AheadColor, defaultValue)
|
||||||
|
} else if g.repo.behind > 0 {
|
||||||
|
return g.props.getColor(BehindColor, defaultValue)
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
func (g *git) getGitCommandOutput(args ...string) string {
|
func (g *git) getGitCommandOutput(args ...string) string {
|
||||||
args = append([]string{"-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
args = append([]string{"-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
||||||
val, _ := g.env.runCommand("git", args...)
|
val, _ := g.env.runCommand("git", args...)
|
||||||
|
@ -287,6 +327,7 @@ func (g *git) parseGitStats(output []string, working bool) *gitStatus {
|
||||||
status.modified++
|
status.modified++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
status.changed = status.added > 0 || status.deleted > 0 || status.modified > 0 || status.unmerged > 0 || status.untracked > 0
|
||||||
return &status
|
return &status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,6 +309,7 @@ func TestParseGitStatsWorking(t *testing.T) {
|
||||||
assert.Equal(t, 1, status.added)
|
assert.Equal(t, 1, status.added)
|
||||||
assert.Equal(t, 1, status.deleted)
|
assert.Equal(t, 1, status.deleted)
|
||||||
assert.Equal(t, 2, status.untracked)
|
assert.Equal(t, 2, status.untracked)
|
||||||
|
assert.True(t, status.changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseGitStatsStaging(t *testing.T) {
|
func TestParseGitStatsStaging(t *testing.T) {
|
||||||
|
@ -330,6 +331,7 @@ func TestParseGitStatsStaging(t *testing.T) {
|
||||||
assert.Equal(t, 1, status.added)
|
assert.Equal(t, 1, status.added)
|
||||||
assert.Equal(t, 2, status.deleted)
|
assert.Equal(t, 2, status.deleted)
|
||||||
assert.Equal(t, 1, status.untracked)
|
assert.Equal(t, 1, status.untracked)
|
||||||
|
assert.True(t, status.changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseGitStatsNoChanges(t *testing.T) {
|
func TestParseGitStatsNoChanges(t *testing.T) {
|
||||||
|
@ -340,6 +342,7 @@ func TestParseGitStatsNoChanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
status := g.parseGitStats(output, false)
|
status := g.parseGitStats(output, false)
|
||||||
assert.Equal(t, expected, status)
|
assert.Equal(t, expected, status)
|
||||||
|
assert.False(t, status.changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseGitStatsInvalidLine(t *testing.T) {
|
func TestParseGitStatsInvalidLine(t *testing.T) {
|
||||||
|
@ -351,6 +354,7 @@ func TestParseGitStatsInvalidLine(t *testing.T) {
|
||||||
}
|
}
|
||||||
status := g.parseGitStats(output, false)
|
status := g.parseGitStats(output, false)
|
||||||
assert.Equal(t, expected, status)
|
assert.Equal(t, expected, status)
|
||||||
|
assert.False(t, status.changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bootstrapUpstreamTest(upstream string) *git {
|
func bootstrapUpstreamTest(upstream string) *git {
|
||||||
|
@ -397,3 +401,160 @@ func TestGetUpstreamSymbolGit(t *testing.T) {
|
||||||
upstreamIcon := g.getUpstreamSymbol()
|
upstreamIcon := g.getUpstreamSymbol()
|
||||||
assert.Equal(t, "G", upstreamIcon)
|
assert.Equal(t, "G", upstreamIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorLocalChangesStaging(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{
|
||||||
|
changed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
LocalChangesColor: expected,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorLocalChangesWorking(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{},
|
||||||
|
working: &gitStatus{
|
||||||
|
changed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
LocalChangesColor: expected,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorAheadAndBehind(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{},
|
||||||
|
working: &gitStatus{},
|
||||||
|
ahead: 1,
|
||||||
|
behind: 3,
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
AheadAndBehindColor: expected,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorAhead(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{},
|
||||||
|
working: &gitStatus{},
|
||||||
|
ahead: 1,
|
||||||
|
behind: 0,
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
AheadColor: expected,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorBehind(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{},
|
||||||
|
working: &gitStatus{},
|
||||||
|
ahead: 0,
|
||||||
|
behind: 5,
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
BehindColor: expected,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor("#fg1111"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStatusColorDefault(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{},
|
||||||
|
working: &gitStatus{},
|
||||||
|
ahead: 0,
|
||||||
|
behind: 0,
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
BehindColor: "#BD8BDE",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.Equal(t, expected, g.getStatusColor(expected))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetStatusColorBackground(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{
|
||||||
|
changed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
LocalChangesColor: "#BD8BDE",
|
||||||
|
ColorBackground: false,
|
||||||
|
},
|
||||||
|
foreground: "#ffffff",
|
||||||
|
background: "#111111",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.SetStatusColor()
|
||||||
|
assert.Equal(t, expected, g.props.foreground)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetStatusColorForeground(t *testing.T) {
|
||||||
|
expected := "#BD8BDE"
|
||||||
|
repo := &gitRepo{
|
||||||
|
staging: &gitStatus{
|
||||||
|
changed: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g := &git{
|
||||||
|
repo: repo,
|
||||||
|
props: &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
LocalChangesColor: "#BD8BDE",
|
||||||
|
ColorBackground: true,
|
||||||
|
},
|
||||||
|
foreground: "#ffffff",
|
||||||
|
background: "#111111",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.SetStatusColor()
|
||||||
|
assert.Equal(t, expected, g.props.background)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue