From 57596762dac9f61487472929b64d4bca797b7b0f Mon Sep 17 00:00:00 2001 From: Tobias Melson Date: Fri, 16 Feb 2024 15:28:05 +0100 Subject: [PATCH] Avoid replaceing inside color tag --- src/items.go | 18 +++++++++++++++++- src/items_test.go | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/items.go b/src/items.go index 3682e4f..8fd4dfb 100644 --- a/src/items.go +++ b/src/items.go @@ -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 @@ -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)) @@ -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)) +} diff --git a/src/items_test.go b/src/items_test.go index 672a1f7..2c0fd4d 100644 --- a/src/items_test.go +++ b/src/items_test.go @@ -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"}