mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
selection: break out pivot point adjustment for character-wise selections
This commit is contained in:
parent
3a9172342f
commit
f236dc7701
1 changed files with 113 additions and 82 deletions
195
selection.c
195
selection.c
|
|
@ -549,6 +549,82 @@ selection_modify(struct terminal *term, struct coord start, struct coord end)
|
||||||
render_refresh(term);
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_pivot_point_for_block_and_char_wise(struct terminal *term,
|
||||||
|
struct coord start,
|
||||||
|
enum selection_direction new_direction)
|
||||||
|
{
|
||||||
|
struct coord *pivot_start = &term->selection.pivot.start;
|
||||||
|
struct coord *pivot_end = &term->selection.pivot.end;
|
||||||
|
|
||||||
|
*pivot_start = start;
|
||||||
|
|
||||||
|
/* First, make sure ‘start’ isn’t in the middle of a
|
||||||
|
* multi-column character */
|
||||||
|
while (true) {
|
||||||
|
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
||||||
|
const struct cell *cell = &row->cells[pivot_start->col];
|
||||||
|
|
||||||
|
if (cell->wc != CELL_MULT_COL_SPACER)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Multi-column chars don’t cross rows */
|
||||||
|
assert(pivot_start->col > 0);
|
||||||
|
if (pivot_start->col == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pivot_start->col--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup pivot end to be one character *before* start
|
||||||
|
* Which one we move, the end or start point, depends
|
||||||
|
* on the initial selection direction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*pivot_end = *pivot_start;
|
||||||
|
|
||||||
|
if (new_direction == SELECTION_RIGHT) {
|
||||||
|
bool keep_going = true;
|
||||||
|
while (keep_going) {
|
||||||
|
const struct row *row = term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)];
|
||||||
|
const wchar_t wc = row->cells[pivot_end->col].wc;
|
||||||
|
|
||||||
|
keep_going = wc == CELL_MULT_COL_SPACER;
|
||||||
|
|
||||||
|
if (pivot_end->col == 0) {
|
||||||
|
if (pivot_end->row - term->grid->view <= 0)
|
||||||
|
break;
|
||||||
|
pivot_end->col = term->cols - 1;
|
||||||
|
pivot_end->row--;
|
||||||
|
} else
|
||||||
|
pivot_end->col--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool keep_going = true;
|
||||||
|
while (keep_going) {
|
||||||
|
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
||||||
|
const wchar_t wc = pivot_start->col < term->cols - 1
|
||||||
|
? row->cells[pivot_start->col + 1].wc : 0;
|
||||||
|
|
||||||
|
keep_going = wc == CELL_MULT_COL_SPACER;
|
||||||
|
|
||||||
|
if (pivot_start->col >= term->cols - 1) {
|
||||||
|
if (pivot_start->row - term->grid->view >= term->rows - 1)
|
||||||
|
break;
|
||||||
|
pivot_start->col = 0;
|
||||||
|
pivot_start->row++;
|
||||||
|
} else
|
||||||
|
pivot_start->col++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)]->
|
||||||
|
cells[pivot_start->col].wc != CELL_MULT_COL_SPACER);
|
||||||
|
assert(term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)]->
|
||||||
|
cells[pivot_end->col].wc != CELL_MULT_COL_SPACER);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
selection_update(struct terminal *term, int col, int row)
|
selection_update(struct terminal *term, int col, int row)
|
||||||
{
|
{
|
||||||
|
|
@ -575,93 +651,48 @@ selection_update(struct terminal *term, int col, int row)
|
||||||
struct coord *pivot_start = &term->selection.pivot.start;
|
struct coord *pivot_start = &term->selection.pivot.start;
|
||||||
struct coord *pivot_end = &term->selection.pivot.end;
|
struct coord *pivot_end = &term->selection.pivot.end;
|
||||||
|
|
||||||
if (new_end.row < pivot_start->row ||
|
if (term->selection.kind == SELECTION_BLOCK) {
|
||||||
(new_end.row == pivot_start->row && new_end.col < pivot_start->col))
|
if (new_end.col > pivot_start->col)
|
||||||
{
|
new_direction = SELECTION_RIGHT;
|
||||||
/* New end point is before the start point */
|
else
|
||||||
new_direction = SELECTION_LEFT;
|
new_direction = SELECTION_LEFT;
|
||||||
|
|
||||||
|
if (term->selection.direction == SELECTION_UNDIR)
|
||||||
|
set_pivot_point_for_block_and_char_wise(term, *pivot_start, new_direction);
|
||||||
|
|
||||||
|
if (new_direction == SELECTION_LEFT)
|
||||||
|
new_start = *pivot_end;
|
||||||
|
else
|
||||||
|
new_start = *pivot_start;
|
||||||
|
term->selection.direction = new_direction;
|
||||||
} else {
|
} else {
|
||||||
/* The new end point is after the start point */
|
if (new_end.row < pivot_start->row ||
|
||||||
new_direction = SELECTION_RIGHT;
|
(new_end.row == pivot_start->row &&
|
||||||
}
|
new_end.col < pivot_start->col))
|
||||||
|
|
||||||
if (term->selection.direction != new_direction) {
|
|
||||||
if (term->selection.direction == SELECTION_UNDIR &&
|
|
||||||
pivot_end->row < 0)
|
|
||||||
{
|
{
|
||||||
/* First, make sure ‘start’ isn’t in the middle of a
|
/* New end point is before the start point */
|
||||||
* multi-column character */
|
new_direction = SELECTION_LEFT;
|
||||||
while (true) {
|
} else {
|
||||||
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
/* The new end point is after the start point */
|
||||||
const struct cell *cell = &row->cells[pivot_start->col];
|
new_direction = SELECTION_RIGHT;
|
||||||
|
|
||||||
if (cell->wc != CELL_MULT_COL_SPACER)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Multi-column chars don’t cross rows */
|
|
||||||
assert(pivot_start->col > 0);
|
|
||||||
if (pivot_start->col == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
pivot_start->col--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup pivot end to be one character *before* start
|
|
||||||
* Which one we move, the end or start point, depends
|
|
||||||
* on the initial selection direction.
|
|
||||||
*/
|
|
||||||
|
|
||||||
*pivot_end = *pivot_start;
|
|
||||||
|
|
||||||
if (new_direction == SELECTION_RIGHT) {
|
|
||||||
bool keep_going = true;
|
|
||||||
while (keep_going) {
|
|
||||||
const struct row *row = term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)];
|
|
||||||
const wchar_t wc = row->cells[pivot_end->col].wc;
|
|
||||||
|
|
||||||
keep_going = wc == CELL_MULT_COL_SPACER;
|
|
||||||
|
|
||||||
if (pivot_end->col == 0) {
|
|
||||||
if (pivot_end->row - term->grid->view <= 0)
|
|
||||||
break;
|
|
||||||
pivot_end->col = term->cols - 1;
|
|
||||||
pivot_end->row--;
|
|
||||||
} else
|
|
||||||
pivot_end->col--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool keep_going = true;
|
|
||||||
while (keep_going) {
|
|
||||||
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
|
||||||
const wchar_t wc = pivot_start->col < term->cols - 1
|
|
||||||
? row->cells[pivot_start->col + 1].wc : 0;
|
|
||||||
|
|
||||||
keep_going = wc == CELL_MULT_COL_SPACER;
|
|
||||||
|
|
||||||
if (pivot_start->col >= term->cols - 1) {
|
|
||||||
if (pivot_start->row - term->grid->view >= term->rows - 1)
|
|
||||||
break;
|
|
||||||
pivot_start->col = 0;
|
|
||||||
pivot_start->row++;
|
|
||||||
} else
|
|
||||||
pivot_start->col++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)]->
|
|
||||||
cells[pivot_start->col].wc != CELL_MULT_COL_SPACER);
|
|
||||||
assert(term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)]->
|
|
||||||
cells[pivot_end->col].wc != CELL_MULT_COL_SPACER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_direction == SELECTION_LEFT) {
|
if (term->selection.direction != new_direction) {
|
||||||
assert(pivot_end->row >= 0);
|
if (term->selection.direction == SELECTION_UNDIR &&
|
||||||
new_start = *pivot_end;
|
pivot_end->row < 0)
|
||||||
} else
|
{
|
||||||
new_start = *pivot_start;
|
set_pivot_point_for_block_and_char_wise(
|
||||||
|
term, *pivot_start, new_direction);
|
||||||
|
}
|
||||||
|
|
||||||
term->selection.direction = new_direction;
|
if (new_direction == SELECTION_LEFT) {
|
||||||
|
assert(pivot_end->row >= 0);
|
||||||
|
new_start = *pivot_end;
|
||||||
|
} else
|
||||||
|
new_start = *pivot_start;
|
||||||
|
|
||||||
|
term->selection.direction = new_direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue