diff --git a/.gitmux.yml b/.gitmux.yml index 59953d6..8e29d03 100644 --- a/.gitmux.yml +++ b/.gitmux.yml @@ -75,7 +75,7 @@ tmux: options: # Maximum displayed length for local and remote branch names. branch_max_len: 0 - # Trim left or right end of the branch (`right` or `left`). + # Trim left, right or from the center of the branch (`right`, `left` or `center`). branch_trim: right # Character indicating whether and where a branch was truncated. ellipsis: … diff --git a/README.md b/README.md index 16414d1..7a1d489 100644 --- a/README.md +++ b/README.md @@ -265,15 +265,14 @@ layout: [branch, "|", flags, "|", stats] This is the list of additional configuration `options`: -| Option | Description | Default | -| :----------------- | :--------------------------------------------------------- | :----------------: | -| `branch_max_len` | Maximum displayed length for local and remote branch names | `0` (no limit) | -| `branch_trim` | Trim left or right end of the branch (`right` or `left`) | `right` (trailing) | -| `ellipsis` | Character to show branch name has been truncated | `…` | -| `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` | - +| Option | Description | Default | +| :----------------- | :------------------------------------------------------------------------------ | :----------------: | +| `branch_max_len` | Maximum displayed length for local and remote branch names | `0` (no limit) | +| `branch_trim` | Trim left, right or from the center of the branch (`right`, `left` or `center`) | `right` (trailing) | +| `ellipsis` | Character to show branch name has been truncated | `…` | +| `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` | ## Troubleshooting diff --git a/tmux/formater.go b/tmux/formater.go index 727290d..f601ff8 100644 --- a/tmux/formater.go +++ b/tmux/formater.go @@ -62,8 +62,9 @@ type styles struct { } const ( - dirLeft direction = "left" - dirRight direction = "right" + dirLeft direction = "left" + dirRight direction = "right" + dirCenter direction = "center" ) type direction string @@ -78,6 +79,8 @@ func (d *direction) UnmarshalYAML(value *yaml.Node) error { *d = dirLeft case dirRight: *d = dirRight + case dirCenter: + *d = dirCenter default: return fmt.Errorf("'direction': unexpected value %v", s) } @@ -100,8 +103,8 @@ type Formater struct { } // truncate returns s, truncated so that it is no more than max runes long. -// Depending on the provided direction, truncation is performed right or left. -// If s is returned truncated, the truncated part is replaced with the +// Depending on the provided direction, truncation is performed right, left or +// center. If s is returned truncated, the truncated part is replaced with the // 'ellipsis' string. // // If max is zero, negative or greater than the number of runes in s, truncate @@ -130,6 +133,16 @@ func truncate(s, ellipsis string, max int, dir direction) string { case dirLeft: runes = runes[len(runes)+len(ell)-max:] runes = append(ell, runes...) + case dirCenter: + // We want to keep the same number of runes on both sides of the ellipsis. If the + // number of runes on each side is odd, we add one more rune to the right side. + llen := (max - len(ell)) / 2 + rlen := max - len(ell) - llen + + right := runes[len(runes)-rlen:] + + runes = append(runes[:llen], ell...) + runes = append(runes, right...) } return string(runes) } diff --git a/tmux/formater_test.go b/tmux/formater_test.go index a55185a..70ffce7 100644 --- a/tmux/formater_test.go +++ b/tmux/formater_test.go @@ -484,6 +484,78 @@ func Test_truncate(t *testing.T) { dir: dirLeft, want: "super-long-branch", }, + + /* trim center */ + { + s: "br", + ellipsis: "...", + max: 1, + dir: dirCenter, + want: "r", + }, + { + s: "br", + ellipsis: "", + max: 1, + dir: dirCenter, + want: "r", + }, + { + s: "br", + ellipsis: "...", + max: 3, + dir: dirCenter, + want: "br", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: 3, + dir: dirCenter, + want: "...", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: 15, + dir: dirCenter, + want: "super-...branch", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: 17, + dir: dirCenter, + want: "super-long-branch", + }, + { + s: "长長的-树樹枝", + ellipsis: "...", + max: 6, + dir: dirCenter, + want: "长...樹枝", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: 32, + dir: dirCenter, + want: "super-long-branch", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: 0, + dir: dirCenter, + want: "super-long-branch", + }, + { + s: "super-long-branch", + ellipsis: "...", + max: -1, + dir: dirCenter, + want: "super-long-branch", + }, } for _, tt := range tests { t.Run("", func(t *testing.T) {