From d9fc3d3d9e6b27a68e15fd55215fbcb4954ee9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Rainone?= <476650+arl@users.noreply.github.com> Date: Tue, 24 Dec 2019 01:05:17 +0100 Subject: [PATCH] Sensible defaults (#11) * Change default options to more sensible ones Remove `-quiet` and `-fmt` option, replace them with `-dbg` since they were only meant to be used if something went wrong. * In debug mod, prints errors on stderr * cosmetics * Keep -q -fmt deprecated/unused options * Improve README.md --- README.md | 39 ++++++++++++++++- format/json/formater.go | 2 + format/tmux/formater.go | 9 ++++ main.go => gitmux.go | 96 +++++++++++++++++++---------------------- 4 files changed, 92 insertions(+), 54 deletions(-) rename main.go => gitmux.go (50%) diff --git a/README.md b/README.md index 43fc61c..5f96d70 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Gitmux [![Build Status](https://travis-ci.com/arl/gitmux.svg?branch=master)](https://travis-ci.com/arl/gitmux) [![Go Report Card](https://goreportcard.com/badge/github.com/arl/gitmux)](https://goreportcard.com/report/github.com/arl/gitmux) + ## **Gitmux** shows **Git** status in your **Tmux** status bar. ![Gitmux in action](https://raw.githubusercontent.com/arl/gitmux/readme-images/demo-small.gif) + ## Description Gitmux is a tmux addon that shows a minimal but useful **Git status** info in your tmux status bar. @@ -24,6 +26,7 @@ And generally there's always a lot of empty space left in tmux status bar. **Gitmux** might be just for you! + ## Installation * **Install a binary release for your platform** (preferred and simplest way) @@ -42,11 +45,43 @@ go get -u github.com/arl/gitmux ## Usage -Simply add this line to your `.tmux.conf` +Simply add this line to your `.tmux.conf`: ``` # Show Git working tree status -set -g status-right '#(gitmux -q -fmt tmux #{pane_current_path})' +set -g status-right '#(gitmux #{pane_current_path})' +``` + + +## Customize status string + +Nothing simpler! First save `gitmux` config in a file: + +``` +gitmux -printcfg > .gitmux.conf +``` + +`gitmux` config is divided in 2 sections: + - symbols are unicode characters + - styles are tmux format strings (man tmux for reference) + +Modify it, then feed that config each time you run `gitmux`: + +``` +gitmux -cfg .gitmux.conf +``` + +## Troubleshooting + +If something goes wrong, please [file an issue](https://github.com/arl/gitmux/issues/new) +and indicate your tmux and gitmux versions, +what you did, what you saw and what you expected yo see. +Also you can run `gitmux -dbg` for debugging output. + +``` +tmux -V +gitmux -V +gitmux -dbg ``` ## Contributing diff --git a/format/json/formater.go b/format/json/formater.go index 1b37580..dbc726b 100644 --- a/format/json/formater.go +++ b/format/json/formater.go @@ -15,8 +15,10 @@ type Formater struct{} func (Formater) Format(w io.Writer, st *gitstatus.Status) error { enc := json.NewEncoder(w) enc.SetIndent("", " ") + if err := enc.Encode(st); err != nil { return fmt.Errorf("can't format status to json: %v", err) } + return nil } diff --git a/format/tmux/formater.go b/format/tmux/formater.go index 49d5450..2f880c0 100644 --- a/format/tmux/formater.go +++ b/format/tmux/formater.go @@ -98,6 +98,7 @@ fileCounts: f.flags() _, err := f.b.WriteTo(w) + return err } @@ -149,11 +150,13 @@ func (f *Formater) currentRef() { func (f *Formater) divergence() { f.clear() + pref := " " if f.st.BehindCount != 0 { fmt.Fprintf(&f.b, " %s%d", f.Symbols.Behind, f.st.BehindCount) pref = "" } + if f.st.AheadCount != 0 { fmt.Fprintf(&f.b, "%s%s%d", pref, f.Symbols.Ahead, f.st.AheadCount) } @@ -162,6 +165,7 @@ 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) return @@ -173,21 +177,26 @@ func (f *Formater) flags() { flags = append(flags, fmt.Sprintf("%s%s%d", f.Styles.Staged, f.Symbols.Staged, f.st.NumStaged)) } + if f.st.NumConflicts != 0 { flags = append(flags, fmt.Sprintf("%s%s%d", f.Styles.Conflict, f.Symbols.Conflict, f.st.NumConflicts)) } + if f.st.NumModified != 0 { flags = append(flags, fmt.Sprintf("%s%s%d", f.Styles.Modified, f.Symbols.Modified, f.st.NumModified)) } + if f.st.NumStashed != 0 { flags = append(flags, fmt.Sprintf("%s%s%d", f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed)) } + if f.st.NumUntracked != 0 { flags = append(flags, fmt.Sprintf("%s%s%d", f.Styles.Untracked, f.Symbols.Untracked, f.st.NumUntracked)) } + f.b.WriteString(strings.Join(flags, " ")) } diff --git a/main.go b/gitmux.go similarity index 50% rename from main.go rename to gitmux.go index 7d2afb6..f185b18 100644 --- a/main.go +++ b/gitmux.go @@ -1,129 +1,121 @@ package main import ( - "errors" "flag" "fmt" "os" - "github.com/arl/gitmux/format/json" - "github.com/arl/gitmux/format/tmux" "github.com/arl/gitstatus" "gopkg.in/yaml.v2" -) - -func check(err error, quiet bool) { - if err != nil { - if !quiet { - fmt.Println("error:", err) - } - os.Exit(1) - } -} -// Config configures output formatting. -type Config struct{ Tmux tmux.Config } + "github.com/arl/gitmux/format/json" + "github.com/arl/gitmux/format/tmux" +) var version = "<>" var usage = `gitmux ` + version + ` Usage: gitmux [options] [dir] -gitmux prints the status of a Git working tree. +gitmux prints the status of a Git working tree as a tmux format string. If directory is not given, it default to the working directory. Options: - -q be quiet. In case of errors, don't print nothing. - -fmt output format, defaults to json. - json prints status as a JSON object. - tmux prints status as a tmux format string. -cfg cfgfile use cfgfile when printing git status. -printcfg prints default configuration file. - -V prints gitmux version and exits. + -dbg outputs Git status as JSON and print errors. + -V prints gitmux version and exits. ` +// Config configures output formatting. +type Config struct{ Tmux tmux.Config } + var defaultCfg = Config{Tmux: tmux.DefaultCfg} -func parseOptions() (dir string, format string, quiet bool, cfg Config) { - fmtOpt := flag.String("fmt", "json", "") +func parseOptions() (dir string, dbg bool, cfg Config) { + dbgOpt := flag.Bool("dbg", false, "") cfgOpt := flag.String("cfg", "", "") printCfgOpt := flag.Bool("printcfg", false, "") - quietOpt := flag.Bool("q", false, "") versionOpt := flag.Bool("V", false, "") + flag.Bool("q", true, "") // unused, kept for retrocompatibility. + flag.String("fmt", "", "") // unused, kept for retrocompatibility. flag.Usage = func() { fmt.Println(usage) } flag.Parse() + dir = "." if flag.NArg() > 0 { dir = flag.Arg(0) } - cfg = defaultCfg + if *versionOpt { fmt.Println(version) os.Exit(0) } + if *printCfgOpt { enc := yaml.NewEncoder(os.Stdout) - check(enc.Encode(&defaultCfg), *quietOpt) + check(enc.Encode(&defaultCfg), *dbgOpt) enc.Close() os.Exit(0) } + + cfg = defaultCfg + if *cfgOpt != "" { f, err := os.Open(*cfgOpt) - check(err, *quietOpt) + check(err, *dbgOpt) + dec := yaml.NewDecoder(f) - check(dec.Decode(&cfg), *quietOpt) + check(dec.Decode(&cfg), *dbgOpt) } - return dir, *fmtOpt, *quietOpt, cfg -} -type popdir func() error + return dir, *dbgOpt, cfg +} -func pushdir(dir string) (popdir, error) { - pwd, err := os.Getwd() - if err != nil { +func pushdir(dir string) (popdir func() error, err error) { + pwd := "" + if pwd, err = os.Getwd(); err != nil { return nil, err } - err = os.Chdir(dir) - if err != nil { + if err = os.Chdir(dir); err != nil { return nil, err } return func() error { return os.Chdir(pwd) }, nil } -var errUnknownOutputFormat = errors.New("unknown output format") +func check(err error, dbg bool) { + if err != nil && dbg { + fmt.Fprintln(os.Stderr, "error:", err) + os.Exit(1) + } +} func main() { - // parse cli options. - dir, format, quiet, cfg := parseOptions() + dir, dbg, cfg := parseOptions() // handle directory change. if dir != "." { popDir, err := pushdir(dir) - check(err, quiet) + check(err, dbg) defer func() { - check(popDir(), quiet) + check(popDir(), dbg) }() } // retrieve git status. st, err := gitstatus.New() - check(err, quiet) - - // register formaters - formaters := make(map[string]formater) - formaters["json"] = &json.Formater{} - formaters["tmux"] = &tmux.Formater{Config: cfg.Tmux} + check(err, dbg) - formater, ok := formaters[format] - if !ok { - check(errUnknownOutputFormat, quiet) + // select defauit formater + var formater formater = &tmux.Formater{Config: cfg.Tmux} + if dbg { + formater = &json.Formater{} } // format and print - err = formater.Format(os.Stdout, st) - check(err, quiet) + check(formater.Format(os.Stdout, st), dbg) }