summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2025-01-20 00:49:08 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2025-01-20 01:02:58 +0900
commita4db8bd7b550c010b99f26337d841395e319890a (patch)
tree89f4ca038fa6c5a8d599133413852e9581e5ea02 /src
parentf1c1b02d77a9d36cc5195a11ec2e162d829ddb9d (diff)
downloadfzf-a4db8bd7b550c010b99f26337d841395e319890a.tar.gz
Make 'current-fg' inherit from 'fg' to simplify configuration
If you do not want 'current-fg' to inherit attributes of 'fg', prefix it with 'regular:' to reset them. # italic and underline fzf --color fg:italic,current-fg:underline # only underline fzf --color fg:italic,current-fg:regular:underline
Diffstat (limited to 'src')
-rw-r--r--src/ansi.go2
-rw-r--r--src/options.go2
-rw-r--r--src/result.go17
-rw-r--r--src/terminal.go56
-rw-r--r--src/tui/dummy.go6
-rw-r--r--src/tui/light.go2
-rw-r--r--src/tui/tcell.go16
-rw-r--r--src/tui/tui.go14
8 files changed, 68 insertions, 47 deletions
diff --git a/src/ansi.go b/src/ansi.go
index 37d9c767..687b9524 100644
--- a/src/ansi.go
+++ b/src/ansi.go
@@ -44,7 +44,7 @@ func (s *ansiState) ToString() string {
}
ret := ""
- if s.attr&tui.Bold > 0 {
+ if s.attr&tui.Bold > 0 || s.attr&tui.BoldForce > 0 {
ret += "1;"
}
if s.attr&tui.Dim > 0 {
diff --git a/src/options.go b/src/options.go
index cb077a17..2168284b 100644
--- a/src/options.go
+++ b/src/options.go
@@ -3135,7 +3135,7 @@ func postProcessOptions(opts *Options) error {
boldify := func(c tui.ColorAttr) tui.ColorAttr {
dup := c
if (c.Attr & tui.AttrRegular) == 0 {
- dup.Attr |= tui.Bold
+ dup.Attr |= tui.BoldForce
}
return dup
}
diff --git a/src/result.go b/src/result.go
index ada31d59..10e0c6d6 100644
--- a/src/result.go
+++ b/src/result.go
@@ -150,10 +150,6 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
}
for _, off := range nthOffsets {
- // Exclude the whole line
- if int(off[1])-int(off[0]) == result.item.text.Length() {
- continue
- }
for i := off[0]; i < off[1]; i++ {
cols[i].nth = true
}
@@ -190,7 +186,12 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
add := func(idx int) {
if (curr.color || curr.nth || curr.match) && idx > start {
if curr.match {
- color := colMatch
+ var color tui.ColorPair
+ if curr.nth {
+ color = colBase.WithAttr(attrNth).Merge(colMatch)
+ } else {
+ color = colBase.Merge(colMatch)
+ }
var url *url
if curr.color && theme.Colored {
ansi := itemColors[curr.index]
@@ -206,13 +207,13 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
// echo -e "\x1b[42mfoo\x1b[mbar" | fzf --ansi --color bg+:1,hl+:-1:underline
if color.Fg().IsDefault() && origColor.HasBg() {
color = origColor
+ if curr.nth {
+ color = color.WithAttr(attrNth)
+ }
} else {
color = origColor.MergeNonDefault(color)
}
}
- if curr.nth {
- color = color.WithAttr(attrNth)
- }
colors = append(colors, colorOffset{
offset: [2]int32{int32(start), int32(idx)}, color: color, match: true, url: url})
} else if curr.color {
diff --git a/src/terminal.go b/src/terminal.go
index a5d8f767..b1d86489 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -2725,38 +2725,38 @@ func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMat
sort.Sort(ByOrder(charOffsets))
}
- wholeCovered := len(t.nthCurrent) == 0
- for _, nth := range t.nthCurrent {
- // Do we still want to apply a different style when the current nth
- // covers the whole string? Probably not. And we can simplify the logic.
- if nth.IsFull() {
- wholeCovered = true
- break
+ // When postTask is nil, we're printing header lines. No need to care about nth.
+ var nthOffsets []Offset
+ if postTask != nil {
+ wholeCovered := len(t.nthCurrent) == 0
+ for _, nth := range t.nthCurrent {
+ // Do we still want to apply a different style when the current nth
+ // covers the whole string? Probably not. And we can simplify the logic.
+ if nth.IsFull() {
+ wholeCovered = true
+ break
+ }
}
- }
- // But if 'nth' is set to 'regular', it's a sign that you're applying
- // a different style to the rest of the string. e.g. 'nth:regular,fg:dim'
- // In this case, we still need to apply and clear the style.
- // We do the same when postTask is nil, which means we're printing header lines.
- if t.nthAttr == tui.AttrRegular && wholeCovered || postTask == nil {
- if t.nthAttr == tui.AttrRegular {
+ if wholeCovered && t.nthAttr&tui.AttrRegular > 0 {
+ // But if 'nth' is set to 'regular', it's a sign that you're applying
+ // a different style to the rest of the string. e.g. 'nth:regular,fg:dim'
+ // In this case, we still need to apply it to clear the style.
colBase = colBase.WithAttr(t.nthAttr)
}
- }
- var nthOffsets []Offset
- if !wholeCovered && t.nthAttr > 0 && postTask != nil {
- var tokens []Token
- if item.transformed != nil {
- tokens = item.transformed.tokens
- } else {
- tokens = Transform(Tokenize(item.text.ToString(), t.delimiter), t.nthCurrent)
- }
- for _, token := range tokens {
- start := token.prefixLength
- end := start + int32(token.text.Length())
- nthOffsets = append(nthOffsets, Offset{int32(start), int32(end)})
+ if !wholeCovered && t.nthAttr > 0 {
+ var tokens []Token
+ if item.transformed != nil {
+ tokens = item.transformed.tokens
+ } else {
+ tokens = Transform(Tokenize(item.text.ToString(), t.delimiter), t.nthCurrent)
+ }
+ for _, token := range tokens {
+ start := token.prefixLength
+ end := start + int32(token.text.Length())
+ nthOffsets = append(nthOffsets, Offset{int32(start), int32(end)})
+ }
+ sort.Sort(ByOrder(nthOffsets))
}
- sort.Sort(ByOrder(nthOffsets))
}
allOffsets := result.colorOffsets(charOffsets, nthOffsets, t.theme, colBase, colMatch, t.nthAttr, current)
diff --git a/src/tui/dummy.go b/src/tui/dummy.go
index aaa9a7ea..1e62e849 100644
--- a/src/tui/dummy.go
+++ b/src/tui/dummy.go
@@ -11,8 +11,9 @@ func HasFullscreenRenderer() bool {
var DefaultBorderShape = BorderRounded
func (a Attr) Merge(b Attr) Attr {
- if b == AttrRegular {
- return b
+ if b&AttrRegular > 0 {
+ // Only keep bold attribute set by the system
+ return b | (a & BoldForce)
}
return a | b
@@ -22,6 +23,7 @@ const (
AttrUndefined = Attr(0)
AttrRegular = Attr(1 << 8)
AttrClear = Attr(1 << 9)
+ BoldForce = Attr(1 << 10)
Bold = Attr(1)
Dim = Attr(1 << 1)
diff --git a/src/tui/light.go b/src/tui/light.go
index 48202bce..f4688060 100644
--- a/src/tui/light.go
+++ b/src/tui/light.go
@@ -1011,7 +1011,7 @@ func attrCodes(attr Attr) []string {
if (attr & AttrClear) > 0 {
return codes
}
- if (attr & Bold) > 0 {
+ if (attr&Bold) > 0 || (attr&BoldForce) > 0 {
codes = append(codes, "1")
}
if (attr & Dim) > 0 {
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
index 991052bd..0bf160c4 100644
--- a/src/tui/tcell.go
+++ b/src/tui/tcell.go
@@ -97,6 +97,7 @@ const (
AttrUndefined = Attr(0)
AttrRegular = Attr(1 << 7)
AttrClear = Attr(1 << 8)
+ BoldForce = Attr(1 << 10)
)
func (r *FullscreenRenderer) PassThrough(str string) {
@@ -141,6 +142,11 @@ func (c Color) Style() tcell.Color {
}
func (a Attr) Merge(b Attr) Attr {
+ if b&AttrRegular > 0 {
+ // Only keep bold attribute set by the system
+ return b | (a & BoldForce)
+ }
+
return a | b
}
@@ -556,13 +562,13 @@ func (r *FullscreenRenderer) NewWindow(top int, left int, width int, height int,
normal := ColBorder
switch windowType {
case WindowList:
- normal = ColListBorder
+ normal = ColNormal
case WindowHeader:
- normal = ColHeaderBorder
+ normal = ColHeader
case WindowInput:
- normal = ColInputBorder
+ normal = ColInput
case WindowPreview:
- normal = ColPreviewBorder
+ normal = ColPreview
}
w := &TcellWindow{
color: r.theme.Colored,
@@ -694,7 +700,7 @@ func (w *TcellWindow) fillString(text string, pair ColorPair) FillReturn {
}
style = style.
Blink(a&Attr(tcell.AttrBlink) != 0).
- Bold(a&Attr(tcell.AttrBold) != 0).
+ Bold(a&Attr(tcell.AttrBold) != 0 || a&BoldForce != 0).
Dim(a&Attr(tcell.AttrDim) != 0).
Reverse(a&Attr(tcell.AttrReverse) != 0).
Underline(a&Attr(tcell.AttrUnderline) != 0).
diff --git a/src/tui/tui.go b/src/tui/tui.go
index 212a1bed..58c1bec5 100644
--- a/src/tui/tui.go
+++ b/src/tui/tui.go
@@ -213,6 +213,16 @@ func NewColorAttr() ColorAttr {
return ColorAttr{Color: colUndefined, Attr: AttrUndefined}
}
+func (a ColorAttr) Merge(other ColorAttr) ColorAttr {
+ if other.Color != colUndefined {
+ a.Color = other.Color
+ }
+ if other.Attr != AttrUndefined {
+ a.Attr = a.Attr.Merge(other.Attr)
+ }
+ return a
+}
+
const (
colUndefined Color = -2
colDefault Color = -1
@@ -904,7 +914,9 @@ func InitTheme(theme *ColorTheme, baseTheme *ColorTheme, forceBlack bool, hasInp
theme.DarkBg = o(baseTheme.DarkBg, theme.DarkBg)
theme.Prompt = o(baseTheme.Prompt, theme.Prompt)
theme.Match = o(baseTheme.Match, theme.Match)
- theme.Current = o(baseTheme.Current, theme.Current)
+ // Inherit from 'fg', so that we don't have to write 'current-fg:dim'
+ // e.g. fzf --delimiter / --nth -1 --color fg:dim,nth:regular
+ theme.Current = theme.Fg.Merge(o(baseTheme.Current, theme.Current))
theme.CurrentMatch = o(baseTheme.CurrentMatch, theme.CurrentMatch)
theme.Spinner = o(baseTheme.Spinner, theme.Spinner)
theme.Info = o(baseTheme.Info, theme.Info)