mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-12 21:33:49 -05:00
Add special 'strip' style attribute for stripping colors
Test cases: fd --color always | fzf --ansi --delimiter / fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim,nth:regular fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular --raw fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular,hidden:strikethrough --raw fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular,hidden:strip:strikethrough --raw fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular,hidden:strip:dim:strikethrough --raw
This commit is contained in:
@@ -50,6 +50,14 @@ fzf --raw --color hidden:red:strikethrough:dim
|
|||||||
fzf --raw --color hidden:red:strikethrough:dim:italic
|
fzf --raw --color hidden:red:strikethrough:dim:italic
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For colored input, dimming alone may not be enough, and you may prefer to remove
|
||||||
|
colors entirely. For that case, a new special style attribute `strip` has been
|
||||||
|
added.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
fd --color always | fzf --ansi --raw --color hidden:dim:strip:strikethrough
|
||||||
|
```
|
||||||
|
|
||||||
#### Conditional actions for raw mode
|
#### Conditional actions for raw mode
|
||||||
|
|
||||||
You may want to perform different actions depending on whether the current item
|
You may want to perform different actions depending on whether the current item
|
||||||
|
|||||||
@@ -325,7 +325,8 @@ color mappings. Each entry is separated by a comma and/or whitespaces.
|
|||||||
\fB#rrggbb \fR24-bit colors
|
\fB#rrggbb \fR24-bit colors
|
||||||
|
|
||||||
.B ANSI ATTRIBUTES: (Only applies to foreground colors)
|
.B ANSI ATTRIBUTES: (Only applies to foreground colors)
|
||||||
\fBregular \fRClears previously set attributes; should precede the other ones
|
\fBregular \fRClear previously set attributes; should precede the other ones
|
||||||
|
\fBstrip \fRRemove colors
|
||||||
\fBbold\fR
|
\fBbold\fR
|
||||||
\fBunderline\fR
|
\fBunderline\fR
|
||||||
\fBreverse\fR
|
\fBreverse\fR
|
||||||
|
|||||||
@@ -1366,6 +1366,8 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) (*tui.ColorTheme, *tui
|
|||||||
cattr.Attr |= tui.Bold
|
cattr.Attr |= tui.Bold
|
||||||
case "dim":
|
case "dim":
|
||||||
cattr.Attr |= tui.Dim
|
cattr.Attr |= tui.Dim
|
||||||
|
case "strip":
|
||||||
|
cattr.Attr |= tui.Strip
|
||||||
case "italic":
|
case "italic":
|
||||||
cattr.Attr |= tui.Italic
|
cattr.Attr |= tui.Italic
|
||||||
case "underline":
|
case "underline":
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ func minRank() Result {
|
|||||||
return Result{item: &minItem, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
|
return Result{item: &minItem, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, theme *tui.ColorTheme, colBase tui.ColorPair, colMatch tui.ColorPair, attrNth tui.Attr) []colorOffset {
|
func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, theme *tui.ColorTheme, colBase tui.ColorPair, colMatch tui.ColorPair, attrNth tui.Attr, hidden bool) []colorOffset {
|
||||||
itemColors := result.item.Colors()
|
itemColors := result.item.Colors()
|
||||||
|
|
||||||
// No ANSI codes
|
// No ANSI codes
|
||||||
@@ -194,6 +194,10 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
|
|||||||
if !theme.Colored {
|
if !theme.Colored {
|
||||||
return tui.NewColorPair(-1, -1, ansi.color.attr).MergeAttr(base)
|
return tui.NewColorPair(-1, -1, ansi.color.attr).MergeAttr(base)
|
||||||
}
|
}
|
||||||
|
// fd --color always | fzf --ansi --delimiter / --nth -1 --color fg:dim:strip,nth:regular
|
||||||
|
if base.ShouldStripColors() {
|
||||||
|
return base
|
||||||
|
}
|
||||||
fg := ansi.color.fg
|
fg := ansi.color.fg
|
||||||
bg := ansi.color.bg
|
bg := ansi.color.bg
|
||||||
if fg == -1 {
|
if fg == -1 {
|
||||||
@@ -251,6 +255,9 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
|
|||||||
if curr.nth {
|
if curr.nth {
|
||||||
base = base.WithAttr(attrNth)
|
base = base.WithAttr(attrNth)
|
||||||
}
|
}
|
||||||
|
if hidden {
|
||||||
|
base = base.WithFg(theme.Hidden)
|
||||||
|
}
|
||||||
color := ansiToColorPair(ansi, base)
|
color := ansiToColorPair(ansi, base)
|
||||||
colors = append(colors, colorOffset{
|
colors = append(colors, colorOffset{
|
||||||
offset: [2]int32{int32(start), int32(idx)},
|
offset: [2]int32{int32(start), int32(idx)},
|
||||||
@@ -258,9 +265,13 @@ func (result *Result) colorOffsets(matchOffsets []Offset, nthOffsets []Offset, t
|
|||||||
match: false,
|
match: false,
|
||||||
url: ansi.color.url})
|
url: ansi.color.url})
|
||||||
} else {
|
} else {
|
||||||
|
color := colBase.WithAttr(attrNth)
|
||||||
|
if hidden {
|
||||||
|
color = color.WithFg(theme.Hidden)
|
||||||
|
}
|
||||||
colors = append(colors, colorOffset{
|
colors = append(colors, colorOffset{
|
||||||
offset: [2]int32{int32(start), int32(idx)},
|
offset: [2]int32{int32(start), int32(idx)},
|
||||||
color: colBase.WithAttr(attrNth),
|
color: color,
|
||||||
match: false,
|
match: false,
|
||||||
url: nil})
|
url: nil})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ func TestColorOffset(t *testing.T) {
|
|||||||
|
|
||||||
colBase := tui.NewColorPair(89, 189, tui.AttrUndefined)
|
colBase := tui.NewColorPair(89, 189, tui.AttrUndefined)
|
||||||
colMatch := tui.NewColorPair(99, 199, tui.AttrUndefined)
|
colMatch := tui.NewColorPair(99, 199, tui.AttrUndefined)
|
||||||
colors := item.colorOffsets(offsets, nil, tui.Dark256, colBase, colMatch, tui.AttrUndefined)
|
colors := item.colorOffsets(offsets, nil, tui.Dark256, colBase, colMatch, tui.AttrUndefined, false)
|
||||||
assert := func(idx int, b int32, e int32, c tui.ColorPair) {
|
assert := func(idx int, b int32, e int32, c tui.ColorPair) {
|
||||||
o := colors[idx]
|
o := colors[idx]
|
||||||
if o.offset[0] != b || o.offset[1] != e || o.color != c {
|
if o.offset[0] != b || o.offset[1] != e || o.color != c {
|
||||||
@@ -158,7 +158,7 @@ func TestColorOffset(t *testing.T) {
|
|||||||
|
|
||||||
nthOffsets := []Offset{{37, 39}, {42, 45}}
|
nthOffsets := []Offset{{37, 39}, {42, 45}}
|
||||||
for _, attr := range []tui.Attr{tui.AttrRegular, tui.StrikeThrough} {
|
for _, attr := range []tui.Attr{tui.AttrRegular, tui.StrikeThrough} {
|
||||||
colors = item.colorOffsets(offsets, nthOffsets, tui.Dark256, colRegular, colUnderline, attr)
|
colors = item.colorOffsets(offsets, nthOffsets, tui.Dark256, colRegular, colUnderline, attr, false)
|
||||||
|
|
||||||
// [{[0 5] {1 5 0}} {[5 15] {1 5 8}} {[15 20] {1 5 0}}
|
// [{[0 5] {1 5 0}} {[5 15] {1 5 8}} {[15 20] {1 5 0}}
|
||||||
// {[22 25] {2 6 1}} {[25 27] {2 6 9}} {[27 30] {-1 -1 8}}
|
// {[22 25] {2 6 1}} {[25 27] {2 6 9}} {[27 30] {-1 -1 8}}
|
||||||
|
|||||||
@@ -1485,7 +1485,7 @@ func (t *Terminal) ansiLabelPrinter(str string, color *tui.ColorPair, fill bool)
|
|||||||
printFn := func(window tui.Window, limit int) {
|
printFn := func(window tui.Window, limit int) {
|
||||||
if offsets == nil {
|
if offsets == nil {
|
||||||
// tui.Col* are not initialized until renderer.Init()
|
// tui.Col* are not initialized until renderer.Init()
|
||||||
offsets = result.colorOffsets(nil, nil, t.theme, *color, *color, t.nthAttr)
|
offsets = result.colorOffsets(nil, nil, t.theme, *color, *color, t.nthAttr, false)
|
||||||
}
|
}
|
||||||
for limit > 0 {
|
for limit > 0 {
|
||||||
if length > limit {
|
if length > limit {
|
||||||
@@ -1548,7 +1548,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
t.printHighlighted(
|
t.printHighlighted(
|
||||||
Result{item: item}, tui.ColPrompt, tui.ColPrompt, false, false, line, line, true, preTask, nil)
|
Result{item: item}, tui.ColPrompt, tui.ColPrompt, false, false, false, line, line, true, preTask, nil)
|
||||||
})
|
})
|
||||||
t.wrap = wrap
|
t.wrap = wrap
|
||||||
}
|
}
|
||||||
@@ -3070,7 +3070,7 @@ func (t *Terminal) printFooter() {
|
|||||||
colors: colors}
|
colors: colors}
|
||||||
|
|
||||||
t.printHighlighted(Result{item: item},
|
t.printHighlighted(Result{item: item},
|
||||||
tui.ColFooter, tui.ColFooter, false, false, line, line, true,
|
tui.ColFooter, tui.ColFooter, false, false, false, line, line, true,
|
||||||
func(markerClass) int {
|
func(markerClass) int {
|
||||||
t.footerWindow.Print(indent)
|
t.footerWindow.Print(indent)
|
||||||
return indentSize
|
return indentSize
|
||||||
@@ -3142,7 +3142,7 @@ func (t *Terminal) printHeaderImpl(window tui.Window, borderShape tui.BorderShap
|
|||||||
colors: colors}
|
colors: colors}
|
||||||
|
|
||||||
t.printHighlighted(Result{item: item},
|
t.printHighlighted(Result{item: item},
|
||||||
tui.ColHeader, tui.ColHeader, false, false, line, line, true,
|
tui.ColHeader, tui.ColHeader, false, false, false, line, line, true,
|
||||||
func(markerClass) int {
|
func(markerClass) int {
|
||||||
t.window.Print(indent)
|
t.window.Print(indent)
|
||||||
return indentSize
|
return indentSize
|
||||||
@@ -3378,13 +3378,7 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
|
|||||||
}
|
}
|
||||||
return indentSize
|
return indentSize
|
||||||
}
|
}
|
||||||
base := tui.ColCurrent
|
finalLineNum = t.printHighlighted(result, tui.ColCurrent, tui.ColCurrentMatch, true, true, !matched, line, maxLine, forceRedraw, preTask, postTask)
|
||||||
match := tui.ColCurrentMatch
|
|
||||||
if !matched {
|
|
||||||
base = base.WithFg(t.theme.Hidden)
|
|
||||||
match = match.WithFg(t.theme.Hidden)
|
|
||||||
}
|
|
||||||
finalLineNum = t.printHighlighted(result, base, match, true, true, line, maxLine, forceRedraw, preTask, postTask)
|
|
||||||
} else {
|
} else {
|
||||||
preTask := func(marker markerClass) int {
|
preTask := func(marker markerClass) int {
|
||||||
w := t.window.Width() - t.pointerLen
|
w := t.window.Width() - t.pointerLen
|
||||||
@@ -3418,11 +3412,7 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
|
|||||||
base = base.WithBg(altBg)
|
base = base.WithBg(altBg)
|
||||||
match = match.WithBg(altBg)
|
match = match.WithBg(altBg)
|
||||||
}
|
}
|
||||||
if !matched {
|
finalLineNum = t.printHighlighted(result, base, match, false, true, !matched, line, maxLine, forceRedraw, preTask, postTask)
|
||||||
base = base.WithFg(t.theme.Hidden)
|
|
||||||
match = match.WithFg(t.theme.Hidden)
|
|
||||||
}
|
|
||||||
finalLineNum = t.printHighlighted(result, base, match, false, true, line, maxLine, forceRedraw, preTask, postTask)
|
|
||||||
}
|
}
|
||||||
for i := 0; i < t.gap && finalLineNum < maxLine; i++ {
|
for i := 0; i < t.gap && finalLineNum < maxLine; i++ {
|
||||||
finalLineNum++
|
finalLineNum++
|
||||||
@@ -3469,7 +3459,7 @@ func (t *Terminal) overflow(runes []rune, max int) bool {
|
|||||||
return t.displayWidthWithLimit(runes, 0, max) > max
|
return t.displayWidthWithLimit(runes, 0, max) > max
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMatch tui.ColorPair, current bool, match bool, lineNum int, maxLineNum int, forceRedraw bool, preTask func(markerClass) int, postTask func(int, int, bool, bool, tui.ColorPair)) int {
|
func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMatch tui.ColorPair, current bool, match bool, hidden bool, lineNum int, maxLineNum int, forceRedraw bool, preTask func(markerClass) int, postTask func(int, int, bool, bool, tui.ColorPair)) int {
|
||||||
var displayWidth int
|
var displayWidth int
|
||||||
item := result.item
|
item := result.item
|
||||||
matchOffsets := []Offset{}
|
matchOffsets := []Offset{}
|
||||||
@@ -3521,7 +3511,7 @@ func (t *Terminal) printHighlighted(result Result, colBase tui.ColorPair, colMat
|
|||||||
sort.Sort(ByOrder(nthOffsets))
|
sort.Sort(ByOrder(nthOffsets))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allOffsets := result.colorOffsets(charOffsets, nthOffsets, t.theme, colBase, colMatch, t.nthAttr)
|
allOffsets := result.colorOffsets(charOffsets, nthOffsets, t.theme, colBase, colMatch, t.nthAttr, hidden)
|
||||||
|
|
||||||
maxLines := 1
|
maxLines := 1
|
||||||
if t.canSpanMultiLines() {
|
if t.canSpanMultiLines() {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const (
|
|||||||
AttrClear = Attr(1 << 9)
|
AttrClear = Attr(1 << 9)
|
||||||
BoldForce = Attr(1 << 10)
|
BoldForce = Attr(1 << 10)
|
||||||
FullBg = Attr(1 << 11)
|
FullBg = Attr(1 << 11)
|
||||||
|
Strip = Attr(1 << 12)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a Attr) Merge(b Attr) Attr {
|
func (a Attr) Merge(b Attr) Attr {
|
||||||
@@ -384,6 +385,10 @@ func (p ColorPair) IsFullBgMarker() bool {
|
|||||||
return p.attr&FullBg > 0
|
return p.attr&FullBg > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p ColorPair) ShouldStripColors() bool {
|
||||||
|
return p.attr&Strip > 0
|
||||||
|
}
|
||||||
|
|
||||||
func (p ColorPair) HasBg() bool {
|
func (p ColorPair) HasBg() bool {
|
||||||
return p.attr&Reverse == 0 && p.bg != colDefault ||
|
return p.attr&Reverse == 0 && p.bg != colDefault ||
|
||||||
p.attr&Reverse > 0 && p.fg != colDefault
|
p.attr&Reverse > 0 && p.fg != colDefault
|
||||||
|
|||||||
Reference in New Issue
Block a user