mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-07 23:52:04 -07:00
Support ANSI code for clearing the rest of the line (ESC[0K)
Some programs use it to set the background color for the whole line. fzf --preview "printf 'normal \x1b[42mgreen\x1b[0K \x1b[43myellow\x1b[m\nnormal again'" fzf --preview 'delta <(echo foo) <(echo bar) < /dev/tty' Fix #2249
This commit is contained in:
12
src/ansi.go
12
src/ansi.go
@@ -19,17 +19,18 @@ type ansiState struct {
|
|||||||
fg tui.Color
|
fg tui.Color
|
||||||
bg tui.Color
|
bg tui.Color
|
||||||
attr tui.Attr
|
attr tui.Attr
|
||||||
|
lbg tui.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ansiState) colored() bool {
|
func (s *ansiState) colored() bool {
|
||||||
return s.fg != -1 || s.bg != -1 || s.attr > 0
|
return s.fg != -1 || s.bg != -1 || s.attr > 0 || s.lbg >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ansiState) equals(t *ansiState) bool {
|
func (s *ansiState) equals(t *ansiState) bool {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return !s.colored()
|
return !s.colored()
|
||||||
}
|
}
|
||||||
return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr
|
return s.fg == t.fg && s.bg == t.bg && s.attr == t.attr && s.lbg == t.lbg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ansiState) ToString() string {
|
func (s *ansiState) ToString() string {
|
||||||
@@ -195,11 +196,14 @@ func interpretCode(ansiCode string, prevState *ansiState) *ansiState {
|
|||||||
// State
|
// State
|
||||||
var state *ansiState
|
var state *ansiState
|
||||||
if prevState == nil {
|
if prevState == nil {
|
||||||
state = &ansiState{-1, -1, 0}
|
state = &ansiState{-1, -1, 0, -1}
|
||||||
} else {
|
} else {
|
||||||
state = &ansiState{prevState.fg, prevState.bg, prevState.attr}
|
state = &ansiState{prevState.fg, prevState.bg, prevState.attr, prevState.lbg}
|
||||||
}
|
}
|
||||||
if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || ansiCode[len(ansiCode)-1] != 'm' {
|
if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || ansiCode[len(ansiCode)-1] != 'm' {
|
||||||
|
if strings.HasSuffix(ansiCode, "0K") {
|
||||||
|
state.lbg = prevState.bg
|
||||||
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -525,7 +525,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) {
|
|||||||
// // unless the part has a non-default ANSI state
|
// // unless the part has a non-default ANSI state
|
||||||
loc := whiteSuffix.FindStringIndex(trimmed)
|
loc := whiteSuffix.FindStringIndex(trimmed)
|
||||||
if loc != nil {
|
if loc != nil {
|
||||||
blankState := ansiOffset{[2]int32{int32(loc[0]), int32(loc[1])}, ansiState{-1, -1, tui.AttrClear}}
|
blankState := ansiOffset{[2]int32{int32(loc[0]), int32(loc[1])}, ansiState{-1, -1, tui.AttrClear, -1}}
|
||||||
if item.colors != nil {
|
if item.colors != nil {
|
||||||
lastColor := (*item.colors)[len(*item.colors)-1]
|
lastColor := (*item.colors)[len(*item.colors)-1]
|
||||||
if lastColor.offset[1] < int32(loc[1]) {
|
if lastColor.offset[1] < int32(loc[1]) {
|
||||||
@@ -1277,6 +1277,10 @@ func (t *Terminal) renderPreviewText(unchanged bool) {
|
|||||||
}
|
}
|
||||||
var ansi *ansiState
|
var ansi *ansiState
|
||||||
for _, line := range t.previewer.lines {
|
for _, line := range t.previewer.lines {
|
||||||
|
var lbg tui.Color = -1
|
||||||
|
if ansi != nil {
|
||||||
|
ansi.lbg = -1
|
||||||
|
}
|
||||||
line = strings.TrimSuffix(line, "\n")
|
line = strings.TrimSuffix(line, "\n")
|
||||||
if lineNo >= height || t.pwindow.Y() == height-1 && t.pwindow.X() > 0 {
|
if lineNo >= height || t.pwindow.Y() == height-1 && t.pwindow.X() > 0 {
|
||||||
t.previewed.filled = true
|
t.previewed.filled = true
|
||||||
@@ -1292,6 +1296,7 @@ func (t *Terminal) renderPreviewText(unchanged bool) {
|
|||||||
str, width := t.processTabs(trimmed, prefixWidth)
|
str, width := t.processTabs(trimmed, prefixWidth)
|
||||||
prefixWidth += width
|
prefixWidth += width
|
||||||
if t.theme.Colored && ansi != nil && ansi.colored() {
|
if t.theme.Colored && ansi != nil && ansi.colored() {
|
||||||
|
lbg = ansi.lbg
|
||||||
fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
|
fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str)
|
||||||
} else {
|
} else {
|
||||||
fillRet = t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), tui.AttrRegular, str)
|
fillRet = t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), tui.AttrRegular, str)
|
||||||
@@ -1308,7 +1313,12 @@ func (t *Terminal) renderPreviewText(unchanged bool) {
|
|||||||
if unchanged && lineNo == 0 {
|
if unchanged && lineNo == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
t.pwindow.Fill("\n")
|
if lbg >= 0 {
|
||||||
|
t.pwindow.CFill(-1, lbg, tui.AttrRegular,
|
||||||
|
strings.Repeat(" ", t.pwindow.Width()-t.pwindow.X())+"\n")
|
||||||
|
} else {
|
||||||
|
t.pwindow.Fill("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lineNo++
|
lineNo++
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
package tui
|
package tui
|
||||||
|
|
||||||
type Attr int
|
type Attr int32
|
||||||
|
|
||||||
func HasFullscreenRenderer() bool {
|
func HasFullscreenRenderer() bool {
|
||||||
return false
|
return false
|
||||||
|
Reference in New Issue
Block a user