mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
selection: extract text: also copy combining characters
This commit is contained in:
parent
76567e9ef0
commit
623329cf23
1 changed files with 23 additions and 14 deletions
37
selection.c
37
selection.c
|
|
@ -46,7 +46,7 @@ selection_on_row_in_view(const struct terminal *term, int row_no)
|
|||
static void
|
||||
foreach_selected_normal(
|
||||
struct terminal *term, struct coord _start, struct coord _end,
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, void *data),
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, int col, void *data),
|
||||
void *data)
|
||||
{
|
||||
const struct coord *start = &_start;
|
||||
|
|
@ -80,7 +80,7 @@ foreach_selected_normal(
|
|||
c <= (r == end_row ? end_col : term->cols - 1);
|
||||
c++)
|
||||
{
|
||||
cb(term, row, &row->cells[c], data);
|
||||
cb(term, row, &row->cells[c], c, data);
|
||||
}
|
||||
|
||||
start_col = 0;
|
||||
|
|
@ -90,7 +90,7 @@ foreach_selected_normal(
|
|||
static void
|
||||
foreach_selected_block(
|
||||
struct terminal *term, struct coord _start, struct coord _end,
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, void *data),
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, int col, void *data),
|
||||
void *data)
|
||||
{
|
||||
const struct coord *start = &_start;
|
||||
|
|
@ -112,14 +112,14 @@ foreach_selected_block(
|
|||
assert(row != NULL);
|
||||
|
||||
for (int c = top_left.col; c <= bottom_right.col; c++)
|
||||
cb(term, row, &row->cells[c], data);
|
||||
cb(term, row, &row->cells[c], c, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
foreach_selected(
|
||||
struct terminal *term, struct coord start, struct coord end,
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, void *data),
|
||||
void (*cb)(struct terminal *term, struct row *row, struct cell *cell, int col, void *data),
|
||||
void *data)
|
||||
{
|
||||
switch (term->selection.kind) {
|
||||
|
|
@ -142,6 +142,8 @@ min_bufsize_for_extraction(const struct terminal *term)
|
|||
{
|
||||
const struct coord *start = &term->selection.start;
|
||||
const struct coord *end = &term->selection.end;
|
||||
const size_t chars_per_cell
|
||||
= 1 + ALEN(term->grid->cur_row->comb_chars[0].chars);
|
||||
|
||||
switch (term->selection.kind) {
|
||||
case SELECTION_NONE:
|
||||
|
|
@ -160,7 +162,7 @@ min_bufsize_for_extraction(const struct terminal *term)
|
|||
}
|
||||
|
||||
if (start->row == end->row)
|
||||
return end->col - start->col + 1;
|
||||
return (end->col - start->col + 1) * chars_per_cell;
|
||||
else {
|
||||
size_t cells = 0;
|
||||
|
||||
|
|
@ -169,7 +171,7 @@ min_bufsize_for_extraction(const struct terminal *term)
|
|||
cells += term->cols - start->col + 1;
|
||||
cells += (term->cols + 1) * (end->row - start->row - 1);
|
||||
cells += end->col + 1 + 1;
|
||||
return cells;
|
||||
return cells * chars_per_cell;
|
||||
}
|
||||
|
||||
case SELECTION_BLOCK: {
|
||||
|
|
@ -186,7 +188,7 @@ min_bufsize_for_extraction(const struct terminal *term)
|
|||
/* Add one extra column on each row, for \n */
|
||||
int cols = bottom_right.col - top_left.col + 1 + 1;
|
||||
int rows = bottom_right.row - top_left.row + 1;
|
||||
return rows * cols;
|
||||
return rows * cols * chars_per_cell;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,13 +201,13 @@ struct extract {
|
|||
size_t size;
|
||||
size_t idx;
|
||||
size_t empty_count;
|
||||
struct row *last_row;
|
||||
struct cell *last_cell;
|
||||
const struct row *last_row;
|
||||
const struct cell *last_cell;
|
||||
};
|
||||
|
||||
static void
|
||||
extract_one(struct terminal *term, struct row *row, struct cell *cell,
|
||||
void *data)
|
||||
int col, void *data)
|
||||
{
|
||||
struct extract *ctx = data;
|
||||
|
||||
|
|
@ -235,6 +237,13 @@ extract_one(struct terminal *term, struct row *row, struct cell *cell,
|
|||
assert(ctx->idx + 1 <= ctx->size);
|
||||
ctx->buf[ctx->idx++] = cell->wc;
|
||||
|
||||
const struct combining_chars *comb_chars = &row->comb_chars[col];
|
||||
|
||||
assert(cell->wc != 0);
|
||||
assert(ctx->idx + comb_chars->count <= ctx->size);
|
||||
for (size_t i = 0; i < comb_chars->count; i++)
|
||||
ctx->buf[ctx->idx++] = comb_chars->chars[i];
|
||||
|
||||
ctx->last_row = row;
|
||||
ctx->last_cell = cell;
|
||||
}
|
||||
|
|
@ -299,7 +308,7 @@ selection_start(struct terminal *term, int col, int row,
|
|||
|
||||
static void
|
||||
unmark_selected(struct terminal *term, struct row *row, struct cell *cell,
|
||||
void *data)
|
||||
int col, void *data)
|
||||
{
|
||||
if (cell->attrs.selected == 0 || (cell->attrs.selected & 2)) {
|
||||
/* Ignore if already deselected, or if premarked for updated selection */
|
||||
|
|
@ -313,7 +322,7 @@ unmark_selected(struct terminal *term, struct row *row, struct cell *cell,
|
|||
|
||||
static void
|
||||
premark_selected(struct terminal *term, struct row *row, struct cell *cell,
|
||||
void *data)
|
||||
int col, void *data)
|
||||
{
|
||||
/* Tell unmark to leave this be */
|
||||
cell->attrs.selected |= 2;
|
||||
|
|
@ -321,7 +330,7 @@ premark_selected(struct terminal *term, struct row *row, struct cell *cell,
|
|||
|
||||
static void
|
||||
mark_selected(struct terminal *term, struct row *row, struct cell *cell,
|
||||
void *data)
|
||||
int col, void *data)
|
||||
{
|
||||
if (cell->attrs.selected & 1) {
|
||||
cell->attrs.selected = 1; /* Clear the pre-mark bit */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue