test(04-02): add i3bar formatting with TDD

- I3BarBlock struct for i3bar protocol JSON
- formatI3BarBlocks: compact format D-06/D-07/D-08
- 10 tests covering mixed states, colors, labels, markers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pierre Martin
2026-03-23 21:29:09 +01:00
parent 399e3e8f02
commit a28e8d6f1e
2 changed files with 181 additions and 0 deletions

52
i3bar.go Normal file
View File

@@ -0,0 +1,52 @@
package main
import (
"fmt"
"strings"
)
// I3BarBlock represents a single block in the i3bar protocol.
type I3BarBlock struct {
FullText string `json:"full_text"`
ShortText string `json:"short_text,omitempty"`
Color string `json:"color"`
Name string `json:"name"`
Markup string `json:"markup,omitempty"`
}
// formatI3BarBlocks builds the vmux status block for i3bar from session data.
func formatI3BarBlocks(sessions []SessionInfo) []I3BarBlock {
if len(sessions) == 0 {
return []I3BarBlock{{FullText: "vmux: no sessions", Color: "#00ff00", Name: "vmux"}}
}
hasWaiting := false
parts := make([]string, 0, len(sessions))
for _, s := range sessions {
name := shortName(s)
switch s.State {
case "Needs Input":
parts = append(parts, name+"[!]")
hasWaiting = true
case "Working":
parts = append(parts, name+"[W]")
case "Idle":
parts = append(parts, name+"[I]")
}
}
var text string
if !hasWaiting {
text = fmt.Sprintf("vmux: all working (%d)", len(sessions))
} else {
text = "vmux: " + strings.Join(parts, " ")
}
color := "#00ff00"
if hasWaiting {
color = "#ff0000"
}
return []I3BarBlock{{FullText: text, Color: color, Name: "vmux"}}
}