diff --git a/extract.c b/extract.c index dd72ea92..b9fd3331 100644 --- a/extract.c +++ b/extract.c @@ -11,6 +11,7 @@ struct extraction_context { size_t idx; size_t empty_count; size_t newline_count; + bool strip_trailing_empty; bool failed; const struct row *last_row; const struct cell *last_cell; @@ -18,7 +19,7 @@ struct extraction_context { }; struct extraction_context * -extract_begin(enum selection_kind kind) +extract_begin(enum selection_kind kind, bool strip_trailing_empty) { struct extraction_context *ctx = malloc(sizeof(*ctx)); if (unlikely(ctx == NULL)) { @@ -28,6 +29,7 @@ extract_begin(enum selection_kind kind) *ctx = (struct extraction_context){ .selection_kind = kind, + .strip_trailing_empty = strip_trailing_empty, }; return ctx; } @@ -51,8 +53,7 @@ ensure_size(struct extraction_context *ctx, size_t additional_chars) } bool -extract_finish_wide(struct extraction_context *ctx, bool strip_trailing_empty, - wchar_t **text, size_t *len) +extract_finish_wide(struct extraction_context *ctx, wchar_t **text, size_t *len) { if (text == NULL) return false; @@ -64,7 +65,7 @@ extract_finish_wide(struct extraction_context *ctx, bool strip_trailing_empty, if (ctx->failed) goto err; - if (!strip_trailing_empty) { + if (!ctx->strip_trailing_empty) { /* Insert pending newlines, and replace empty cells with spaces */ if (!ensure_size(ctx, ctx->newline_count + ctx->empty_count)) goto err; @@ -106,8 +107,7 @@ err: } bool -extract_finish(struct extraction_context *ctx, bool strip_trailing_empty, - char **text, size_t *len) +extract_finish(struct extraction_context *ctx, char **text, size_t *len) { if (text == NULL) return false; @@ -115,7 +115,7 @@ extract_finish(struct extraction_context *ctx, bool strip_trailing_empty, *len = 0; wchar_t *wtext; - if (!extract_finish_wide(ctx, strip_trailing_empty, &wtext, NULL)) + if (!extract_finish_wide(ctx, &wtext, NULL)) return false; bool ret = false; @@ -167,6 +167,13 @@ extract_one(const struct terminal *term, const struct row *row, /* Don't emit newline just yet - only if there are * non-empty cells following it */ ctx->newline_count++; + + if (!ctx->strip_trailing_empty) { + if (!ensure_size(ctx, ctx->empty_count)) + goto err; + for (size_t i = 0; i < ctx->empty_count; i++) + ctx->buf[ctx->idx++] = L' '; + } ctx->empty_count = 0; } } else { @@ -175,6 +182,13 @@ extract_one(const struct terminal *term, const struct row *row, goto err; ctx->buf[ctx->idx++] = L'\n'; + + if (!ctx->strip_trailing_empty) { + if (!ensure_size(ctx, ctx->empty_count)) + goto err; + for (size_t i = 0; i < ctx->empty_count; i++) + ctx->buf[ctx->idx++] = L' '; + } ctx->empty_count = 0; } } diff --git a/extract.h b/extract.h index 879461cf..dc802bc5 100644 --- a/extract.h +++ b/extract.h @@ -8,15 +8,14 @@ struct extraction_context; -struct extraction_context *extract_begin(enum selection_kind kind); +struct extraction_context *extract_begin( + enum selection_kind kind, bool strip_trailing_empty); bool extract_one( const struct terminal *term, const struct row *row, const struct cell *cell, int col, void *context); bool extract_finish( - struct extraction_context *context, bool strip_trailing_empty, - char **text, size_t *len); + struct extraction_context *context, char **text, size_t *len); bool extract_finish_wide( - struct extraction_context *context, bool strip_trailing_empty, - wchar_t **text, size_t *len); + struct extraction_context *context, wchar_t **text, size_t *len); diff --git a/pgo/pgo.c b/pgo/pgo.c index c1620b04..34af7115 100644 --- a/pgo/pgo.c +++ b/pgo/pgo.c @@ -106,7 +106,7 @@ render_worker_thread(void *_ctx) } struct extraction_context * -extract_begin(enum selection_kind kind) +extract_begin(enum selection_kind kind, bool strip_trailing_empty) { return NULL; } diff --git a/search.c b/search.c index cce205d4..e7d03fe1 100644 --- a/search.c +++ b/search.c @@ -473,7 +473,7 @@ search_match_to_end_of_word(struct terminal *term, bool spaces_only) struct coord pos = old_end; row = term->grid->rows[pos.row]; - struct extraction_context *ctx = extract_begin(SELECTION_NONE); + struct extraction_context *ctx = extract_begin(SELECTION_NONE, false); if (ctx == NULL) return; @@ -487,7 +487,7 @@ search_match_to_end_of_word(struct terminal *term, bool spaces_only) wchar_t *new_text; size_t new_len; - if (!extract_finish_wide(ctx, false, &new_text, &new_len)) + if (!extract_finish_wide(ctx, &new_text, &new_len)) return; if (!search_ensure_size(term, term->search.len + new_len)) diff --git a/selection.c b/selection.c index 7316dfc3..f684c2fa 100644 --- a/selection.c +++ b/selection.c @@ -215,7 +215,7 @@ selection_to_text(const struct terminal *term) if (term->selection.end.row == -1) return NULL; - struct extraction_context *ctx = extract_begin(term->selection.kind); + struct extraction_context *ctx = extract_begin(term->selection.kind, true); if (ctx == NULL) return NULL; @@ -224,7 +224,7 @@ selection_to_text(const struct terminal *term) &extract_one_const_wrapper, ctx); char *text; - return extract_finish(ctx, true, &text, NULL) ? text : NULL; + return extract_finish(ctx, &text, NULL) ? text : NULL; } void diff --git a/terminal.c b/terminal.c index c2bcf86f..8264274a 100644 --- a/terminal.c +++ b/terminal.c @@ -2900,7 +2900,7 @@ static bool rows_to_text(const struct terminal *term, int start, int end, char **text, size_t *len) { - struct extraction_context *ctx = extract_begin(SELECTION_NONE); + struct extraction_context *ctx = extract_begin(SELECTION_NONE, true); if (ctx == NULL) return false; @@ -2917,7 +2917,7 @@ rows_to_text(const struct terminal *term, int start, int end, } out: - return extract_finish(ctx, true, text, len); + return extract_finish(ctx, text, len); } bool