mirror of
https://github.com/arl/gitmux.git
synced 2026-09-10 07:26:18 -04:00
allow flexible display for output format of git status (#21)
* changes from casonadams: - added options in cfg file to show or hide remote information - Consider possibility to choose/reorder/remove the info shown #14 fix - updated test cases to accomidate changes to code base - better docs, added second delm option, more flexible formatting - fixed tests to run on travis CI - fixed tests to run on travis CI - adding README info for cfg options in dynamic layout output - making display output not break if missing, plus making spacing strings more flexible - adding usage in READ around display features - fixed typo in README * changes from salarkhan - match string exactly, remove regexp - don't call git, create a synthetic status to compare against - use "Symbol-Thing" instead of the actual symbols, in case they change - note that divergence is coupled to remote. maybe these should be split - add empty test case - no need to have a test for every single permutation, one example should suffice * display -> layout Co-authored-by: Cason Adams <casonadams@gmail.com>
This commit is contained in:
parent
a2244005d4
commit
9846b104da
16
README.md
16
README.md
|
|
@ -51,13 +51,13 @@ Add this line to your `.tmux.conf`:
|
|||
|
||||
## Customizing
|
||||
|
||||
`gitmux` output can be customized via a configuration file in YAML format.
|
||||
`gitmux` output can be customized via a configuration file in YAML format.
|
||||
|
||||
First, save the default configuration to a new file
|
||||
|
||||
gitmux -printcfg > .gitmux.conf
|
||||
|
||||
Open `.gitmux.conf` and modify it, replacing symbols and colors to suit your needs.
|
||||
Open `.gitmux.conf` and modify it, replacing symbols and colors to suit your needs.
|
||||
Ensure the file is valid by adding the `-dbg` flag
|
||||
|
||||
gitmux -dbg -cfg .gitmux.conf
|
||||
|
|
@ -66,10 +66,17 @@ Modify the line in `.tmux.conf`, passing the path of the configuration file as a
|
|||
|
||||
gitmux -cfg .gitmux.conf
|
||||
|
||||
|
||||
`gitmux` configuration is split into 2 sections:
|
||||
`gitmux` configuration is split into 3 sections:
|
||||
- symbols: they are just strings of unicode characters
|
||||
- styles: they are tmux format strings (`man tmux` for reference)
|
||||
- layout: is the layout of git components & separators
|
||||
|
||||
Example layouts:
|
||||
```
|
||||
layout: [branch, '..', remote, ' - ', flags]
|
||||
layout: [branch]
|
||||
layout: [flags, ' && ', branch]
|
||||
```
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
|
@ -78,6 +85,7 @@ Please report anything by [filing an issue](https://github.com/arl/gitmux/issues
|
|||
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ type Config struct {
|
|||
// Styles contains the tmux style strings for symbols and Git status
|
||||
// components.
|
||||
Styles styles
|
||||
// Layout sets the output format of the Git status.
|
||||
Layout []string `yaml:",flow"`
|
||||
}
|
||||
|
||||
type symbols struct {
|
||||
|
|
@ -71,6 +73,7 @@ var DefaultCfg = Config{
|
|||
Stashed: "#[fg=cyan,bold]",
|
||||
Clean: "#[fg=green,bold]",
|
||||
},
|
||||
Layout: []string{"branch", "..", "remote", " - ", "flags"},
|
||||
}
|
||||
|
||||
// A Formater formats git status to a tmux style string.
|
||||
|
|
@ -88,20 +91,31 @@ func (f *Formater) Format(w io.Writer, st *gitstatus.Status) error {
|
|||
// overall working tree state
|
||||
if f.st.IsInitial {
|
||||
fmt.Fprintf(w, "%s%s [no commits yet]", f.Styles.Branch, f.st.LocalBranch)
|
||||
goto fileCounts
|
||||
f.flags()
|
||||
_, err := f.b.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
f.specialState()
|
||||
f.remote()
|
||||
|
||||
fileCounts:
|
||||
f.flags()
|
||||
|
||||
f.format()
|
||||
_, err := f.b.WriteTo(w)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *Formater) format() {
|
||||
for _, order := range f.Layout {
|
||||
switch order {
|
||||
case "branch":
|
||||
f.specialState()
|
||||
case "remote":
|
||||
f.remote()
|
||||
case "flags":
|
||||
f.flags()
|
||||
default:
|
||||
f.b.WriteString(order)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formater) specialState() {
|
||||
f.clear()
|
||||
switch f.st.State {
|
||||
|
|
@ -128,7 +142,7 @@ func (f *Formater) specialState() {
|
|||
func (f *Formater) remote() {
|
||||
f.clear()
|
||||
if f.st.RemoteBranch != "" {
|
||||
fmt.Fprintf(&f.b, "..%s%s", f.Styles.Remote, f.st.RemoteBranch)
|
||||
fmt.Fprintf(&f.b, "%s%s", f.Styles.Remote, f.st.RemoteBranch)
|
||||
f.divergence()
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +178,6 @@ func (f *Formater) divergence() {
|
|||
|
||||
func (f *Formater) flags() {
|
||||
f.clear()
|
||||
f.b.WriteString(" - ")
|
||||
|
||||
if f.st.IsClean {
|
||||
fmt.Fprintf(&f.b, "%s%s", f.Styles.Clean, f.Symbols.Clean)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package tmux
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/arl/gitstatus"
|
||||
|
|
@ -12,21 +13,23 @@ func TestFormater_flags(t *testing.T) {
|
|||
name string
|
||||
styles styles
|
||||
symbols symbols
|
||||
layout []string
|
||||
st *gitstatus.Status
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "clean flag",
|
||||
styles: styles{
|
||||
Clean: "CleanStyle",
|
||||
Clean: "StyleClean",
|
||||
},
|
||||
symbols: symbols{
|
||||
Clean: "CleanSymbol",
|
||||
Clean: "SymbolClean",
|
||||
},
|
||||
layout: []string{"branch", "..", "remote", " - ", "flags"},
|
||||
st: &gitstatus.Status{
|
||||
IsClean: true,
|
||||
},
|
||||
want: clear + " - CleanStyleCleanSymbol",
|
||||
want: clear + "StyleCleanSymbolClean",
|
||||
},
|
||||
{
|
||||
name: "mixed flags",
|
||||
|
|
@ -40,6 +43,7 @@ func TestFormater_flags(t *testing.T) {
|
|||
Stashed: "SymbolStash",
|
||||
Staged: "SymbolStaged",
|
||||
},
|
||||
layout: []string{"branch", "..", "remote", " - ", "flags"},
|
||||
st: &gitstatus.Status{
|
||||
NumStashed: 1,
|
||||
Porcelain: gitstatus.Porcelain{
|
||||
|
|
@ -47,7 +51,7 @@ func TestFormater_flags(t *testing.T) {
|
|||
NumStaged: 3,
|
||||
},
|
||||
},
|
||||
want: clear + " - StyleStagedSymbolStaged3 StyleModSymbolMod2 StyleStashSymbolStash1",
|
||||
want: clear + "StyleStagedSymbolStaged3 StyleModSymbolMod2 StyleStashSymbolStash1",
|
||||
},
|
||||
{
|
||||
name: "mixed flags 2",
|
||||
|
|
@ -65,13 +69,13 @@ func TestFormater_flags(t *testing.T) {
|
|||
NumUntracked: 17,
|
||||
},
|
||||
},
|
||||
want: clear + " - StyleConflictSymbolConflict42 StyleUntrackedSymbolUntracked17",
|
||||
want: clear + "StyleConflictSymbolConflict42 StyleUntrackedSymbolUntracked17",
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
f := &Formater{
|
||||
Config: Config{Styles: tc.styles, Symbols: tc.symbols},
|
||||
Config: Config{Styles: tc.styles, Symbols: tc.symbols, Layout: tc.layout},
|
||||
st: tc.st,
|
||||
}
|
||||
f.flags()
|
||||
|
|
@ -156,3 +160,111 @@ func TestFormater_divergence(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormater_Format(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
styles styles
|
||||
symbols symbols
|
||||
layout []string
|
||||
st *gitstatus.Status
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default format",
|
||||
styles: styles{
|
||||
Clean: "StyleClean",
|
||||
Branch: "StyleBranch",
|
||||
Modified: "StyleMod",
|
||||
Remote: "StyleRemote",
|
||||
},
|
||||
symbols: symbols{
|
||||
Branch: "SymbolBranch",
|
||||
Clean: "SymbolClean",
|
||||
Modified: "SymbolMod",
|
||||
},
|
||||
layout: []string{"branch", "..", "remote", " - ", "flags"},
|
||||
st: &gitstatus.Status{
|
||||
Porcelain: gitstatus.Porcelain{
|
||||
LocalBranch: "Local",
|
||||
RemoteBranch: "Remote",
|
||||
NumModified: 2,
|
||||
},
|
||||
},
|
||||
want: clear + "StyleBranchSymbolBranch" + clear + "Local" + ".." + clear + "StyleRemoteRemote" + clear + " - " + clear + "StyleModSymbolMod2",
|
||||
},
|
||||
{
|
||||
name: "branch, different delimiter, flags",
|
||||
styles: styles{
|
||||
Branch: "StyleBranch",
|
||||
Remote: "StyleRemote",
|
||||
Modified: "StyleMod",
|
||||
},
|
||||
symbols: symbols{
|
||||
Branch: "SymbolBranch",
|
||||
Ahead: "SymbolAhead",
|
||||
Modified: "SymbolMod",
|
||||
},
|
||||
layout: []string{"branch", " ~~ ", "flags"},
|
||||
st: &gitstatus.Status{
|
||||
Porcelain: gitstatus.Porcelain{
|
||||
LocalBranch: "Local",
|
||||
RemoteBranch: "Remote",
|
||||
NumModified: 2,
|
||||
AheadCount: 1,
|
||||
},
|
||||
},
|
||||
want: clear + "StyleBranchSymbolBranch" + clear + "Local" + " ~~ " + clear + "StyleModSymbolMod2",
|
||||
},
|
||||
{
|
||||
name: "remote only",
|
||||
styles: styles{
|
||||
Branch: "StyleBranch",
|
||||
Remote: "StyleRemote",
|
||||
},
|
||||
symbols: symbols{
|
||||
Branch: "SymbolBranch",
|
||||
Ahead: "SymbolAhead",
|
||||
},
|
||||
layout: []string{"remote"},
|
||||
st: &gitstatus.Status{
|
||||
Porcelain: gitstatus.Porcelain{
|
||||
LocalBranch: "Local",
|
||||
RemoteBranch: "Remote",
|
||||
AheadCount: 1,
|
||||
},
|
||||
},
|
||||
want: clear + "StyleRemoteRemote" + clear + " SymbolAhead1",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
styles: styles{
|
||||
Branch: "StyleBranch",
|
||||
Modified: "StyleMod",
|
||||
},
|
||||
symbols: symbols{
|
||||
Branch: "SymbolBranch",
|
||||
Modified: "SymbolMod",
|
||||
},
|
||||
layout: []string{},
|
||||
st: &gitstatus.Status{
|
||||
Porcelain: gitstatus.Porcelain{
|
||||
LocalBranch: "Local",
|
||||
NumModified: 2,
|
||||
},
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
f := &Formater{
|
||||
Config: Config{Styles: tc.styles, Symbols: tc.symbols, Layout: tc.layout},
|
||||
}
|
||||
|
||||
f.Format(os.Stdout, tc.st)
|
||||
f.format()
|
||||
require.EqualValues(t, tc.want, f.b.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
go.sum
1
go.sum
|
|
@ -4,6 +4,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
|
|
|||
Loading…
Reference in a new issue