mirror of https://github.com/gdamore/tcell.git
Change interpretation of pushing quoted character in terminfo parser
I noticed this problem while running a gowid test program (palette.go) with TERM=xterm-16color. This terminal type is not present in tcell's built-in database, and so tcell falls back to the dynamic terminal type by parsing the output of infocmp. The symptom was that foreground colors were not correctly set, leaving a monochrome screen. This seems to be caused by a problem interpreting the *background* color terminfo rule. The attribute to set background color is defined like this (Ubuntu 20.04): $ infocmp xterm-16color | grep setab setab=\E[%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm, The middle sections says "if p1<8 then push(p1+'(') ". '(' is ascii 40. If I run $ tput setab 5 the terminal sees 'ESC[45m'. This correctly sets the background color to magenta. But if I tell tcell to emit a cell with background color set to tcell.Color(5), the terminal sees 'ESC[0m'. This means in practice, my app emits a code to set the foreground color, then an SGR code that resets all attributes, then the ASCII character. When tcell "runs" a terminfo rule in terminfo::TParm(), a push to the stack preserves the type of the argument pushed - int or string. When a single quote is encountered, the argument within is pushed to the stack as a string. For the `setab` rule above, tcell will then pop as an int, discarding the error and returning 0. The fix here is to have tcell push the argument inside the single quotes as an integer, using the ascii value of the argument e.g. "(" -> 40 - and assume the string is length 1, I suppose. Cross-referencing against ncurses/tinfo/lib_tinfo.c::tparam_internal(), it looks like this code assumes a single-quoted string is assumed to be length=1 and is also interpreted as an integer with the ascii value of the character: case S_QUOTE: cp++; npush(UChar(*cp)); cp++; break;
This commit is contained in:
parent
222a03c3db
commit
2d6d7fbe48
|
@ -461,7 +461,7 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
|||
case '\'': // push(char)
|
||||
ch, _ = pb.NextCh()
|
||||
pb.NextCh() // must be ' but we don't check
|
||||
stk = stk.Push(string(ch))
|
||||
stk = stk.PushInt(int(ch))
|
||||
|
||||
case '{': // push(int)
|
||||
ai = 0
|
||||
|
|
Loading…
Reference in New Issue