Skip to content

tview.Escape escapes too much #1148

@isbldr

Description

@isbldr

When I render text escaped using tview.Escape into text view with .SetDynamicColors(true), I expect that it shows the same as if I disabled the dynamic colors and skipped the escape. And that I expect to show up the same as when I just print the text into console.
Instead, when ANSI escape sequences and [] brackets are involved, I get extra [. Attached is a reproduction case which shows the problem.

Reproduction case (go code)
package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/rivo/tview"
)

const structlogLine = "\x1b[2m2026-01-01T00:00:00Z\x1b[0m" +
	" [\x1b[32m\x1b[1minfo     \x1b[0m]" +
	" \x1b[1msome [yellow::]log message\x1b[0m" +
	" [\x1b[34mmyapp\x1b[0m]" +
	" \x1b[36mkey\x1b[0m=\x1b[35mvalue\x1b[0m"

func main() {
	app := tview.NewApplication()

	tv := tview.NewTextView().SetDynamicColors(true)

	// print raw line to stdout so that it's visible what I want to see
	fmt.Fprintln(os.Stdout, structlogLine)

	ansiWriter := tview.ANSIWriter(tv)

	// BUGGY: process-compose pipeline — Escape then ANSIWriter
	fmt.Fprint(ansiWriter, tview.Escape(structlogLine+"\n"))

	// FIXED: replace only when the ] would be interpretted
	fmt.Fprint(ansiWriter, strings.ReplaceAll(structlogLine, "::]", "::[]")+"\n")

	app.SetRoot(tv, true)

	if err := app.Run(); err != nil {
		panic(err)
	}
}

What I expect to see

2026-01-01T00:00:00Z [info     [] some [yellow::]log message [myapp[] key=value

What I see instead

2026-01-01T00:00:00Z [info     ] some [yellow::]log message [myapp] key=value

(note the extra bracket)

For context, this came up when investigating a bug in process-compose

AI use disclosure: this is my first time writing go, so I used LLMs to help me write the reproduction. I reduced it considerably from the crap it produced though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions