Merge branch 'fix_issue_1924' of https://github.com/s1341/kitty
Fixes #1924
This commit is contained in:
commit
c905978874
@ -39,6 +39,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- When the OS returns a fallback font that does not actually contain glyphs
|
||||
for the text, do not exhaust the list of fallback fonts (:iss:`1918`)
|
||||
|
||||
- Fix formatting attributes not reset across line boundaries when passing
|
||||
buffer as ANSI (:iss:`1924`)
|
||||
|
||||
|
||||
0.14.3 [2019-07-29]
|
||||
---------------------
|
||||
|
||||
@ -288,7 +288,7 @@ void cursor_copy_to(Cursor *src, Cursor *dest);
|
||||
void cursor_reset_display_attrs(Cursor*);
|
||||
void cursor_from_sgr(Cursor *self, unsigned int *params, unsigned int count);
|
||||
void apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count);
|
||||
const char* cell_as_sgr(GPUCell *, GPUCell *);
|
||||
const char* cell_as_sgr(const GPUCell *, const GPUCell *);
|
||||
const char* cursor_as_sgr(const Cursor *);
|
||||
|
||||
double monotonic(void);
|
||||
|
||||
@ -179,6 +179,7 @@ pagerhist_push(HistoryBuf *self) {
|
||||
PagerHistoryBuf *ph = self->pagerhist;
|
||||
if (!ph) return;
|
||||
bool truncated;
|
||||
const GPUCell *prev_cell = NULL;
|
||||
Line l = {.xnum=self->xnum};
|
||||
init_line(self, self->start_of_data, &l);
|
||||
#define EXPAND_IF_FULL(sz) { \
|
||||
@ -193,7 +194,7 @@ pagerhist_push(HistoryBuf *self) {
|
||||
ph->buffer[ph->end++] = '\n';
|
||||
}
|
||||
while(sz < ph->maxsz - 2) {
|
||||
size_t num = line_as_ansi(&l, ph->buffer + ph->end, ph->bufsize - ph->end - 2, &truncated);
|
||||
size_t num = line_as_ansi(&l, ph->buffer + ph->end, ph->bufsize - ph->end - 2, &truncated, &prev_cell);
|
||||
if (!truncated) {
|
||||
ph->end += num;
|
||||
ph->buffer[ph->end++] = '\r';
|
||||
@ -270,12 +271,13 @@ as_ansi(HistoryBuf *self, PyObject *callback) {
|
||||
static Py_UCS4 t[5120];
|
||||
Line l = {.xnum=self->xnum};
|
||||
bool truncated;
|
||||
const GPUCell *prev_cell = NULL;
|
||||
for(unsigned int i = 0; i < self->count; i++) {
|
||||
init_line(self, i, &l);
|
||||
if (i < self->count - 1) {
|
||||
l.continued = *attrptr(self, index_of(self, i + 1)) & CONTINUED_MASK;
|
||||
} else l.continued = false;
|
||||
index_type num = line_as_ansi(&l, t, 5120, &truncated);
|
||||
index_type num = line_as_ansi(&l, t, 5120, &truncated, &prev_cell);
|
||||
if (!(l.continued) && num < 5119) t[num++] = 10; // 10 = \n
|
||||
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, t, num);
|
||||
if (ans == NULL) return PyErr_NoMemory();
|
||||
|
||||
@ -398,16 +398,17 @@ as_ansi(LineBuf *self, PyObject *callback) {
|
||||
// remove trailing empty lines
|
||||
index_type ylimit = self->ynum - 1;
|
||||
bool truncated;
|
||||
const GPUCell *prev_cell = NULL;
|
||||
do {
|
||||
init_line(self, (&l), self->line_map[ylimit]);
|
||||
if (line_as_ansi(&l, t, 5120, &truncated) != 0) break;
|
||||
if (line_as_ansi(&l, t, 5120, &truncated, &prev_cell) != 0) break;
|
||||
ylimit--;
|
||||
} while(ylimit > 0);
|
||||
|
||||
for(index_type i = 0; i <= ylimit; i++) {
|
||||
l.continued = ((i < self->ynum - 1) ? self->line_attrs[i+1] : self->line_attrs[i]) & CONTINUED_MASK;
|
||||
init_line(self, (&l), self->line_map[i]);
|
||||
index_type num = line_as_ansi(&l, t, 5120, &truncated);
|
||||
index_type num = line_as_ansi(&l, t, 5120, &truncated, &prev_cell);
|
||||
if (!(l.continued) && num < 5119) t[num++] = 10; // 10 = \n
|
||||
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, t, num);
|
||||
if (ans == NULL) return PyErr_NoMemory();
|
||||
|
||||
20
kitty/line.c
20
kitty/line.c
@ -258,7 +258,7 @@ write_sgr(const char *val, Py_UCS4 *buf, index_type buflen, index_type *i) {
|
||||
}
|
||||
|
||||
index_type
|
||||
line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool *truncated) {
|
||||
line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool *truncated, const GPUCell** prev_cell) {
|
||||
#define WRITE_SGR(val) { if (!write_sgr(val, buf, buflen, &i)) { *truncated = true; return i; } }
|
||||
#define WRITE_CH(val) if (i > buflen - 1) { *truncated = true; return i; } buf[i++] = val;
|
||||
|
||||
@ -267,8 +267,9 @@ line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool *truncated) {
|
||||
if (limit == 0) return 0;
|
||||
char_type previous_width = 0;
|
||||
|
||||
GPUCell blank_cell = { 0 };
|
||||
GPUCell *cell, *prev_cell = &blank_cell;
|
||||
static const GPUCell blank_cell = { 0 };
|
||||
GPUCell *cell;
|
||||
if (*prev_cell == NULL) *prev_cell = &blank_cell;
|
||||
|
||||
for (index_type pos=0; pos < limit; pos++) {
|
||||
char_type ch = self->cpu_cells[pos].ch;
|
||||
@ -279,13 +280,13 @@ line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool *truncated) {
|
||||
|
||||
cell = &self->gpu_cells[pos];
|
||||
|
||||
#define CMP_ATTRS (cell->attrs & ATTRS_MASK_WITHOUT_WIDTH) != (prev_cell->attrs & ATTRS_MASK_WITHOUT_WIDTH)
|
||||
#define CMP(x) cell->x != prev_cell->x
|
||||
#define CMP_ATTRS (cell->attrs & ATTRS_MASK_WITHOUT_WIDTH) != ((*prev_cell)->attrs & ATTRS_MASK_WITHOUT_WIDTH)
|
||||
#define CMP(x) cell->x != (*prev_cell)->x
|
||||
if (CMP_ATTRS || CMP(fg) || CMP(bg) || CMP(decoration_fg)) {
|
||||
const char *sgr = cell_as_sgr(cell, prev_cell);
|
||||
const char *sgr = cell_as_sgr(cell, *prev_cell);
|
||||
if (*sgr) WRITE_SGR(sgr);
|
||||
}
|
||||
prev_cell = cell;
|
||||
*prev_cell = cell;
|
||||
WRITE_CH(ch);
|
||||
for(unsigned c = 0; c < arraysz(self->cpu_cells[pos].cc_idx) && self->cpu_cells[pos].cc_idx[c]; c++) {
|
||||
WRITE_CH(codepoint_for_mark(self->cpu_cells[pos].cc_idx[c]));
|
||||
@ -304,7 +305,8 @@ as_ansi(Line* self, PyObject *a UNUSED) {
|
||||
#define as_ansi_doc "Return the line's contents with ANSI (SGR) escape codes for formatting"
|
||||
static Py_UCS4 t[5120] = {0};
|
||||
bool truncated;
|
||||
index_type num = line_as_ansi(self, t, 5120, &truncated);
|
||||
const GPUCell *prev_cell = NULL;
|
||||
index_type num = line_as_ansi(self, t, 5120, &truncated, &prev_cell);
|
||||
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, t, num);
|
||||
return ans;
|
||||
}
|
||||
@ -589,7 +591,7 @@ decoration_as_sgr(uint8_t decoration) {
|
||||
|
||||
|
||||
const char*
|
||||
cell_as_sgr(GPUCell *cell, GPUCell *prev) {
|
||||
cell_as_sgr(const GPUCell *cell, const GPUCell *prev) {
|
||||
static char buf[128];
|
||||
#define SZ sizeof(buf) - (p - buf) - 2
|
||||
#define P(s) { size_t len = strlen(s); if (SZ > len) { memcpy(p, s, len); p += len; } }
|
||||
|
||||
@ -61,7 +61,7 @@ void line_right_shift(Line *, unsigned int , unsigned int );
|
||||
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_end_at(Line *self, index_type x, bool, char_type);
|
||||
index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool*);
|
||||
index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool*, const GPUCell**) __attribute__((nonnull));
|
||||
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_for_fallback(CPUCell *cell, Py_UCS4 *buf);
|
||||
@ -100,6 +100,7 @@ void historybuf_clear(HistoryBuf *self);
|
||||
Py_UCS4 *buf = NULL; \
|
||||
PyObject *nl = PyUnicode_FromString("\n"); \
|
||||
PyObject *cr = PyUnicode_FromString("\r"); \
|
||||
const GPUCell *prev_cell = NULL; \
|
||||
if (nl == NULL || cr == NULL) goto end; \
|
||||
if (as_ansi) { \
|
||||
buf = malloc(sizeof(Py_UCS4) * columns * 100); \
|
||||
@ -114,7 +115,7 @@ void historybuf_clear(HistoryBuf *self);
|
||||
} \
|
||||
if (as_ansi) { \
|
||||
bool truncated; \
|
||||
index_type num = line_as_ansi(line, buf, columns * 100 - 2, &truncated); \
|
||||
index_type num = line_as_ansi(line, buf, columns * 100 - 2, &truncated, &prev_cell); \
|
||||
t = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buf, num); \
|
||||
} else { \
|
||||
t = line_as_unicode(line); \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user