Implement add combining char
This commit is contained in:
parent
c069d40ffe
commit
85076d3012
@ -36,6 +36,8 @@ typedef unsigned int index_type;
|
|||||||
#define COL_MASK 0xFFFFFFFF
|
#define COL_MASK 0xFFFFFFFF
|
||||||
#define COL_SHIFT 32
|
#define COL_SHIFT 32
|
||||||
#define HAS_BG_MASK (0xFF << COL_SHIFT)
|
#define HAS_BG_MASK (0xFF << COL_SHIFT)
|
||||||
|
#define CC_MASK 0xFFFF
|
||||||
|
#define CC_SHIFT 16
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|||||||
24
kitty/line.c
24
kitty/line.c
@ -35,7 +35,7 @@ text_at(Line* self, PyObject *x) {
|
|||||||
if (ans == NULL) return PyErr_NoMemory();
|
if (ans == NULL) return PyErr_NoMemory();
|
||||||
PyUnicode_WriteChar(ans, 0, ch);
|
PyUnicode_WriteChar(ans, 0, ch);
|
||||||
} else {
|
} 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);
|
Py_UCS4 maxc = (ch > cc1) ? MAX(ch, cc2) : MAX(cc1, cc2);
|
||||||
ans = PyUnicode_New(cc2 ? 3 : 2, maxc);
|
ans = PyUnicode_New(cc2 ? 3 : 2, maxc);
|
||||||
if (ans == NULL) return PyErr_NoMemory();
|
if (ans == NULL) return PyErr_NoMemory();
|
||||||
@ -59,7 +59,7 @@ as_unicode(Line* self) {
|
|||||||
char_type ch = self->chars[i] & CHAR_MASK;
|
char_type ch = self->chars[i] & CHAR_MASK;
|
||||||
char_type cc = self->combining_chars[i];
|
char_type cc = self->combining_chars[i];
|
||||||
buf[n++] = ch & CHAR_MASK;
|
buf[n++] = ch & CHAR_MASK;
|
||||||
Py_UCS4 cc1 = cc & 0xFFFF, cc2;
|
Py_UCS4 cc1 = cc & CC_MASK, cc2;
|
||||||
if (cc1) {
|
if (cc1) {
|
||||||
buf[n++] = cc1;
|
buf[n++] = cc1;
|
||||||
cc2 = cc >> 16;
|
cc2 = cc >> 16;
|
||||||
@ -71,10 +71,28 @@ as_unicode(Line* self) {
|
|||||||
return ans;
|
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 {{{
|
// Boilerplate {{{
|
||||||
static PyMethodDef methods[] = {
|
static PyMethodDef methods[] = {
|
||||||
{"text_at", (PyCFunction)text_at, METH_O,
|
{"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 */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,7 +13,7 @@ from kitty.fast_data_types import LineBuf
|
|||||||
|
|
||||||
class TestDataTypes(BaseTest):
|
class TestDataTypes(BaseTest):
|
||||||
|
|
||||||
def test_line_buf(self):
|
def test_line(self):
|
||||||
lb = LineBuf(2, 3)
|
lb = LineBuf(2, 3)
|
||||||
for y in range(2):
|
for y in range(2):
|
||||||
line = lb.line(y)
|
line = lb.line(y)
|
||||||
@ -24,6 +24,15 @@ class TestDataTypes(BaseTest):
|
|||||||
lb.line(5)
|
lb.line(5)
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
lb.line(0).text_at(5)
|
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):
|
def test_line_ops(self):
|
||||||
t = 'Testing with simple text'
|
t = 'Testing with simple text'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user