Skip to content

Commit

Permalink
Avoid replaceing inside color tag
Browse files Browse the repository at this point in the history
  • Loading branch information
terminationshock committed Feb 16, 2024
1 parent 188a46d commit 5759676
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/items.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const tabSize = 4
var reAnsiColorCodes = regexp.MustCompile("\\x1B\\[(([0-9]{1,2})?(;)?([0-9]{1,2})?)?[m,K,H,f,J]")
var reColorTag = regexp.MustCompile("\\[[a-z-]+:[a-z:-]*\\]")

type ItemList struct {
items []Item
Expand Down Expand Up @@ -75,7 +76,7 @@ func (item *Item) highlightFirstMatch(matches []string) bool {
item.match = match
highlighted := strings.Replace(matches[0], item.match, "[::-][::r]" + item.match + "[::-]", 1)
if strings.Contains(item.display, matches[0]) {
item.display = strings.Replace(item.display, matches[0], highlighted, 1)
item.display = replaceFirst(item.display, matches[0], highlighted)
} else {
// Special case where the color ranges intersect
item.display = mergeStrings(item.display, strings.Replace(item.original, matches[0], highlighted, 1))
Expand Down Expand Up @@ -204,3 +205,18 @@ func mergeStrings(string1 string, string2 string) string {

return string(result)
}

func replaceFirst(s string, old string, new string) string {
var b strings.Builder
b.Grow(len(s) + len(new) - len(old))

i := strings.Index(reColorTag.ReplaceAllStringFunc(s, maskString), old)
b.WriteString(s[:i])
b.WriteString(new)
b.WriteString(s[i + len(old):])
return b.String()
}

func maskString(s string) string {
return strings.Repeat(" ", len(s))
}
15 changes: 15 additions & 0 deletions src/items_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ func TestProcessRegexpWithColors(t *testing.T) {
}
}

func TestProcessRegexpWithMatchInColor(t *testing.T) {
lines := []string{"\033[32mgreen\033[0m green", "green \033[32mgreen\033[0m"}

config = &Config{}
config.pattern = regexp.MustCompile("e")
items := NewItemList(lines)

if items.items[0].display != "[green:]gr[::-][::r]e[::-]en[-:-:] green" {
t.Error("Incorrect processed colored line with match in color tag")
}
if items.items[1].display != "gr[::-][::r]e[::-]en [green:]green[-:-:]" {
t.Error("Incorrect processed colored line with match in color tag")
}
}

func TestProcessRegexpWithFunc(t *testing.T) {
lines := []string{"the match MATCH"}

Expand Down

0 comments on commit 5759676

Please sign in to comment.