mirror of
https://github.com/junegunn/fzf.git
synced 2025-07-31 04:02:01 -07:00
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
This commit is contained in:
@@ -90,11 +90,11 @@ Also, fzf now offers "style presets" for quick customization, which can be activ
|
||||
ls -al | fzf --nth -1 --color nth:reverse:bold
|
||||
|
||||
# Dim the other parts
|
||||
ls -al | fzf --nth -1 --color nth:regular,fg:dim,current-fg:dim
|
||||
ls -al | fzf --nth -1 --color nth:regular,fg:dim
|
||||
|
||||
# With 'change-nth'. The current nth option is exported as $FZF_NTH.
|
||||
ps -ef | fzf --reverse --header-lines 1 --header-border bottom --input-border \
|
||||
--color nth:regular,fg:dim,current-fg:dim \
|
||||
--color nth:regular,fg:dim \
|
||||
--bind 'ctrl-n:change-nth(8..|1|2|3|4|5|6|7|)' \
|
||||
--bind 'result:transform-prompt:echo "${FZF_NTH}> "'
|
||||
```
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
allOffsets := result.colorOffsets(charOffsets, nthOffsets, t.theme, colBase, colMatch, t.nthAttr, current)
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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 {
|
||||
|
@@ -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).
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user