Add 'alt-bg' color for striped lines

Test cases:

1. 'jump' should show alternating background colors even when 'alt-bg' is
not defined as before.

  go run main.go --bind load:jump

Two differences:
  * The alternating lines will not be in bold (was a bug)
  * The marker column will not be rendered with alternating background color

2. Use alternating background color when 'alt-bg' is set

  go run main.go --color bg:238,alt-bg:237
  go run main.go --color bg:238,alt-bg:237 --highlight-line

3. 'selected-bg' should take precedence

  go run main.go --color bg:238,alt-bg:237,selected-bg:232 \
                 --highlight-line --multi --bind 'load:select+up+select+up'

---

Close #4354
This commit is contained in:
Junegunn Choi
2025-05-02 10:43:39 +09:00
parent 9c1a47acf7
commit 072d14f1f1
4 changed files with 35 additions and 5 deletions

View File

@@ -270,6 +270,7 @@ color mappings.
\fBcurrent\-bg (bg+) \fRBackground (current line)
\fBgutter \fRGutter on the left
\fBcurrent\-hl (hl+) \fRHighlighted substrings (current line)
\fBalt\-bg \fRAlternate background color for striped lines
\fBquery (input\-fg) \fRQuery string
\fBdisabled \fRQuery string when search is disabled (\fB\-\-disabled\fR)
\fBinfo \fRInfo line (match counters)

View File

@@ -1295,6 +1295,8 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) (*tui.ColorTheme, erro
mergeAttr(&theme.Current)
case "current-bg", "bg+":
mergeAttr(&theme.DarkBg)
case "alt-bg":
mergeAttr(&theme.AltBg)
case "selected-fg":
mergeAttr(&theme.SelectedFg)
case "selected-bg":

View File

@@ -2791,17 +2791,26 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
_, selected := t.selected[item.Index()]
label := ""
extraWidth := 0
alt := false
altBg := t.theme.AltBg
selectedBg := selected && t.theme.SelectedBg != t.theme.ListBg
if t.jumping != jumpDisabled {
if !altBg.IsColorDefined() {
altBg = t.theme.DarkBg
}
if index < len(t.jumpLabels) {
// Striped
current = index%2 == 0
alt = index%2 == 0
label = t.jumpLabels[index:index+1] + strings.Repeat(" ", util.Max(0, t.pointerLen-1))
if t.pointerLen == 0 {
extraWidth = 1
}
}
} else if current {
label = t.pointer
} else {
if current {
label = t.pointer
}
alt = !selectedBg && altBg.IsColorDefined() && index%2 == 0
}
// Avoid unnecessary redraw
@@ -2828,10 +2837,12 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
maxWidth := t.window.Width() - (t.pointerLen + t.markerLen + 1)
postTask := func(lineNum int, width int, wrapped bool, forceRedraw bool) {
width += extraWidth
if (current || selected) && t.highlightLine {
if (current || selected || alt) && t.highlightLine {
color := tui.ColSelected
if current {
color = tui.ColCurrent
} else if alt {
color = color.WithBg(altBg)
}
fillSpaces := maxWidth - width
if wrapped {
@@ -2899,7 +2910,7 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
}
return indentSize
}
finalLineNum = t.printHighlighted(result, tui.ColCurrent, tui.ColCurrentMatch, true, true, line, maxLine, forceRedraw, preTask, postTask)
finalLineNum = t.printHighlighted(result, tui.ColCurrent, tui.ColCurrentMatch, current, true, line, maxLine, forceRedraw, preTask, postTask)
} else {
preTask := func(marker markerClass) int {
w := t.window.Width() - t.pointerLen
@@ -2929,6 +2940,10 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
base = tui.ColNormal
match = tui.ColMatch
}
if alt {
base = base.WithBg(altBg)
match = match.WithBg(altBg)
}
finalLineNum = t.printHighlighted(result, base, match, false, true, line, maxLine, forceRedraw, preTask, postTask)
}
for i := 0; i < t.gap && finalLineNum < maxLine; i++ {

View File

@@ -308,6 +308,12 @@ func (p ColorPair) WithAttr(attr Attr) ColorPair {
return dup
}
func (p ColorPair) WithBg(bg ColorAttr) ColorPair {
dup := p
bgPair := ColorPair{colUndefined, bg.Color, bg.Attr}
return dup.Merge(bgPair)
}
func (p ColorPair) MergeAttr(other ColorPair) ColorPair {
return p.WithAttr(other.attr)
}
@@ -328,6 +334,7 @@ type ColorTheme struct {
Bg ColorAttr
ListFg ColorAttr
ListBg ColorAttr
AltBg ColorAttr
Nth ColorAttr
SelectedFg ColorAttr
SelectedBg ColorAttr
@@ -735,6 +742,7 @@ func EmptyTheme() *ColorTheme {
Bg: ColorAttr{colUndefined, AttrUndefined},
ListFg: ColorAttr{colUndefined, AttrUndefined},
ListBg: ColorAttr{colUndefined, AttrUndefined},
AltBg: ColorAttr{colUndefined, AttrUndefined},
SelectedFg: ColorAttr{colUndefined, AttrUndefined},
SelectedBg: ColorAttr{colUndefined, AttrUndefined},
SelectedMatch: ColorAttr{colUndefined, AttrUndefined},
@@ -780,6 +788,7 @@ func NoColorTheme() *ColorTheme {
Bg: ColorAttr{colDefault, AttrUndefined},
ListFg: ColorAttr{colDefault, AttrUndefined},
ListBg: ColorAttr{colDefault, AttrUndefined},
AltBg: ColorAttr{colUndefined, AttrUndefined},
SelectedFg: ColorAttr{colDefault, AttrUndefined},
SelectedBg: ColorAttr{colDefault, AttrUndefined},
SelectedMatch: ColorAttr{colDefault, AttrUndefined},
@@ -825,6 +834,7 @@ func init() {
Bg: ColorAttr{colDefault, AttrUndefined},
ListFg: ColorAttr{colUndefined, AttrUndefined},
ListBg: ColorAttr{colUndefined, AttrUndefined},
AltBg: ColorAttr{colUndefined, AttrUndefined},
SelectedFg: ColorAttr{colUndefined, AttrUndefined},
SelectedBg: ColorAttr{colUndefined, AttrUndefined},
SelectedMatch: ColorAttr{colUndefined, AttrUndefined},
@@ -864,6 +874,7 @@ func init() {
Bg: ColorAttr{colDefault, AttrUndefined},
ListFg: ColorAttr{colUndefined, AttrUndefined},
ListBg: ColorAttr{colUndefined, AttrUndefined},
AltBg: ColorAttr{colUndefined, AttrUndefined},
SelectedFg: ColorAttr{colUndefined, AttrUndefined},
SelectedBg: ColorAttr{colUndefined, AttrUndefined},
SelectedMatch: ColorAttr{colUndefined, AttrUndefined},
@@ -903,6 +914,7 @@ func init() {
Bg: ColorAttr{colDefault, AttrUndefined},
ListFg: ColorAttr{colUndefined, AttrUndefined},
ListBg: ColorAttr{colUndefined, AttrUndefined},
AltBg: ColorAttr{colUndefined, AttrUndefined},
SelectedFg: ColorAttr{colUndefined, AttrUndefined},
SelectedBg: ColorAttr{colUndefined, AttrUndefined},
SelectedMatch: ColorAttr{colUndefined, AttrUndefined},