selection: recognize empty padding cells in a forced linewrap

When printing a multi-column character at the end of the line, and it
doesn't fit, we currently insert a forced line-wrap. This means the
last character(s) on the previous line will be empty, followed by a
multi-column character in the first cell on the next line.

Without special code to handle this, the selection text extraction
code will insert a hard newline, since this is normally the correct
thing to do.

Add a TODO, to consider writing a special place holder value to these
padding cells.
This commit is contained in:
Daniel Eklöf 2020-07-14 13:17:50 +02:00
parent 3bc404b5a3
commit 4cf7195695
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 45 additions and 9 deletions

View file

@ -269,15 +269,41 @@ extract_one(struct terminal *term, struct row *row, struct cell *cell,
{
struct extract *ctx = data;
if (ctx->last_row != NULL && row != ctx->last_row &&
((term->selection.kind == SELECTION_NORMAL &&
(ctx->last_row->linebreak ||
ctx->empty_count > 0 || cell->wc == 0)) ||
term->selection.kind == SELECTION_BLOCK))
{
/* Last cell was the last column in the selection */
ctx->buf[ctx->idx++] = L'\n';
ctx->empty_count = 0;
if (ctx->last_row != NULL && row != ctx->last_row) {
/* New row - determine if we should insert a newline or not */
if (term->selection.kind == SELECTION_NORMAL) {
int width = max(1, wcwidth(cell->wc));
if (width > 1) {
/* Heuristict to handle force-wrapped multi-column
* characters */
/*
* TODO: maybe we should print a placeholder value to
* the empty cells at the end of the line when
* force-wrapping? Then extract() could simply skip
* those cells
*/
ctx->empty_count -= min(width, ctx->empty_count);
}
else if (ctx->last_row->linebreak ||
ctx->empty_count > 0 ||
cell->wc == 0)
{
/* Row has a hard linebreak, or either last cell or
* current cell is empty */
ctx->buf[ctx->idx++] = L'\n';
ctx->empty_count = 0;
}
}
else if (term->selection.kind == SELECTION_BLOCK) {
/* Always insert a linebreak */
ctx->buf[ctx->idx++] = L'\n';
ctx->empty_count = 0;
}
}
if (cell->wc == 0) {

View file

@ -2399,6 +2399,16 @@ term_print(struct terminal *term, wchar_t wc, int width)
/* Multi-column character that doesn't fit on current line -
* force a line wrap */
term->grid->cursor.lcf = 1;
/*
* TODO: should we insert place holder values in the remaining
* cells? This would allow e.g. text extraction to simply
* skip these, instead of trying to recognize a sequence of
* empty cells at the end of the line followed by a
* multi-column character...
*
* Might also make text reflow easier, or even more correct.
*/
}
print_linewrap(term);