Compare commits

..

7 commits

Author SHA1 Message Date
Aurélien Rainone 941739b1ad
Update README.md
Some checks failed
Test, Build and Publish / tests (macos-latest) (push) Has been cancelled
Test, Build and Publish / tests (ubuntu-latest) (push) Has been cancelled
Test, Build and Publish / Build and Publish (push) Has been cancelled
2026-02-17 09:43:13 +01:00
Chaitanya Sharma 2e9ceb19d9
feat: add install.sh script (#120)
* feat: add installation script

* feat(install): ask install path as an envvar

* feat: add help command to installation script

* docs(install): say that INSTALL_PATH is required

* fix(install): should exit early if curl is not found

* refactor: rename install -> install.sh
2025-08-11 09:41:56 +02:00
Aurélien Rainone 6662631da0
Cosmetics: make tests easier to maintain (#139)
Fix #137
2025-08-10 19:27:18 +02:00
Copilot 6a169c649f
Fix flags_without_count option behavior for empty symbols (#136)
The flags_without_count option was not handling empty symbols correctly.
Previously, flags with empty symbols were completely hidden regardless of
the option value, but according to the intended behavior, they should show
counts when flags_without_count=false (default).
2025-08-10 17:38:21 +02:00
Copilot 70a31330cd
Add ability to hide specific flags by setting their symbols to empty string (#132)
* Initial plan

* Test commit for clean state

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-07-31 12:15:18 +02:00
Aurélien Rainone 3d6516be61
Repository gardening (#131)
* ci: remove brew tag check from workflow

* goreleaser: remove brew-specific configuration

* .github: improve pull request template

* .github: add copilot instructions
2025-07-31 11:47:06 +02:00
Aurélien Rainone a5c6f875cd
Update README.md (#130)
Fix #41
2025-07-31 11:01:51 +02:00
9 changed files with 766 additions and 227 deletions

23
.github/copilot-instructions.md vendored Normal file
View file

@ -0,0 +1,23 @@
This is a Go based repository buliding a command line tool that converts the status of a git working tree for a specific directory into a tmux status string the end user can add to their tmux status line. It is designed to be used with the `tmux` terminal multiplexer.
## Code Standards
### Required Before Each Commit
- Run `go test ./...` before committing any changes to ensure tests pass
- Go code should be formatted with `gofmt`
## Repository Structure
- `./`: repository root, main package, default configuration file, and main entry point
- `tmux/`: tmux formatting
- `json/`: used by gitmux -dbg to print the git working tree status as a json object, for debugging purposes
- `testdata/`: testscripts fixtures when actual gitmux output is checked against some specific conditions.
## Key Guidelines
1. Follow Go best practices and idiomatic patterns
2. Maintain existing code structure and organization
3. Write unit tests for new functionality. Use table-driven unit tests when possible.
4. Document public options
5. Keep table aligned in the README.md file, for a nice experience even when reading the file in a terminal

View file

@ -2,6 +2,14 @@
_Describe the problem or feature in addition to a link to the issues._
## Approach
_How does this change address the problem?_
_How does this Pull Request address the problem?_
Thank you!
## Testing
- There should be some unit tests for every behaviour change or new feature
- If you're adding a new configuration option, the default configuration file
(.gitmux.yml) should be modified with the new option
- There's a test that verifies that gitmux output always remains the same
across versions when using the default configuration. You can run it with:
`go test -run TestScriptst`
- `README.md` should always be updated.

View file

@ -35,17 +35,3 @@ jobs:
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
check_brew:
name: Check Brew Tap
needs: goreleaser
runs-on: macos-latest
steps:
- name: Install gitmux with brew
run: |
brew tap arl/arl
brew install gitmux
gitmux -V
- name: Check installed gitmux version
run: |
[ v$(gitmux -V) == "$GITHUB_REF_NAME" ]

View file

@ -86,4 +86,6 @@ tmux:
# Add a space between behind & ahead upstream counts.
divergence_space: false
# Show flags symbols without counts.
# When true, shows only symbols (empty symbols show nothing).
# When false (default), shows symbols with counts (empty symbols show counts only).
flags_without_count: false

View file

@ -31,20 +31,3 @@ changelog:
exclude:
- "^docs:"
- "^test:"
brews:
- name: gitmux
homepage: "https://github.com/arl/gitmux"
description: "Git in your tmux status bar."
license: "MIT"
url_template: "https://github.com/arl/gitmux/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
commit_msg_template: "Brew formula update for {{ .ProjectName }} version {{ .Tag }}"
directory: Formula
skip_upload: false
repository:
owner: arl
name: homebrew-arl
branch: main
commit_author:
name: goreleaser-bot
email: bot@goreleaser.com

View file

@ -21,21 +21,22 @@
![demo](https://raw.githubusercontent.com/arl/gitmux/readme-images/demo-small.gif)
- **easy**. Install and forget about it
- **minimal**. Just shows what you need, when you need it
- **discrete**. Get out of your way if current directory is not in a Git tree
- **shell-agnostic**. Does not rely on shell-features so works with all of them
- **customizable**. Colors, symbols and layout are configurable
- **easy**: install and forget
- **minimal**: shows what you need, when you need it
- **discrete**: shows nothing when you're not in a git-managed directory
- **shell-agnostic**: doesn't rely on any shell-specific features, so will work with all of them
- **customizable**: colors, symbols and layout are all configurable
---
- [Prerequisites](#prerequisites)
- [Installing](#installing)
- [Binary release](#binary-release)
- [Homebrew tap (macOS and linux) (amd64 and arm64)](#homebrew-tap-macos-and-linux-amd64-and-arm64)
- [Homebrew (macOS and linux) (amd64 and arm64)](#homebrew-macos-and-linux-amd64-and-arm64)
- [AUR](#aur)
- [From source](#from-source)
- [Getting started](#getting-started)
- [Command line interface](#command-line-interface)
- [Customizing](#customizing)
- [Symbols](#symbols)
- [Styles](#styles)
@ -90,6 +91,29 @@ you run or when you switch windows, however it won't refresh automatically, nor
Note that `tmux v2.1` was released in 2015 so you're probably better off updating to a more recent version anyway 🙂.
### Command line interface
`gitmux` is not meant to be call directly but it still has a command line interface
that can be used to create the default configuration, troubleshoot your installation or during development:
```
$ gitmux -h
gitmux v0.11.5
Usage: gitmux [options] [dir]
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:
-cfg FILE read gitmux config from FILE.
-printcfg prints default configuration file.
-dbg outputs Git status as JSON and print errors.
-timeout DUR exits if still running after given duration (ex: 2s, 500ms).
-V prints gitmux version and exits.
```
## Customizing
`gitmux` output can be customized via a configuration file in YAML format.
@ -272,7 +296,9 @@ This is the list of additional configuration `options`:
| `hide_clean` | Hides the clean flag entirely | `false` |
| `swap_divergence` | Swaps order of behind & ahead upstream counts | `false` |
| `divergence_space` | Add a space between behind & ahead upstream counts | `false` |
| `flags_without_count`| Show flags symbols without counts | `false` |
| `flags_without_count`| Show flags symbols without counts* | `false` |
*When `flags_without_count` is true, shows only symbols (empty symbols show nothing). When false (default), shows symbols with counts (empty symbols show counts only).
## Troubleshooting

64
install.sh Executable file
View file

@ -0,0 +1,64 @@
#!/bin/sh
_have() { type "$1" >/dev/null 2>&1; }
help() {
cat <<EOF
Usage: ${0##*/} [options] [version]
Options:
-h, --help Show this help message and exit.
Arguments:
version Specify the version of gitmux to install. If not provided, the latest version will be installed.
Environment Variables:
INSTALL_PATH Specify the directory where gitmux should be installed. Required
Description:
This script installs the gitmux tool, which provides Git status information in the tmux status line.
It automatically detects the system architecture and downloads the appropriate version of gitmux.
Examples:
INSTALL_PATH=/usr/local/bin ${0##*/} Install the latest version of gitmux to /usr/local/bin.
INSTALL_PATH=/usr/local/bin ${0##*/} v0.7.0 Install version 0.7.0 of gitmux to /usr/local/bin.
EOF
}
gh_install() {
ver="$1"
repo='arl/gitmux'
[ -z "$ver" ] && {
latest="https://api.github.com/repos/$repo/releases/latest"
ver=$(curl -sS "$latest" | grep tarball_url | sed 's>.*: "\(.*\)".*>\1>') && test -n "$ver"
ver=${ver##*/}
}
tarname=''
archi=$(uname -sm)
case "$archi" in
Darwin\ arm64) tarname="gitmux_${ver}_macOS_arm64.tar.gz" ;;
Darwin\ x86_64) tarname="gitmux_${ver}_macOS_amd64.tar.gz" ;;
Linux\ aarch64*) tarname="gitmux_${ver}_linux_arm64.tar.gz" ;;
Linux\ *64) tarname="gitmux_${ver}_linux_amd64.tar.gz" ;;
*) echo "Unsupported architecture" && return 1 ;;
esac
tmpdir="$(mktemp -d)"
cd "$tmpdir" || :
curl -sSLO "https://github.com/$repo/releases/download/$ver/$tarname"
tar -xf gitmux*.tar.gz &&
mv gitmux "${INSTALL_PATH}"
[ -d "$tmpdir" ] && rm -rf "$tmpdir"
}
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then help && exit 0; fi
! _have curl && echo "This script depends on curl" && exit 1
[ -z "$INSTALL_PATH" ] && echo "Please set the INSTALL_PATH envvar to specify installation directory" && exit 1
echo "Installing gitmux..."
if gh_install "$@"; then
echo "Successfully installed gitmux"
else
echo "Could not install gitmux" && exit 1
fi

View file

@ -295,22 +295,32 @@ func (f *Formater) currentRef() string {
return fmt.Sprintf("%s%s%s", f.Styles.Clear, f.Styles.Branch, branch)
}
// formatFlag formats a flag with or without count based on the flags_without_count option
func (f *Formater) formatFlag(style, symbol string, count int) string {
if f.Options.FlagsWithoutCount {
return fmt.Sprintf("%s%s", style, symbol)
// appendFlag appends a flag to the flags slice based on configuration options
func (f *Formater) appendFlag(flags []string, style, symbol string, count int) []string {
if count == 0 {
return flags
}
return fmt.Sprintf("%s%s%d", style, symbol, count)
if f.Options.FlagsWithoutCount {
// When flags_without_count is true, show symbol only (empty string if symbol is empty)
if symbol == "" {
return flags
}
return append(flags, fmt.Sprintf("%s%s", style, symbol))
}
// When flags_without_count is false, show symbol + count, or just count if symbol is empty
return append(flags, fmt.Sprintf("%s%s%d", style, symbol, count))
}
func (f *Formater) flags() string {
var flags []string
if f.st.IsClean {
if f.st.NumStashed != 0 {
flags = append(flags, f.formatFlag(f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed))
}
// For stashed in clean state, handle empty symbols properly
flags = f.appendFlag(flags, f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed)
if !f.Options.HideClean {
// Clean flag only shows if symbol is not empty and hide_clean is false
if !f.Options.HideClean && f.Symbols.Clean != "" {
flags = append(flags, fmt.Sprintf("%s%s", f.Styles.Clean, f.Symbols.Clean))
}
@ -319,25 +329,12 @@ func (f *Formater) flags() string {
}
}
if f.st.NumStaged != 0 {
flags = append(flags, f.formatFlag(f.Styles.Staged, f.Symbols.Staged, f.st.NumStaged))
}
if f.st.NumConflicts != 0 {
flags = append(flags, f.formatFlag(f.Styles.Conflict, f.Symbols.Conflict, f.st.NumConflicts))
}
if f.st.NumModified != 0 {
flags = append(flags, f.formatFlag(f.Styles.Modified, f.Symbols.Modified, f.st.NumModified))
}
if f.st.NumStashed != 0 {
flags = append(flags, f.formatFlag(f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed))
}
if f.st.NumUntracked != 0 {
flags = append(flags, f.formatFlag(f.Styles.Untracked, f.Symbols.Untracked, f.st.NumUntracked))
}
// For all other flags, handle empty symbols properly
flags = f.appendFlag(flags, f.Styles.Staged, f.Symbols.Staged, f.st.NumStaged)
flags = f.appendFlag(flags, f.Styles.Conflict, f.Symbols.Conflict, f.st.NumConflicts)
flags = f.appendFlag(flags, f.Styles.Modified, f.Symbols.Modified, f.st.NumModified)
flags = f.appendFlag(flags, f.Styles.Stashed, f.Symbols.Stashed, f.st.NumStashed)
flags = f.appendFlag(flags, f.Styles.Untracked, f.Symbols.Untracked, f.st.NumUntracked)
if len(flags) > 0 {
return f.Styles.Clear + strings.Join(flags, " ")

File diff suppressed because it is too large Load diff