diff --git a/kitty/data-types.h b/kitty/data-types.h index c90bc534d..5938e3513 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -330,6 +330,7 @@ void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *); void line_right_shift(Line *, unsigned int , unsigned int ); void line_add_combining_char(Line *, uint32_t , unsigned int ); +index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen); void linebuf_init_line(LineBuf *, index_type); void linebuf_clear(LineBuf *, char_type ch); diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 635a60293..0d2f3033f 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -343,6 +343,25 @@ delete_lines(LineBuf *self, PyObject *args) { Py_RETURN_NONE; } +static PyObject* +as_ansi(LineBuf *self, PyObject *callback) { +#define as_ansi_doc "as_ansi(callback) -> The contents of this buffer ans ANSI escaped text. callback is called with each successive line." + static Py_UCS4 t[5120]; + Line l = {.xnum=self->xnum}; + for(index_type i = 0; i < self->ynum; i++) { + l.continued = (i < self->ynum - 1) ? self->continued_map[i+1] : self->continued_map[i]; + INIT_LINE(self, (&l), self->line_map[i]); + index_type num = line_as_ansi(&l, t, 5120); + 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(); + PyObject *ret = PyObject_CallFunctionObjArgs(callback, ans, NULL); + Py_CLEAR(ans); + if (ret == NULL) return NULL; + Py_CLEAR(ret); + } + Py_RETURN_NONE; +} // Boilerplate {{{ static PyObject* @@ -361,6 +380,7 @@ static PyMethodDef methods[] = { METHOD(create_line_copy, METH_O) METHOD(rewrap, METH_VARARGS) METHOD(clear, METH_NOARGS) + METHOD(as_ansi, METH_O) METHOD(set_attribute, METH_VARARGS) METHOD(set_continued, METH_VARARGS) METHOD(index, METH_VARARGS) diff --git a/kitty_tests/datatypes.py b/kitty_tests/datatypes.py index 30ebd5526..2ccdd7fcb 100644 --- a/kitty_tests/datatypes.py +++ b/kitty_tests/datatypes.py @@ -326,6 +326,10 @@ class TestDataTypes(BaseTest): lb = filled_line_buf() l = lb.line(0) self.ae(l.as_ansi(), '\x1b[0m00000') + a = [] + lb.as_ansi(a.append) + self.ae(a, ['\x1b[0m' + str(lb.line(i)) + '\n' for i in range(lb.ynum)]) + l = lb.line(0) c = Cursor() c.bold = c.italic = c.reverse = c.strikethrough = True c.fg = (4 << 8) | 1