selection: handle multi-column characters when reversing selection direction

This commit is contained in:
Daniel Eklöf 2020-08-13 18:32:56 +02:00
parent a4b18ba832
commit 3816a3b460
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -320,6 +320,11 @@ selection_update(struct terminal *term, int col, int row)
struct coord new_start = term->selection.start; struct coord new_start = term->selection.start;
struct coord new_end = {col, term->grid->view + row}; struct coord new_end = {col, term->grid->view + row};
size_t start_row_idx = new_start.row & (term->grid->num_rows - 1);
size_t end_row_idx = new_end.row & (term->grid->num_rows - 1);
const struct row *row_start = term->grid->rows[start_row_idx];
const struct row *row_end = term->grid->rows[end_row_idx];
/* Adjust start point if the selection has changed 'direction' */ /* Adjust start point if the selection has changed 'direction' */
if (!(new_end.row == new_start.row && new_end.col == new_start.col)) { if (!(new_end.row == new_start.row && new_end.col == new_start.col)) {
enum selection_direction new_direction; enum selection_direction new_direction;
@ -327,26 +332,41 @@ selection_update(struct terminal *term, int col, int row)
if (new_end.row > new_start.row || if (new_end.row > new_start.row ||
(new_end.row == new_start.row && new_end.col > new_start.col)) (new_end.row == new_start.row && new_end.col > new_start.col))
{ {
/* New end point is before the start point */ /* New end point is after the start point */
new_direction = SELECTION_RIGHT; new_direction = SELECTION_RIGHT;
} else { } else {
/* The new end point is after the start point */ /* The new end point is before the start point */
new_direction = SELECTION_LEFT; new_direction = SELECTION_LEFT;
} }
if (term->selection.direction != new_direction) { if (term->selection.direction != new_direction) {
if (term->selection.direction != SELECTION_UNDIR) { if (term->selection.direction != SELECTION_UNDIR) {
if (new_direction == SELECTION_LEFT) { if (new_direction == SELECTION_LEFT) {
new_start.col--; bool keep_going = true;
if (new_start.col < 0) { while (keep_going) {
new_start.col = term->cols - 1; const wchar_t wc = row_start->cells[new_start.col].wc;
new_start.row--; keep_going = wc == CELL_MULT_COL_SPACER;
new_start.col--;
if (new_start.col < 0) {
new_start.col = term->cols - 1;
new_start.row--;
}
} }
} else { } else {
new_start.col++; bool keep_going = true;
if (new_start.col >= term->cols) { while (keep_going) {
new_start.col = 0; const wchar_t wc = new_start.col < term->cols - 1
new_start.row++; ? row_start->cells[new_start.col + 1].wc
: 0;
keep_going = wc == CELL_MULT_COL_SPACER;
new_start.col++;
if (new_start.col >= term->cols) {
new_start.col = 0;
new_start.row++;
}
} }
} }
} }
@ -355,12 +375,6 @@ selection_update(struct terminal *term, int col, int row)
} }
} }
size_t start_row_idx = new_start.row & (term->grid->num_rows - 1);
size_t end_row_idx = new_end.row & (term->grid->num_rows - 1);
const struct row *row_start = term->grid->rows[start_row_idx];
const struct row *row_end = term->grid->rows[end_row_idx];
/* Handle double-width characters */ /* Handle double-width characters */
if (new_start.row < new_end.row || if (new_start.row < new_end.row ||
(new_start.row == new_end.row && new_start.col <= new_end.col)) (new_start.row == new_end.row && new_start.col <= new_end.col))