diff options
author | Junegunn Choi <junegunn.c@gmail.com> | 2020-11-25 01:40:30 +0900 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2020-11-25 01:49:48 +0900 |
commit | 3829eab1cf572d26e12dd5d96b1700c07c2905fc (patch) | |
tree | 06786ec2c59786e8e0df17f0c66fc341cbb5d6e6 /src | |
parent | 3fe8eeedc5f5180f9c9db76fca26844f8c6acf37 (diff) |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/ansi.go | 12 | ||||
-rw-r--r-- | src/terminal.go | 14 | ||||
-rw-r--r-- | src/tui/dummy.go | 2 |
3 files changed, 21 insertions, 7 deletions
diff --git a/src/ansi.go b/src/ansi.go index b15bd91c..0d716c0d 100644 --- a/src/ansi.go +++ b/src/ansi.go @@ -19,17 +19,18 @@ type ansiState struct { fg tui.Color bg tui.Color attr tui.Attr + lbg tui.Color } 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 { if t == nil { 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 { @@ -195,11 +196,14 @@ func interpretCode(ansiCode string, prevState *ansiState) *ansiState { // State var state *ansiState if prevState == nil { - state = &ansiState{-1, -1, 0} + state = &ansiState{-1, -1, 0, -1} } 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 strings.HasSuffix(ansiCode, "0K") { + state.lbg = prevState.bg + } return state } diff --git a/src/terminal.go b/src/terminal.go index a294f26d..14a90d51 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -525,7 +525,7 @@ func (t *Terminal) parsePrompt(prompt string) (func(), int) { // // unless the part has a non-default ANSI state loc := whiteSuffix.FindStringIndex(trimmed) 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 { lastColor := (*item.colors)[len(*item.colors)-1] if lastColor.offset[1] < int32(loc[1]) { @@ -1277,6 +1277,10 @@ func (t *Terminal) renderPreviewText(unchanged bool) { } var ansi *ansiState for _, line := range t.previewer.lines { + var lbg tui.Color = -1 + if ansi != nil { + ansi.lbg = -1 + } line = strings.TrimSuffix(line, "\n") if lineNo >= height || t.pwindow.Y() == height-1 && t.pwindow.X() > 0 { t.previewed.filled = true @@ -1292,6 +1296,7 @@ func (t *Terminal) renderPreviewText(unchanged bool) { str, width := t.processTabs(trimmed, prefixWidth) prefixWidth += width if t.theme.Colored && ansi != nil && ansi.colored() { + lbg = ansi.lbg fillRet = t.pwindow.CFill(ansi.fg, ansi.bg, ansi.attr, str) } else { 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 { 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++ } diff --git a/src/tui/dummy.go b/src/tui/dummy.go index ca50e655..af7e759c 100644 --- a/src/tui/dummy.go +++ b/src/tui/dummy.go @@ -4,7 +4,7 @@ package tui -type Attr int +type Attr int32 func HasFullscreenRenderer() bool { return false |