detached b65ab9e

feat(config): add bar.accent to pick which theme color highlights use

commit
b65ab9e9e74ebce27e3f83a3fb8ca758237fa224
author
brice · · 2026-10-05 17:17 UTC
parent
b752a4a
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
8 files · +54 -7
M README.md +2 -0
@@ -53,6 +53,7 @@ Add one `[[module]]` block per script. Save the file and the bar updates immedia
5353 | `bar.scale` | `1.0` | Extra zoom on top of the monitor scale. |
5454 | `bar.output` | any | A monitor name such as `HDMI-A-1`. Needs a restart. |
5555 | `bar.theme` | `auto` | `auto` reads the colors of the terminal you use. Or the path of a theme file (see Colors). |
56+| `bar.accent` | `4` | Which of the theme's 16 colors (0-15) the highlights use. 4 is the ANSI blue; try 2 (green), 6 (cyan) or 5 (magenta) to match your theme. |
5657 | `bar.background`, `bar.foreground` | from the theme | `#rrggbb`. Set them to override the theme. |
5758
5859 If the font is not installed, neferbar warns and falls back to another font, and icons may be missing.
@@ -84,6 +85,7 @@ Scripts get the colors as environment variables, each `#rrggbb`, so a script nev
8485 | Variable | Color |
8586 |---|---|
8687 | `NEFERBAR_BACKGROUND`, `NEFERBAR_FOREGROUND` | the bar's own background and text |
88+| `NEFERBAR_ACCENT` | the highlight color, the theme color that `bar.accent` picks |
8789 | `NEFERBAR_COLOR0` .. `NEFERBAR_COLOR15` | the theme's 16 ANSI colors |
8890
8991 The 16 ANSI codes a script prints (`\033[31m` red, `\033[44m` blue background and so on) use the theme as well.
@@ -53,6 +53,7 @@ Add one `[[module]]` block per script. Save the file and the bar updates immedia
53 | `bar.scale` | `1.0` | Extra zoom on top of the monitor scale. |53 | `bar.scale` | `1.0` | Extra zoom on top of the monitor scale. |
54 | `bar.output` | any | A monitor name such as `HDMI-A-1`. Needs a restart. |54 | `bar.output` | any | A monitor name such as `HDMI-A-1`. Needs a restart. |
55 | `bar.theme` | `auto` | `auto` reads the colors of the terminal you use. Or the path of a theme file (see Colors). |55 | `bar.theme` | `auto` | `auto` reads the colors of the terminal you use. Or the path of a theme file (see Colors). |
56+| `bar.accent` | `4` | Which of the theme's 16 colors (0-15) the highlights use. 4 is the ANSI blue; try 2 (green), 6 (cyan) or 5 (magenta) to match your theme. |
56 | `bar.background`, `bar.foreground` | from the theme | `#rrggbb`. Set them to override the theme. |57 | `bar.background`, `bar.foreground` | from the theme | `#rrggbb`. Set them to override the theme. |
57 58
58 If the font is not installed, neferbar warns and falls back to another font, and icons may be missing.59 If the font is not installed, neferbar warns and falls back to another font, and icons may be missing.
@@ -84,6 +85,7 @@ Scripts get the colors as environment variables, each `#rrggbb`, so a script nev
84 | Variable | Color |85 | Variable | Color |
85 |---|---|86 |---|---|
86 | `NEFERBAR_BACKGROUND`, `NEFERBAR_FOREGROUND` | the bar's own background and text |87 | `NEFERBAR_BACKGROUND`, `NEFERBAR_FOREGROUND` | the bar's own background and text |
88+| `NEFERBAR_ACCENT` | the highlight color, the theme color that `bar.accent` picks |
87 | `NEFERBAR_COLOR0` .. `NEFERBAR_COLOR15` | the theme's 16 ANSI colors |89 | `NEFERBAR_COLOR0` .. `NEFERBAR_COLOR15` | the theme's 16 ANSI colors |
88 90
89 The 16 ANSI codes a script prints (`\033[31m` red, `\033[44m` blue background and so on) use the theme as well.91 The 16 ANSI codes a script prints (`\033[31m` red, `\033[44m` blue background and so on) use the theme as well.
M examples/bundle/config.toml +1 -0
@@ -10,6 +10,7 @@
1010 font = "JetBrainsMono Nerd Font Mono" # any "Mono" Nerd Font
1111 size = 14
1212 theme = "auto" # the colors of the terminal in $TERMINAL, or the path of a theme file
13+accent = 4 # which theme color (0-15) highlights use: 4 is blue, 2 green, 6 cyan
1314
1415 [[module]]
1516 name = "workspaces"
@@ -10,6 +10,7 @@
10 font = "JetBrainsMono Nerd Font Mono" # any "Mono" Nerd Font10 font = "JetBrainsMono Nerd Font Mono" # any "Mono" Nerd Font
11 size = 1411 size = 14
12 theme = "auto" # the colors of the terminal in $TERMINAL, or the path of a theme file12 theme = "auto" # the colors of the terminal in $TERMINAL, or the path of a theme file
13+accent = 4 # which theme color (0-15) highlights use: 4 is blue, 2 green, 6 cyan
13 14
14 [[module]]15 [[module]]
15 name = "workspaces"16 name = "workspaces"
M examples/bundle/lib.sh +4 -1
@@ -4,11 +4,14 @@
44 # hard-codes one:
55 # NEFERBAR_BACKGROUND the bar's own background
66 # NEFERBAR_FOREGROUND the bar's text color
7+# NEFERBAR_ACCENT the highlight color: bar.accent in the config picks
8+# which of the 16 theme colors it is
79 # NEFERBAR_COLOR0..15 the theme's 16 ANSI colors
810
911 : "${NEFERBAR_BACKGROUND:=#26263a}" "${NEFERBAR_FOREGROUND:=#cdd6f4}"
1012 : "${NEFERBAR_COLOR0:=#45475a}" "${NEFERBAR_COLOR2:=#a6e3a1}" "${NEFERBAR_COLOR3:=#f9e2af}"
1113 : "${NEFERBAR_COLOR4:=#89b4fa}" "${NEFERBAR_COLOR15:=#a6adc8}"
14+: "${NEFERBAR_ACCENT:=$NEFERBAR_COLOR4}"
1215
1316 RESET=$'\e[0m' BOLD=$'\e[1m'
1417
@@ -43,7 +46,7 @@ fade() {
4346 }
4447
4548 BAR=$NEFERBAR_BACKGROUND
46-ACCENT=$NEFERBAR_COLOR4
49+ACCENT=$NEFERBAR_ACCENT
4750 DIM=$(mix "$BAR" "$NEFERBAR_FOREGROUND" 45)
4851
4952 # ink "#accent" -> the text color for a block of that color: the theme's black
@@ -4,11 +4,14 @@
4 # hard-codes one:4 # hard-codes one:
5 # NEFERBAR_BACKGROUND the bar's own background5 # NEFERBAR_BACKGROUND the bar's own background
6 # NEFERBAR_FOREGROUND the bar's text color6 # NEFERBAR_FOREGROUND the bar's text color
7+# NEFERBAR_ACCENT the highlight color: bar.accent in the config picks
8+# which of the 16 theme colors it is
7 # NEFERBAR_COLOR0..15 the theme's 16 ANSI colors9 # NEFERBAR_COLOR0..15 the theme's 16 ANSI colors
8 10
9 : "${NEFERBAR_BACKGROUND:=#26263a}" "${NEFERBAR_FOREGROUND:=#cdd6f4}"11 : "${NEFERBAR_BACKGROUND:=#26263a}" "${NEFERBAR_FOREGROUND:=#cdd6f4}"
10 : "${NEFERBAR_COLOR0:=#45475a}" "${NEFERBAR_COLOR2:=#a6e3a1}" "${NEFERBAR_COLOR3:=#f9e2af}"12 : "${NEFERBAR_COLOR0:=#45475a}" "${NEFERBAR_COLOR2:=#a6e3a1}" "${NEFERBAR_COLOR3:=#f9e2af}"
11 : "${NEFERBAR_COLOR4:=#89b4fa}" "${NEFERBAR_COLOR15:=#a6adc8}"13 : "${NEFERBAR_COLOR4:=#89b4fa}" "${NEFERBAR_COLOR15:=#a6adc8}"
14+: "${NEFERBAR_ACCENT:=$NEFERBAR_COLOR4}"
12 15
13 RESET=$'\e[0m' BOLD=$'\e[1m'16 RESET=$'\e[0m' BOLD=$'\e[1m'
14 17
@@ -43,7 +46,7 @@ fade() {
43 }46 }
44 47
45 BAR=$NEFERBAR_BACKGROUND48 BAR=$NEFERBAR_BACKGROUND
46-ACCENT=$NEFERBAR_COLOR449+ACCENT=$NEFERBAR_ACCENT
47 DIM=$(mix "$BAR" "$NEFERBAR_FOREGROUND" 45)50 DIM=$(mix "$BAR" "$NEFERBAR_FOREGROUND" 45)
48 51
49 # ink "#accent" -> the text color for a block of that color: the theme's black52 # ink "#accent" -> the text color for a block of that color: the theme's black
M internal/bar/bar.go +1 -1
@@ -171,7 +171,7 @@ func (b *Bar) setTheme(th theme.Theme) {
171171 b.theme = th
172172 b.fg, b.bg = barColors(b.cfg, th)
173173 b.pal = th.Palette
174- b.env = th.EnvVars(b.bg, b.fg)
174+ b.env = th.EnvVars(b.bg, b.fg, b.cfg.Bar.Accent)
175175 if b.lay != nil {
176176 b.lay.SetColors(b.fg, b.bg, b.pal)
177177 }
@@ -171,7 +171,7 @@ func (b *Bar) setTheme(th theme.Theme) {
171 b.theme = th171 b.theme = th
172 b.fg, b.bg = barColors(b.cfg, th)172 b.fg, b.bg = barColors(b.cfg, th)
173 b.pal = th.Palette173 b.pal = th.Palette
174- b.env = th.EnvVars(b.bg, b.fg)174+ b.env = th.EnvVars(b.bg, b.fg, b.cfg.Bar.Accent)
175 if b.lay != nil {175 if b.lay != nil {
176 b.lay.SetColors(b.fg, b.bg, b.pal)176 b.lay.SetColors(b.fg, b.bg, b.pal)
177 }177 }
M internal/config/config.go +7 -1
@@ -20,6 +20,9 @@ type Bar struct {
2020 // Theme is "auto" (the colors of the terminal in use) or the path of a
2121 // terminal theme or config file: kitty, foot, ghostty or alacritty.
2222 Theme string `toml:"theme"`
23+ // Accent is the number (0-15) of the theme's ANSI color the bundled
24+ // scripts use for highlights. Scripts read it as $NEFERBAR_ACCENT.
25+ Accent int `toml:"accent"`
2326 // Background and Foreground, as #rrggbb, override the theme's.
2427 Background string `toml:"background"`
2528 Foreground string `toml:"foreground"`
@@ -42,7 +45,7 @@ type Config struct {
4245 func Default() Config {
4346 return Config{Bar: Bar{
4447 Font: "JetBrainsMono Nerd Font Mono", Size: 14, Scale: 1,
45- Theme: "auto",
48+ Theme: "auto", Accent: 4,
4649 }}
4750 }
4851
@@ -93,6 +96,9 @@ func (c *Config) Validate() error {
9396 return err
9497 }
9598 }
99+ if b.Accent < 0 || b.Accent > 15 {
100+ return fmt.Errorf("config: bar.accent %d must be a color number from 0 to 15", b.Accent)
101+ }
96102 if b.Theme == "" {
97103 return fmt.Errorf("config: bar.theme is empty; use \"auto\" or the path of a theme file")
98104 }
@@ -20,6 +20,9 @@ type Bar struct {
20 // Theme is "auto" (the colors of the terminal in use) or the path of a20 // Theme is "auto" (the colors of the terminal in use) or the path of a
21 // terminal theme or config file: kitty, foot, ghostty or alacritty.21 // terminal theme or config file: kitty, foot, ghostty or alacritty.
22 Theme string `toml:"theme"`22 Theme string `toml:"theme"`
23+ // Accent is the number (0-15) of the theme's ANSI color the bundled
24+ // scripts use for highlights. Scripts read it as $NEFERBAR_ACCENT.
25+ Accent int `toml:"accent"`
23 // Background and Foreground, as #rrggbb, override the theme's.26 // Background and Foreground, as #rrggbb, override the theme's.
24 Background string `toml:"background"`27 Background string `toml:"background"`
25 Foreground string `toml:"foreground"`28 Foreground string `toml:"foreground"`
@@ -42,7 +45,7 @@ type Config struct {
42 func Default() Config {45 func Default() Config {
43 return Config{Bar: Bar{46 return Config{Bar: Bar{
44 Font: "JetBrainsMono Nerd Font Mono", Size: 14, Scale: 1,47 Font: "JetBrainsMono Nerd Font Mono", Size: 14, Scale: 1,
45- Theme: "auto",48+ Theme: "auto", Accent: 4,
46 }}49 }}
47 }50 }
48 51
@@ -93,6 +96,9 @@ func (c *Config) Validate() error {
93 return err96 return err
94 }97 }
95 }98 }
99+ if b.Accent < 0 || b.Accent > 15 {
100+ return fmt.Errorf("config: bar.accent %d must be a color number from 0 to 15", b.Accent)
101+ }
96 if b.Theme == "" {102 if b.Theme == "" {
97 return fmt.Errorf("config: bar.theme is empty; use \"auto\" or the path of a theme file")103 return fmt.Errorf("config: bar.theme is empty; use \"auto\" or the path of a theme file")
98 }104 }
M internal/config/config_test.go +13 -0
@@ -37,6 +37,8 @@ func TestLoadErrors(t *testing.T) {
3737 "bad size": "[bar]\nsize = 1\n",
3838 "bad scale": "[bar]\nscale = 20\n",
3939 "bad color": "[bar]\nbackground = \"red\"\n",
40+ "accent low": "[bar]\naccent = -1\n",
41+ "accent high": "[bar]\naccent = 16\n",
4042 "syntax error": "[bar\n",
4143 } {
4244 if _, err := Load(write(t, body), true); err == nil {
@@ -56,3 +58,14 @@ func TestMissingFile(t *testing.T) {
5658 t.Fatal("explicit path missing must fail")
5759 }
5860 }
61+
62+func TestAccentDefaultsToBlue(t *testing.T) {
63+ c, err := Load(write(t, "[bar]\nsize = 14\n"), true)
64+ if err != nil || c.Bar.Accent != 4 {
65+ t.Fatalf("accent = %d, err %v; want the default 4", c.Bar.Accent, err)
66+ }
67+ c, err = Load(write(t, "[bar]\naccent = 2\n"), true)
68+ if err != nil || c.Bar.Accent != 2 {
69+ t.Fatalf("accent = %d, err %v; want 2", c.Bar.Accent, err)
70+ }
71+}
@@ -37,6 +37,8 @@ func TestLoadErrors(t *testing.T) {
37 "bad size": "[bar]\nsize = 1\n",37 "bad size": "[bar]\nsize = 1\n",
38 "bad scale": "[bar]\nscale = 20\n",38 "bad scale": "[bar]\nscale = 20\n",
39 "bad color": "[bar]\nbackground = \"red\"\n",39 "bad color": "[bar]\nbackground = \"red\"\n",
40+ "accent low": "[bar]\naccent = -1\n",
41+ "accent high": "[bar]\naccent = 16\n",
40 "syntax error": "[bar\n",42 "syntax error": "[bar\n",
41 } {43 } {
42 if _, err := Load(write(t, body), true); err == nil {44 if _, err := Load(write(t, body), true); err == nil {
@@ -56,3 +58,14 @@ func TestMissingFile(t *testing.T) {
56 t.Fatal("explicit path missing must fail")58 t.Fatal("explicit path missing must fail")
57 }59 }
58 }60 }
61+
62+func TestAccentDefaultsToBlue(t *testing.T) {
63+ c, err := Load(write(t, "[bar]\nsize = 14\n"), true)
64+ if err != nil || c.Bar.Accent != 4 {
65+ t.Fatalf("accent = %d, err %v; want the default 4", c.Bar.Accent, err)
66+ }
67+ c, err = Load(write(t, "[bar]\naccent = 2\n"), true)
68+ if err != nil || c.Bar.Accent != 2 {
69+ t.Fatalf("accent = %d, err %v; want 2", c.Bar.Accent, err)
70+ }
71+}
M internal/theme/theme.go +6 -4
@@ -227,10 +227,12 @@ func Mix(a, b RGB, t float64) RGB {
227227 func Hex(c RGB) string { return fmt.Sprintf("#%02x%02x%02x", c[0], c[1], c[2]) }
228228
229229 // EnvVars returns the colors as environment entries for scripts:
230-// NEFERBAR_BACKGROUND, NEFERBAR_FOREGROUND and NEFERBAR_COLOR0..15, each
231-// #rrggbb. bg and fg are the colors the bar really uses.
232-func (t Theme) EnvVars(bg, fg RGB) []string {
233- out := []string{"NEFERBAR_BACKGROUND=" + Hex(bg), "NEFERBAR_FOREGROUND=" + Hex(fg)}
230+// NEFERBAR_BACKGROUND, NEFERBAR_FOREGROUND, NEFERBAR_ACCENT and
231+// NEFERBAR_COLOR0..15, each #rrggbb. bg and fg are the colors the bar really
232+// uses; accent is the number of the palette color chosen for highlights.
233+func (t Theme) EnvVars(bg, fg RGB, accent int) []string {
234+ out := []string{"NEFERBAR_BACKGROUND=" + Hex(bg), "NEFERBAR_FOREGROUND=" + Hex(fg),
235+ "NEFERBAR_ACCENT=" + Hex(t.Palette[accent&15])}
234236 for i, c := range t.Palette {
235237 out = append(out, fmt.Sprintf("NEFERBAR_COLOR%d=%s", i, Hex(c)))
236238 }
@@ -227,10 +227,12 @@ func Mix(a, b RGB, t float64) RGB {
227 func Hex(c RGB) string { return fmt.Sprintf("#%02x%02x%02x", c[0], c[1], c[2]) }227 func Hex(c RGB) string { return fmt.Sprintf("#%02x%02x%02x", c[0], c[1], c[2]) }
228 228
229 // EnvVars returns the colors as environment entries for scripts:229 // EnvVars returns the colors as environment entries for scripts:
230-// NEFERBAR_BACKGROUND, NEFERBAR_FOREGROUND and NEFERBAR_COLOR0..15, each230+// NEFERBAR_BACKGROUND, NEFERBAR_FOREGROUND, NEFERBAR_ACCENT and
231-// #rrggbb. bg and fg are the colors the bar really uses.231+// NEFERBAR_COLOR0..15, each #rrggbb. bg and fg are the colors the bar really
232-func (t Theme) EnvVars(bg, fg RGB) []string {232+// uses; accent is the number of the palette color chosen for highlights.
233- out := []string{"NEFERBAR_BACKGROUND=" + Hex(bg), "NEFERBAR_FOREGROUND=" + Hex(fg)}233+func (t Theme) EnvVars(bg, fg RGB, accent int) []string {
234+ out := []string{"NEFERBAR_BACKGROUND=" + Hex(bg), "NEFERBAR_FOREGROUND=" + Hex(fg),
235+ "NEFERBAR_ACCENT=" + Hex(t.Palette[accent&15])}
234 for i, c := range t.Palette {236 for i, c := range t.Palette {
235 out = append(out, fmt.Sprintf("NEFERBAR_COLOR%d=%s", i, Hex(c)))237 out = append(out, fmt.Sprintf("NEFERBAR_COLOR%d=%s", i, Hex(c)))
236 }238 }
M internal/theme/theme_test.go +20 -0
@@ -233,3 +233,23 @@ func TestParseColorForms(t *testing.T) {
233233 }
234234 }
235235 }
236+
237+func TestEnvVarsCarryTheChosenAccent(t *testing.T) {
238+ th := Default()
239+ th.Palette[2] = RGB{0x7d, 0xb5, 0xb5}
240+ th.Palette[4] = RGB{0x6c, 0x9b, 0xd9}
241+ has := func(env []string, want string) bool {
242+ for _, e := range env {
243+ if e == want {
244+ return true
245+ }
246+ }
247+ return false
248+ }
249+ if env := th.EnvVars(RGB{}, RGB{}, 2); !has(env, "NEFERBAR_ACCENT=#7db5b5") {
250+ t.Errorf("accent 2 not exported as the teal: %v", env)
251+ }
252+ if env := th.EnvVars(RGB{}, RGB{}, 4); !has(env, "NEFERBAR_ACCENT=#6c9bd9") {
253+ t.Errorf("accent 4 not exported as the blue: %v", env)
254+ }
255+}
@@ -233,3 +233,23 @@ func TestParseColorForms(t *testing.T) {
233 }233 }
234 }234 }
235 }235 }
236+
237+func TestEnvVarsCarryTheChosenAccent(t *testing.T) {
238+ th := Default()
239+ th.Palette[2] = RGB{0x7d, 0xb5, 0xb5}
240+ th.Palette[4] = RGB{0x6c, 0x9b, 0xd9}
241+ has := func(env []string, want string) bool {
242+ for _, e := range env {
243+ if e == want {
244+ return true
245+ }
246+ }
247+ return false
248+ }
249+ if env := th.EnvVars(RGB{}, RGB{}, 2); !has(env, "NEFERBAR_ACCENT=#7db5b5") {
250+ t.Errorf("accent 2 not exported as the teal: %v", env)
251+ }
252+ if env := th.EnvVars(RGB{}, RGB{}, 4); !has(env, "NEFERBAR_ACCENT=#6c9bd9") {
253+ t.Errorf("accent 4 not exported as the blue: %v", env)
254+ }
255+}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 5

Tags 4

↑↓ moveenter openesc close