Implement add combining char

This commit is contained in:
Kovid Goyal 2016-11-01 19:04:38 +05:30
parent c069d40ffe
commit 85076d3012
3 changed files with 33 additions and 4 deletions

View File

@ -36,6 +36,8 @@ typedef unsigned int index_type;
#define COL_MASK 0xFFFFFFFF
#define COL_SHIFT 32
#define HAS_BG_MASK (0xFF << COL_SHIFT)
#define CC_MASK 0xFFFF
#define CC_SHIFT 16
typedef struct {
PyObject_HEAD

View File

@ -35,7 +35,7 @@ text_at(Line* self, PyObject *x) {
if (ans == NULL) return PyErr_NoMemory();
PyUnicode_WriteChar(ans, 0, ch);
} else {
Py_UCS4 cc1 = cc & 0xFFFF, cc2 = cc >> 16;
Py_UCS4 cc1 = cc & CC_MASK, cc2 = cc >> 16;
Py_UCS4 maxc = (ch > cc1) ? MAX(ch, cc2) : MAX(cc1, cc2);
ans = PyUnicode_New(cc2 ? 3 : 2, maxc);
if (ans == NULL) return PyErr_NoMemory();
@ -59,7 +59,7 @@ as_unicode(Line* self) {
char_type ch = self->chars[i] & CHAR_MASK;
char_type cc = self->combining_chars[i];
buf[n++] = ch & CHAR_MASK;
Py_UCS4 cc1 = cc & 0xFFFF, cc2;
Py_UCS4 cc1 = cc & CC_MASK, cc2;
if (cc1) {
buf[n++] = cc1;
cc2 = cc >> 16;
@ -71,10 +71,28 @@ as_unicode(Line* self) {
return ans;
}
static PyObject*
add_combining_char(Line* self, PyObject *args) {
int new_char;
unsigned int x;
if (!PyArg_ParseTuple(args, "IC", &x, &new_char)) return NULL;
if (x >= self->xnum) {
PyErr_SetString(PyExc_ValueError, "Column index out of bounds");
return NULL;
}
combining_type c = self->combining_chars[x];
if (c & CC_MASK) self->combining_chars[x] = (c & CC_MASK) | ( (new_char & CC_MASK) << CC_SHIFT );
else self->combining_chars[x] = new_char & CC_MASK;
Py_RETURN_NONE;
}
// Boilerplate {{{
static PyMethodDef methods[] = {
{"text_at", (PyCFunction)text_at, METH_O,
"Return the text in the specified cell"
"text_at(x) -> Return the text in the specified cell"
},
{"add_combining_char", (PyCFunction)add_combining_char, METH_VARARGS,
"add_combining_char(x, ch) -> Add the specified character as a combining char to the specified cell."
},
{NULL} /* Sentinel */
};

View File

@ -13,7 +13,7 @@ from kitty.fast_data_types import LineBuf
class TestDataTypes(BaseTest):
def test_line_buf(self):
def test_line(self):
lb = LineBuf(2, 3)
for y in range(2):
line = lb.line(y)
@ -24,6 +24,15 @@ class TestDataTypes(BaseTest):
lb.line(5)
with self.assertRaises(ValueError):
lb.line(0).text_at(5)
l = lb.line(0)
l.add_combining_char(0, '1')
self.ae(l.text_at(0), ' 1')
l.add_combining_char(0, '2')
self.ae(l.text_at(0), ' 12')
l.add_combining_char(0, '3')
self.ae(l.text_at(0), ' 13')
self.ae(l.text_at(1), ' ')
self.ae(str(l), ' 13 ')
def test_line_ops(self):
t = 'Testing with simple text'