LineBuf.as_ansi()

This commit is contained in:
Kovid Goyal
2016-12-09 12:44:39 +05:30
parent e3e3e86598
commit 5a6ecbbf43
3 changed files with 25 additions and 0 deletions

View File

@@ -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);

View File

@@ -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)

View File

@@ -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