diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2025-06-24 22:50:02 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2025-06-25 02:12:10 +0900 |
| commit | 4811e52af3ed7f89e82baa908f9a8a25fb593361 (patch) | |
| tree | da7d88eadf9a0e8044b4748dd790cd599117b663 /src/ansi.go | |
| parent | 8d81730ec2855d3d32a171f8b675430ffb4c4d59 (diff) | |
| download | fzf-4811e52af3ed7f89e82baa908f9a8a25fb593361.tar.gz | |
Support full-line background color in the list section
Close #4432
Diffstat (limited to 'src/ansi.go')
| -rw-r--r-- | src/ansi.go | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/ansi.go b/src/ansi.go index 79359d34..cbe73c21 100644 --- a/src/ansi.go +++ b/src/ansi.go @@ -156,13 +156,13 @@ func isCtrlSeqStart(c uint8) bool { // nextAnsiEscapeSequence returns the ANSI escape sequence and is equivalent to // calling FindStringIndex() on the below regex (which was originally used): // -// "(?:\x1b[\\[()][0-9;:?]*[a-zA-Z@]|\x1b][0-9]+[;:][[:print:]]+(?:\x1b\\\\|\x07)|\x1b.|[\x0e\x0f]|.\x08)" +// "(?:\x1b[\\[()][0-9;:?]*[a-zA-Z@]|\x1b][0-9]+[;:][[:print:]]+(?:\x1b\\\\|\x07)|\x1b.|[\x0e\x0f]|.\x08|\n)" func nextAnsiEscapeSequence(s string) (int, int) { // fast check for ANSI escape sequences i := 0 for ; i < len(s); i++ { switch s[i] { - case '\x0e', '\x0f', '\x1b', '\x08': + case '\x0e', '\x0f', '\x1b', '\x08', '\n': // We ignore the fact that '\x08' cannot be the first char // in the string and be an escape sequence for the sake of // speed and simplicity. @@ -174,6 +174,9 @@ func nextAnsiEscapeSequence(s string) (int, int) { Loop: for ; i < len(s); i++ { switch s[i] { + case '\n': + // match: `\n` + return i, i + 1 case '\x08': // backtrack to match: `.\x08` if i > 0 && s[i-1] != '\n' { @@ -265,13 +268,27 @@ func extractColor(str string, state *ansiState, proc func(string, *ansiState) bo output.WriteString(prev) } - newState := interpretCode(str[start:idx], state) - if !newState.equals(state) { + code := str[start:idx] + newState := interpretCode(code, state) + if code == "\n" || !newState.equals(state) { if state != nil { // Update last offset (&offsets[len(offsets)-1]).offset[1] = int32(runeCount) } + if code == "\n" { + output.WriteRune('\n') + // Full-background marker + if newState.lbg >= 0 { + marker := newState + marker.attr |= tui.FullBg + offsets = append(offsets, ansiOffset{ + [2]int32{int32(runeCount), int32(runeCount)}, + marker, + }) + } + } + if newState.colored() { // Append new offset if pstate == nil { @@ -349,6 +366,13 @@ func parseAnsiCode(s string) (int, string) { } func interpretCode(ansiCode string, prevState *ansiState) ansiState { + if ansiCode == "\n" { + if prevState != nil { + return *prevState + } + return ansiState{-1, -1, 0, -1, nil} + } + var state ansiState if prevState == nil { state = ansiState{-1, -1, 0, -1, nil} @@ -435,6 +459,7 @@ func interpretCode(ansiCode string, prevState *ansiState) ansiState { state.fg = -1 state.bg = -1 state.attr = 0 + state.lbg = -1 state256 = 0 default: if num >= 30 && num <= 37 { @@ -477,6 +502,7 @@ func interpretCode(ansiCode string, prevState *ansiState) ansiState { state.fg = -1 state.bg = -1 state.attr = 0 + state.lbg = -1 } if state256 > 0 { |
