Merge branch 'line-wise-selection-with-soft-line-wrapping'

Closes #726
This commit is contained in:
Daniel Eklöf 2021-10-01 16:26:26 +02:00
commit 951fa81989
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 86 additions and 17 deletions

View file

@ -68,6 +68,8 @@
* Added workaround for GNOME bug where multiple button press events * Added workaround for GNOME bug where multiple button press events
(for the same button) is sent to the CSDs without any release or (for the same button) is sent to the CSDs without any release or
leave events in between (https://codeberg.org/dnkl/foot/issues/709). leave events in between (https://codeberg.org/dnkl/foot/issues/709).
* Line-wise selection not taking soft line-wrapping into account
(https://codeberg.org/dnkl/foot/issues/726).
### Security ### Security

View file

@ -378,6 +378,50 @@ selection_find_word_boundary_right(struct terminal *term, struct coord *pos,
} }
} }
void
selection_find_line_boundary_left(struct terminal *term, struct coord *pos,
bool spaces_only)
{
int next_row = pos->row;
pos->col = 0;
while (true) {
if (--next_row < 0)
return;
const struct row *row = grid_row_in_view(term->grid, next_row);
assert(row != NULL);
if (row->linebreak)
return;
pos->col = 0;
pos->row = next_row;
}
}
void
selection_find_line_boundary_right(struct terminal *term, struct coord *pos,
bool spaces_only)
{
int next_row = pos->row;
pos->col = term->cols - 1;
while (true) {
const struct row *row = grid_row_in_view(term->grid, next_row);
assert(row != NULL);
if (row->linebreak)
return;
if (++next_row >= term->rows)
return;
pos->col = term->cols - 1;
pos->row = next_row;
}
}
void void
selection_start(struct terminal *term, int col, int row, selection_start(struct terminal *term, int col, int row,
enum selection_kind kind, enum selection_kind kind,
@ -421,13 +465,19 @@ selection_start(struct terminal *term, int col, int row,
break; break;
} }
case SELECTION_LINE_WISE: case SELECTION_LINE_WISE: {
term->selection.start = (struct coord){0, term->grid->view + row}; struct coord start = {0, row}, end = {term->cols - 1, row};
term->selection.pivot.start = term->selection.start; selection_find_line_boundary_left(term, &start, spaces_only);
term->selection.pivot.end = (struct coord){term->cols - 1, term->grid->view + row}; selection_find_line_boundary_right(term, &end, spaces_only);
selection_update(term, term->cols - 1, row); term->selection.start = (struct coord){
start.col, term->grid->view + start.row};
term->selection.pivot.start = term->selection.start;
term->selection.pivot.end = (struct coord){end.col, term->grid->view + end.row};
selection_update(term, end.col, end.row);
break; break;
}
case SELECTION_NONE: case SELECTION_NONE:
BUG("Invalid selection kind"); BUG("Invalid selection kind");
@ -756,13 +806,21 @@ selection_update(struct terminal *term, int col, int row)
case SELECTION_LINE_WISE: case SELECTION_LINE_WISE:
switch (term->selection.direction) { switch (term->selection.direction) {
case SELECTION_LEFT: case SELECTION_LEFT: {
new_end.col = 0; struct coord end = {0, row};
selection_find_line_boundary_left(
term, &end, term->selection.spaces_only);
new_end = (struct coord){end.col, term->grid->view + end.row};
break; break;
}
case SELECTION_RIGHT: case SELECTION_RIGHT: {
new_end.col = term->cols - 1; struct coord end = {col, row};
selection_find_line_boundary_right(
term, &end, term->selection.spaces_only);
new_end = (struct coord){end.col, term->grid->view + end.row};
break; break;
}
case SELECTION_UNDIR: case SELECTION_UNDIR:
break; break;
@ -870,6 +928,8 @@ selection_extend_normal(struct terminal *term, int col, int row,
} }
} }
const bool spaces_only = term->selection.spaces_only;
switch (term->selection.kind) { switch (term->selection.kind) {
case SELECTION_CHAR_WISE: case SELECTION_CHAR_WISE:
xassert(new_kind == SELECTION_CHAR_WISE); xassert(new_kind == SELECTION_CHAR_WISE);
@ -883,10 +943,8 @@ selection_extend_normal(struct terminal *term, int col, int row,
struct coord pivot_start = {new_start.col, new_start.row - term->grid->view}; struct coord pivot_start = {new_start.col, new_start.row - term->grid->view};
struct coord pivot_end = pivot_start; struct coord pivot_end = pivot_start;
selection_find_word_boundary_left( selection_find_word_boundary_left(term, &pivot_start, spaces_only);
term, &pivot_start, term->selection.spaces_only); selection_find_word_boundary_right(term, &pivot_end, spaces_only);
selection_find_word_boundary_right(
term, &pivot_end, term->selection.spaces_only);
term->selection.pivot.start = term->selection.pivot.start =
(struct coord){pivot_start.col, term->grid->view + pivot_start.row}; (struct coord){pivot_start.col, term->grid->view + pivot_start.row};
@ -895,13 +953,22 @@ selection_extend_normal(struct terminal *term, int col, int row,
break; break;
} }
case SELECTION_LINE_WISE: case SELECTION_LINE_WISE: {
xassert(new_kind == SELECTION_CHAR_WISE || xassert(new_kind == SELECTION_CHAR_WISE ||
new_kind == SELECTION_LINE_WISE); new_kind == SELECTION_LINE_WISE);
term->selection.pivot.start = (struct coord){0, new_start.row}; struct coord pivot_start = {new_start.col, new_start.row - term->grid->view};
term->selection.pivot.end = (struct coord){term->cols - 1, new_start.row}; struct coord pivot_end = pivot_start;
selection_find_line_boundary_left(term, &pivot_start, spaces_only);
selection_find_line_boundary_right(term, &pivot_end, spaces_only);
term->selection.pivot.start =
(struct coord){pivot_start.col, term->grid->view + pivot_start.row};
term->selection.pivot.end =
(struct coord){pivot_end.col, term->grid->view + pivot_end.row};
break; break;
}
case SELECTION_BLOCK: case SELECTION_BLOCK:
case SELECTION_NONE: case SELECTION_NONE: