Fix copy ansi to clipboard ignoring newlines

This commit is contained in:
Kovid Goyal 2022-02-13 15:09:14 +05:30
parent 5f8cb22d02
commit a4abe26d32
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 12 additions and 13 deletions

View File

@ -242,7 +242,7 @@ pagerhist_push(HistoryBuf *self, ANSIBuf *as_ansi_buf) {
const GPUCell *prev_cell = NULL; const GPUCell *prev_cell = NULL;
Line l = {.xnum=self->xnum}; Line l = {.xnum=self->xnum};
init_line(self, self->start_of_data, &l); init_line(self, self->start_of_data, &l);
line_as_ansi(&l, as_ansi_buf, &prev_cell, 0, l.xnum); line_as_ansi(&l, as_ansi_buf, &prev_cell, 0, l.xnum, 0);
if (ringbuf_bytes_used(ph->ringbuf) && !l.attrs.continued) pagerhist_write_bytes(ph, (const uint8_t*)"\n", 1); if (ringbuf_bytes_used(ph->ringbuf) && !l.attrs.continued) pagerhist_write_bytes(ph, (const uint8_t*)"\n", 1);
pagerhist_write_bytes(ph, (const uint8_t*)"\x1b[m", 3); pagerhist_write_bytes(ph, (const uint8_t*)"\x1b[m", 3);
if (pagerhist_write_ucs4(ph, as_ansi_buf->buf, as_ansi_buf->len)) pagerhist_write_bytes(ph, (const uint8_t*)"\r", 1); if (pagerhist_write_ucs4(ph, as_ansi_buf->buf, as_ansi_buf->len)) pagerhist_write_bytes(ph, (const uint8_t*)"\r", 1);
@ -324,7 +324,7 @@ as_ansi(HistoryBuf *self, PyObject *callback) {
if (i < self->count - 1) { if (i < self->count - 1) {
l.attrs.continued = attrptr(self, index_of(self, i + 1))->continued; l.attrs.continued = attrptr(self, index_of(self, i + 1))->continued;
} else l.attrs.continued = false; } else l.attrs.continued = false;
line_as_ansi(&l, &output, &prev_cell, 0, l.xnum); line_as_ansi(&l, &output, &prev_cell, 0, l.xnum, 0);
if (!l.attrs.continued) { if (!l.attrs.continued) {
ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false); ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false);
output.buf[output.len++] = 10; // 10 = \n output.buf[output.len++] = 10; // 10 = \n

View File

@ -413,7 +413,7 @@ as_ansi(LineBuf *self, PyObject *callback) {
ANSIBuf output = {0}; ANSIBuf output = {0};
do { do {
init_line(self, (&l), self->line_map[ylimit]); init_line(self, (&l), self->line_map[ylimit]);
line_as_ansi(&l, &output, &prev_cell, 0, l.xnum); line_as_ansi(&l, &output, &prev_cell, 0, l.xnum, 0);
if (output.len) break; if (output.len) break;
ylimit--; ylimit--;
} while(ylimit > 0); } while(ylimit > 0);
@ -421,7 +421,7 @@ as_ansi(LineBuf *self, PyObject *callback) {
for(index_type i = 0; i <= ylimit; i++) { for(index_type i = 0; i <= ylimit; i++) {
l.attrs.continued = self->line_attrs[(i + 1 < self->ynum) ? i+1 : i].continued; l.attrs.continued = self->line_attrs[(i + 1 < self->ynum) ? i+1 : i].continued;
init_line(self, (&l), self->line_map[i]); init_line(self, (&l), self->line_map[i]);
line_as_ansi(&l, &output, &prev_cell, 0, l.xnum); line_as_ansi(&l, &output, &prev_cell, 0, l.xnum, 0);
if (!l.attrs.continued) { if (!l.attrs.continued) {
ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false); ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false);
output.buf[output.len++] = 10; // 10 = \n output.buf[output.len++] = 10; // 10 = \n

View File

@ -302,7 +302,7 @@ write_hyperlink(hyperlink_id_type hid, ANSIBuf *output) {
void void
line_as_ansi(Line *self, ANSIBuf *output, const GPUCell** prev_cell, index_type start_at, index_type stop_before) { line_as_ansi(Line *self, ANSIBuf *output, const GPUCell** prev_cell, index_type start_at, index_type stop_before, char_type prefix_char) {
#define ENSURE_SPACE(extra) ensure_space_for(output, buf, Py_UCS4, output->len + extra, capacity, 2048, false); #define ENSURE_SPACE(extra) ensure_space_for(output, buf, Py_UCS4, output->len + extra, capacity, 2048, false);
#define WRITE_SGR(val) { ENSURE_SPACE(128); write_sgr(val, output); } #define WRITE_SGR(val) { ENSURE_SPACE(128); write_sgr(val, output); }
#define WRITE_CH(val) { ENSURE_SPACE(1); output->buf[output->len++] = val; } #define WRITE_CH(val) { ENSURE_SPACE(1); output->buf[output->len++] = val; }
@ -316,6 +316,7 @@ line_as_ansi(Line *self, ANSIBuf *output, const GPUCell** prev_cell, index_type
GPUCell *cell; GPUCell *cell;
if (*prev_cell == NULL) *prev_cell = &blank_cell; if (*prev_cell == NULL) *prev_cell = &blank_cell;
const CellAttrs mask_for_sgr = {.val=SGR_MASK}; const CellAttrs mask_for_sgr = {.val=SGR_MASK};
if (prefix_char) WRITE_CH(prefix_char);
for (index_type pos=start_at; pos < limit; pos++) { for (index_type pos=start_at; pos < limit; pos++) {
char_type ch = self->cpu_cells[pos].ch; char_type ch = self->cpu_cells[pos].ch;
@ -365,7 +366,7 @@ as_ansi(Line* self, PyObject *a UNUSED) {
#define as_ansi_doc "Return the line's contents with ANSI (SGR) escape codes for formatting" #define as_ansi_doc "Return the line's contents with ANSI (SGR) escape codes for formatting"
const GPUCell *prev_cell = NULL; const GPUCell *prev_cell = NULL;
ANSIBuf output = {0}; ANSIBuf output = {0};
line_as_ansi(self, &output, &prev_cell, 0, self->xnum); line_as_ansi(self, &output, &prev_cell, 0, self->xnum, 0);
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output.buf, output.len); PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output.buf, output.len);
free(output.buf); free(output.buf);
return ans; return ans;
@ -834,7 +835,7 @@ as_text_generic(PyObject *args, void *container, get_line_func get_line, index_t
// get around to writing a nice pager kitten. // get around to writing a nice pager kitten.
// see https://github.com/kovidgoyal/kitty/issues/2381 // see https://github.com/kovidgoyal/kitty/issues/2381
prev_cell = NULL; prev_cell = NULL;
line_as_ansi(line, ansibuf, &prev_cell, 0, line->xnum); line_as_ansi(line, ansibuf, &prev_cell, 0, line->xnum, 0);
t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, ansibuf->buf, ansibuf->len); t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, ansibuf->buf, ansibuf->len);
if (t && ansibuf->len > 0) APPEND(sgr_reset); if (t && ansibuf->len > 0) APPEND(sgr_reset);
} else { } else {

View File

@ -84,7 +84,7 @@ void line_add_combining_char(Line *, uint32_t , unsigned int );
index_type line_url_start_at(Line *self, index_type x); index_type line_url_start_at(Line *self, index_type x);
index_type line_url_end_at(Line *self, index_type x, bool, char_type, bool); index_type line_url_end_at(Line *self, index_type x, bool, char_type, bool);
bool line_startswith_url_chars(Line*); bool line_startswith_url_chars(Line*);
void line_as_ansi(Line *self, ANSIBuf *output, const GPUCell**, index_type start_at, index_type stop_before) __attribute__((nonnull)); void line_as_ansi(Line *self, ANSIBuf *output, const GPUCell**, index_type start_at, index_type stop_before, char_type prefix_char) __attribute__((nonnull));
unsigned int line_length(Line *self); unsigned int line_length(Line *self);
size_t cell_as_unicode(CPUCell *cell, bool include_cc, Py_UCS4 *buf, char_type); size_t cell_as_unicode(CPUCell *cell, bool include_cc, Py_UCS4 *buf, char_type);
size_t cell_as_unicode_for_fallback(CPUCell *cell, Py_UCS4 *buf); size_t cell_as_unicode_for_fallback(CPUCell *cell, Py_UCS4 *buf);

View File

@ -2465,10 +2465,8 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st
Line *line = range_line_(self, y); Line *line = range_line_(self, y);
XRange xr = xrange_for_iteration(&idata, y, line); XRange xr = xrange_for_iteration(&idata, y, line);
output.len = 0; output.len = 0;
if (i > 0 && insert_newlines && !line->attrs.continued) { char_type prefix_char = 0;
ensure_space_for(&output, buf, Py_UCS4, output.len + 1, capacity, 2048, false); if (i > 0 && insert_newlines && !line->attrs.continued) prefix_char = '\n';
output.buf[output.len++] = '\n';
}
index_type x_limit = xr.x_limit; index_type x_limit = xr.x_limit;
if (strip_trailing_whitespace) { if (strip_trailing_whitespace) {
index_type new_limit = limit_without_trailing_whitespace(line, x_limit); index_type new_limit = limit_without_trailing_whitespace(line, x_limit);
@ -2480,7 +2478,7 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st
} }
} }
} }
line_as_ansi(line, &output, &prev_cell, xr.x, x_limit); line_as_ansi(line, &output, &prev_cell, xr.x, x_limit, prefix_char);
PyObject *t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output.buf, output.len); PyObject *t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output.buf, output.len);
if (!t) return NULL; if (!t) return NULL;
PyTuple_SET_ITEM(ans, i, t); PyTuple_SET_ITEM(ans, i, t);