summaryrefslogtreecommitdiff
path: root/internal/config
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-18 09:00:35 +0200
committerPaul Buetow <paul@buetow.org>2026-02-18 09:00:35 +0200
commit88f4e239a7521112a4db8c7842e3a05db4446cd4 (patch)
tree8c331f9f2e23ad9c9319d6dc8275205b23ce811a /internal/config
parent11204092b5ab5dc0f71515adfcaa6f07111363e5 (diff)
feat: triple-toggle CPU display mode via 1 key; add tooltip, font, hit-test
CPU display now cycles through three states with each press of 1: 0 = CPUModeAverage – aggregate bar only (default) 1 = CPUModeCores – individual core bars + aggregate 2 = CPUModeOff – all CPU bars hidden Config file stores cpumode=N (integer); old showcores=0/1 is read for backward compatibility. CLI flag --showcores replaced by --cpumode. Other improvements landed in this commit: - internal/display: add font.go (text rendering), hittest.go (bar hit testing), tooltip.go (mouse-over tooltip), tooltip_test.go - internal/display: mouse tracking and drawOverlay hook in display.go - internal/display: update build tags to //go:build form - internal/collector: embed remote script via script_embed.go / scriptdata/loadbars-remote.sh - internal/collector: CPULine.Total() changed to value receiver - internal/collector: table test improvements (name field, t.Run) - internal/constants: BytesPerSec consts promoted from var to const - Magefile.go: fix error formatting and install path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/config')
-rw-r--r--internal/config/config.go20
-rw-r--r--internal/config/config_test.go9
2 files changed, 18 insertions, 11 deletions
diff --git a/internal/config/config.go b/internal/config/config.go
index ba7886e..90b8192 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -26,7 +26,7 @@ type Config struct {
NetLink string
ShowAvgLine bool
ShowIOAvgLine bool
- ShowCores bool
+ CPUMode int // constants.CPUModeAverage / CPUModeCores / CPUModeOff
ShowMem bool
ShowNet bool
ShowSeparators bool
@@ -46,7 +46,7 @@ func Default() Config {
MaxWidth: 1900,
NetAverage: 15,
NetLink: "gbit",
- ShowCores: false,
+ CPUMode: constants.CPUModeAverage, // start with aggregate bar only
ShowMem: false,
ShowNet: false,
MaxBarsPerRow: 0,
@@ -108,7 +108,7 @@ func (c *Config) parseReader(f *os.File) error {
validKeys := map[string]bool{
"title": true, "barwidth": true, "cpuaverage": true, "extended": true,
"hasagent": true, "height": true, "maxwidth": true, "netaverage": true,
- "netlink": true, "showcores": true, "showmem": true,
+ "netlink": true, "cpumode": true, "showcores": true, "showmem": true,
"showavgline": true, "showioavgline": true, "shownet": true, "showseparators": true,
"maxbarsperrow": true, "sshopts": true, "cluster": true,
}
@@ -169,8 +169,18 @@ func (c *Config) set(key, val string) {
c.ShowAvgLine = parseBool(val)
case "showioavgline":
c.ShowIOAvgLine = parseBool(val)
+ case "cpumode":
+ // 0=average, 1=cores, 2=off — clamp to valid range
+ if n, err := strconv.Atoi(val); err == nil && n >= 0 && n < constants.CPUModeCount {
+ c.CPUMode = n
+ }
case "showcores":
- c.ShowCores = parseBool(val)
+ // Backward-compatible: old boolean showcores maps to CPUMode
+ if parseBool(val) {
+ c.CPUMode = constants.CPUModeCores
+ } else {
+ c.CPUMode = constants.CPUModeAverage
+ }
case "showmem":
c.ShowMem = parseBool(val)
case "shownet":
@@ -209,7 +219,7 @@ func (c *Config) writeTo(f *os.File) error {
writeStr("netlink", c.NetLink)
writeBool("showavgline", c.ShowAvgLine)
writeBool("showioavgline", c.ShowIOAvgLine)
- writeBool("showcores", c.ShowCores)
+ writeInt("cpumode", c.CPUMode)
writeBool("showmem", c.ShowMem)
writeBool("shownet", c.ShowNet)
writeBool("showseparators", c.ShowSeparators)
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 630fa47..7b0bb37 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -25,9 +25,6 @@ func TestConfig_parseReader(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := Default()
- f, _ := os.Open(os.DevNull)
- defer f.Close()
- // Use a temp file with the content since parseReader takes *os.File
dir := t.TempDir()
path := filepath.Join(dir, "rc")
if err := os.WriteFile(path, []byte(tt.input), 0600); err != nil {
@@ -54,7 +51,7 @@ func TestConfig_parseReader(t *testing.T) {
func TestConfig_writeTo(t *testing.T) {
c := Default()
c.BarWidth = 25
- c.ShowCores = true
+ c.CPUMode = 1 // CPUModeCores
dir := t.TempDir()
path := filepath.Join(dir, "out")
f, err := os.Create(path)
@@ -73,8 +70,8 @@ func TestConfig_writeTo(t *testing.T) {
if !bytes.Contains(data, []byte("barwidth=25")) {
t.Errorf("expected barwidth=25 in %s", data)
}
- if !bytes.Contains(data, []byte("showcores=1")) {
- t.Errorf("expected showcores=1 in %s", data)
+ if !bytes.Contains(data, []byte("cpumode=1")) {
+ t.Errorf("expected cpumode=1 in %s", data)
}
}