Skip to content

Commit

Permalink
feat: separate layout items with spaces (#91)
Browse files Browse the repository at this point in the history
* feat: separate layout items with spaces

* docs: update layout example

* fix: add space after stash

* feat: add trailing space to stats component

* feat: add trailing space to clean section

* test: trailing spaces on all components

* Remove bytes.Buffer, status functions return strings

* Take care of elements spacing in format()

* Fix spacing in default config

---------

Co-authored-by: Aurélien Rainone <aurelien.rainone@gmail.com>
  • Loading branch information
joshmedeski and arl committed Mar 22, 2023
1 parent 2d1c132 commit 395d66d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .gitmux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ tmux:
# - flags: symbols representing the working tree state, for example `✚ 1 ⚑ 1 … 2`
# - stats: insertions/deletions (lines), for example`Σ56 Δ21`
# - some string `foo`: any other character of string is directly shown, for example `foo` or `|`
layout: [branch, " ", remote-branch, divergence, " - ", flags]
layout: [branch, remote-branch, divergence, " - ", flags]

# Additional configuration options.
options:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ tmux:
clean: '#[fg=green,bold]'
insertions: '#[fg=green]'
deletions: '#[fg=red]'
layout: [branch, .., remote-branch, divergence, ' - ', flags]
layout: [branch, .., remote-branch, divergence, '- ', flags]
options:
branch_max_len: 0
branch_trim: right
Expand Down
2 changes: 1 addition & 1 deletion testdata/default.output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ with some different content

-- empty_file --
-- output.golden --
#[fg=default]#[fg=default]#[fg=white,bold]⎇ #[fg=default]#[fg=white,bold]main#[fg=default] #[fg=default] - #[fg=default]#[fg=green,bold]● 1 #[fg=red,bold]✚ 1 #[fg=cyan,bold]⚑ 1 #[fg=magenta,bold]… 2
#[fg=default]#[fg=default]#[fg=white,bold]⎇ #[fg=default]#[fg=white,bold]main#[fg=default] - #[fg=default]#[fg=green,bold]● 1 #[fg=red,bold]✚ 1 #[fg=cyan,bold]⚑ 1 #[fg=magenta,bold]… 2
136 changes: 71 additions & 65 deletions tmux/formater.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tmux

import (
"bytes"
"fmt"
"io"
"strings"
Expand Down Expand Up @@ -95,7 +94,6 @@ type options struct {
// A Formater formats git status to a tmux style string.
type Formater struct {
Config
b bytes.Buffer
st *gitstatus.Status
}

Expand Down Expand Up @@ -137,133 +135,139 @@ func truncate(s, ellipsis string, max int, dir direction) string {
// Format writes st as json into w.
func (f *Formater) Format(w io.Writer, st *gitstatus.Status) error {
f.st = st
f.clear()

// overall working tree state
// Overall working tree state
if f.st.IsInitial {
branch := truncate(f.st.LocalBranch, f.Options.Ellipsis, f.Options.BranchMaxLen, f.Options.BranchTrim)
fmt.Fprintf(w, "%s%s [no commits yet]", f.Styles.Branch, branch)
f.flags()
_, err := f.b.WriteTo(w)

s := fmt.Sprintf("%s%s%s [no commits yet] %s", f.Styles.Clear, f.Styles.Branch, branch, f.flags())
_, err := io.WriteString(w, s)
return err
}

f.format()
_, err := f.b.WriteTo(w)

_, err := fmt.Fprintf(w, "%s%s", f.Styles.Clear, f.format())
return err
}

func (f *Formater) format() {
func (f *Formater) format() string {
var comps []string

// Add spacing between non-empty components.
joinComps := func() string {
i := 0
for _, s := range comps {
if s != "" {
comps[i] = s
i++
}
}
return strings.Join(comps[:i], " ")
}

sb := strings.Builder{}
for _, item := range f.Layout {
switch item {
case "branch":
f.specialState()
comps = append(comps, f.specialState())
case "remote":
f.remoteBranch()
f.divergence()
comps = append(comps, f.remoteBranch())
comps = append(comps, f.divergence())
case "remote-branch":
f.remoteBranch()
comps = append(comps, f.remoteBranch())
case "divergence":
f.divergence()
comps = append(comps, f.divergence())
case "flags":
f.flags()
comps = append(comps, f.flags())
case "stats":
f.stats()
comps = append(comps, f.stats())
default:
f.clear()
f.b.WriteString(item)
sb.WriteString(joinComps())
sb.WriteString(f.Styles.Clear)
sb.WriteString(item)
comps = comps[:0]
}
}

sb.WriteString(joinComps())
return sb.String()
}

func (f *Formater) specialState() {
f.clear()
func (f *Formater) specialState() string {
s := f.Styles.Clear

switch f.st.State {
case gitstatus.Rebasing:
fmt.Fprintf(&f.b, "%s[rebase] ", f.Styles.State)
s += fmt.Sprintf("%s[rebase] ", f.Styles.State)
case gitstatus.AM:
fmt.Fprintf(&f.b, "%s[am] ", f.Styles.State)
s += fmt.Sprintf("%s[am] ", f.Styles.State)
case gitstatus.AMRebase:
fmt.Fprintf(&f.b, "%s[am-rebase] ", f.Styles.State)
s += fmt.Sprintf("%s[am-rebase] ", f.Styles.State)
case gitstatus.Merging:
fmt.Fprintf(&f.b, "%s[merge] ", f.Styles.State)
s += fmt.Sprintf("%s[merge] ", f.Styles.State)
case gitstatus.CherryPicking:
fmt.Fprintf(&f.b, "%s[cherry-pick] ", f.Styles.State)
s += fmt.Sprintf("%s[cherry-pick] ", f.Styles.State)
case gitstatus.Reverting:
fmt.Fprintf(&f.b, "%s[revert] ", f.Styles.State)
s += fmt.Sprintf("%s[revert] ", f.Styles.State)
case gitstatus.Bisecting:
fmt.Fprintf(&f.b, "%s[bisect] ", f.Styles.State)
s += fmt.Sprintf("%s[bisect] ", f.Styles.State)
case gitstatus.Default:
fmt.Fprintf(&f.b, "%s%s", f.Styles.Branch, f.Symbols.Branch)
s += fmt.Sprintf("%s%s", f.Styles.Branch, f.Symbols.Branch)
}

f.currentRef()
s += f.currentRef()
return s
}

func (f *Formater) remoteBranch() {
func (f *Formater) remoteBranch() string {
if f.st.RemoteBranch == "" {
return
return ""
}

f.clear()
s := f.Styles.Clear

branch := truncate(f.st.RemoteBranch, f.Options.Ellipsis, f.Options.BranchMaxLen, f.Options.BranchTrim)
fmt.Fprintf(&f.b, "%s%s", f.Styles.Remote, branch)
s += fmt.Sprintf("%s%s", f.Styles.Remote, branch)
return s
}

func (f *Formater) divergence() {
func (f *Formater) divergence() string {
if f.st.BehindCount == 0 && f.st.AheadCount == 0 {
return
return ""
}

f.clear()
f.b.WriteByte(' ')
fmt.Fprintf(&f.b, "%s", f.Styles.Divergence)

s := f.Styles.Clear + f.Styles.Divergence
if f.st.BehindCount != 0 {
fmt.Fprintf(&f.b, "%s%d", f.Symbols.Behind, f.st.BehindCount)
s += fmt.Sprintf("%s%d", f.Symbols.Behind, f.st.BehindCount)
}

if f.st.AheadCount != 0 {
fmt.Fprintf(&f.b, "%s%d", f.Symbols.Ahead, f.st.AheadCount)
s += fmt.Sprintf("%s%d", f.Symbols.Ahead, f.st.AheadCount)
}
}

func (f *Formater) clear() {
// clear global style
f.b.WriteString(f.Styles.Clear)
return s
}

func (f *Formater) currentRef() {
f.clear()

func (f *Formater) currentRef() string {
if f.st.IsDetached {
fmt.Fprintf(&f.b, "%s%s%s", f.Styles.Branch, f.Symbols.HashPrefix, f.st.HEAD)
return
return fmt.Sprintf("%s%s%s%s", f.Styles.Clear, f.Styles.Branch, f.Symbols.HashPrefix, f.st.HEAD)
}

branch := truncate(f.st.LocalBranch, f.Options.Ellipsis, f.Options.BranchMaxLen, f.Options.BranchTrim)
fmt.Fprintf(&f.b, "%s%s", f.Styles.Branch, branch)
return fmt.Sprintf("%s%s%s", f.Styles.Clear, f.Styles.Branch, branch)
}

func (f *Formater) flags() {
func (f *Formater) flags() string {
var flags []string
if f.st.IsClean {
if f.st.NumStashed != 0 {
flags = append(flags,
fmt.Sprintf("%s%s%d", f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed))
}

if f.Options.HideClean != true {
if !f.Options.HideClean {
flags = append(flags, fmt.Sprintf("%s%s", f.Styles.Clean, f.Symbols.Clean))
}

f.clear()
f.b.WriteString(strings.Join(flags, " "))
return
return f.Styles.Clear + strings.Join(flags, " ")
}

if f.st.NumStaged != 0 {
Expand Down Expand Up @@ -292,12 +296,13 @@ func (f *Formater) flags() {
}

if len(flags) > 0 {
f.clear()
f.b.WriteString(strings.Join(flags, " "))
return f.Styles.Clear + strings.Join(flags, " ")
}

return ""
}

func (f *Formater) stats() {
func (f *Formater) stats() string {
stats := make([]string, 0, 2)

if f.st.Insertions != 0 {
Expand All @@ -308,8 +313,9 @@ func (f *Formater) stats() {
stats = append(stats, fmt.Sprintf("%s%s%d", f.Styles.Deletions, f.Symbols.Deletions, f.st.Deletions))
}

if len(stats) != 0 {
f.clear()
f.b.WriteString(strings.Join(stats, " "))
if len(stats) == 0 {
return ""
}

return f.Styles.Clear + strings.Join(stats, " ")
}

0 comments on commit 395d66d

Please sign in to comment.