If the cursor is already at the right edge, our logic that checked for
non-empty cells failed; it didn’t check the current cell.
Fix by initializing ‘emit_tab_char’ to true/false, depending on the
contents of the current cell.
TAB (\t) move the cursor to the next tab stop. That’s it, according to
the specification.
However, many terminal emulators try to keep tabs in the grid, to be
able to e.g. copy them. That is, copying a text chunk containing tabs
should result in tabs being pasted, not spaces.
In order to do that, we need to print a tab character to the grid. To
improve text reflow of tabs, we also print spaces to the subsequent
cells, up until (but not including) the next tab stop.
However, we can only do this if all the cells between the cursor and
the next tab stop are empty, since (obviously), we cannot overwrite
pre-existing characters.
Finally, while some fonts render tabs as spaces (i.e. an empty glyph),
some use a glyph representing “unprintable” characters, or
similar. Thus, we need to exclude cells with tab characters when
rendering.
This matches XTerm behavior, and fixes vttest 11.6.6.2:
Test non-VT100 ->
Test ISO-6429 colors ->
Test of VT102-style features with BCE ->
Test of screen features
Only the first character in the chain was being compared with `priv`
and the rest were just being evaluated as simple expressions. This
was causing the G2 and G3 operations to erroneously use the G1 index.
Since the characters are a contiguous range, we can just subtract the
start of the range to get the appropriate index. The outer switch
statement already ensures the values are in range.
Without this fix, setting LOG_ENABLE_DBG to 1 in terminal.c would
cause the following error:
> terminal.c:1787: 'struct terminal' has no member named 'font_scale'
The 'font_scale' member was removed in commit
2afc678236.
When marking and unmarking cells, we don’t highlight trailing empty
cells. We do however highlight empty cells if they are followed by
non-empty cells.
I think this was an intentional choice. If one row ended with trailing
empty cells, but *no* hard linebreak, then we’d continue on the next
row, and emit all the empty cells once we hit a non-emtpy cell on the
second row.
But this is something that shouldn’t happen in any real-world use
cases.
Since the alt screen have no scrollback, all scrollback-* actions are
effectively no-ops when the alt screen is active.
Make them available to the client application instead.
Closes#573
Instead of walking the old grid cell-by-cell, and checking for
tracking points, OSC-8 URIs etc on each cell, memcpy() sequences of
cells.
For each row, find the end column, by scanning backward, looking for
the first non-empty cell.
Chunk the row based on tracking point coordinates. If there aren’t any
tracking coordinates, or OSC-8 URIs on the current row, the entire row
is copied in one go.
The chunk of cells is copied to the new grid. We may have to split it
up into multiple copies, since not all cells may fit on the current
“new” row.
Care must also be taken to not line break in the middle of a
multi-column character.
When we resize the alt screen, we don’t reflow the text, we simply
truncate all the lines.
When doing this, make sure we don’t truncate in the middle of a
multi-column character.
When an auto-detected URL ended *on* the right-most column, the URL
endpoint was off by one, resulting in the underline in URL mode being
one character short.
When enabled, PUA (Private Usage Area) codepoints are always treated
as double-width glyphs, regardless of the actual glyph width.
Requires allow-overflowing-double-width-glyphs=yes