diff --git a/color.go b/color.go index a27f041..3e4f585 100644 --- a/color.go +++ b/color.go @@ -160,6 +160,8 @@ func xTermColor(s string) (RGBColor, error) { switch { case strings.HasSuffix(s, "\a"): s = strings.TrimSuffix(s, "\a") + case strings.HasSuffix(s, "\033"): + s = strings.TrimSuffix(s, "\033") case strings.HasSuffix(s, "\033\\"): s = strings.TrimSuffix(s, "\033\\") default: diff --git a/color_test.go b/color_test.go index de47355..9f7cb77 100644 --- a/color_test.go +++ b/color_test.go @@ -8,6 +8,11 @@ func TestXTermColor(t *testing.T) { color RGBColor valid bool }{ + { + "\033]11;rgb:fafa/fafa/fafa\033", + RGBColor("#fafafa"), + true, + }, { "\033]11;rgb:fafa/fafa/fafa\033\\", RGBColor("#fafafa"), diff --git a/termenv_unix.go b/termenv_unix.go index ec68a49..3c48782 100644 --- a/termenv_unix.go +++ b/termenv_unix.go @@ -101,12 +101,21 @@ func readNextByte(f *os.File) (byte, error) { // * OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\" // * cursor position response: "\x1b[42;1R" func readNextResponse(fd *os.File) (response string, isOSC bool, err error) { - // first byte must be ESC start, err := readNextByte(fd) if err != nil { return "", false, err } + // if we encounter a backslash, this is a left-over from the previous OSC + // response, which can be terminated by an optional backslash + if start == '\\' { + start, err = readNextByte(fd) + if err != nil { + return "", false, err + } + } + + // first byte must be ESC if start != '\033' { return "", false, ErrStatusReport } @@ -140,8 +149,8 @@ func readNextResponse(fd *os.File) (response string, isOSC bool, err error) { response += string(b) if oscResponse { - // OSC can be terminated by BEL (\a) or ST (ESC \) - if b == '\a' || strings.HasSuffix(response, "\033\\") { + // OSC can be terminated by BEL (\a) or ST (ESC) + if b == '\a' || strings.HasSuffix(response, "\033") { return response, true, nil } } else { @@ -161,6 +170,8 @@ func readNextResponse(fd *os.File) (response string, isOSC bool, err error) { } func termStatusReport(sequence int) (string, error) { + // screen/tmux can't support OSC, because they can be connected to multiple + // terminals concurrently. term := os.Getenv("TERM") if strings.HasPrefix(term, "screen") { return "", ErrStatusReport @@ -202,6 +213,6 @@ func termStatusReport(sequence int) (string, error) { return "", err } - // fmt.Println("Rcvd", s[1:]) + // fmt.Println("Rcvd", res[1:]) return res, nil }