__eq__ for Line
This commit is contained in:
parent
8324ec1c2b
commit
d324baf979
@ -42,7 +42,7 @@ dealloc(Cursor* self) {
|
||||
|
||||
#define EQ(x) (a->x == b->x)
|
||||
#define PEQ(x) (PyObject_RichCompareBool(a->x, b->x, Py_EQ) == 1)
|
||||
int is_eq(Cursor *a, Cursor *b) {
|
||||
static int __eq__(Cursor *a, Cursor *b) {
|
||||
return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && PEQ(x) && PEQ(y) && PEQ(shape) && PEQ(blink) && PEQ(color) && PEQ(hidden);
|
||||
}
|
||||
|
||||
@ -103,25 +103,10 @@ PyTypeObject Cursor_Type = {
|
||||
.tp_new = new,
|
||||
};
|
||||
|
||||
RICHCMP(Cursor)
|
||||
|
||||
// }}}
|
||||
|
||||
static PyObject *
|
||||
richcmp(PyObject *obj1, PyObject *obj2, int op)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
int eq;
|
||||
|
||||
if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; }
|
||||
if (!PyObject_TypeCheck(obj1, &Cursor_Type)) { Py_RETURN_FALSE; }
|
||||
if (!PyObject_TypeCheck(obj2, &Cursor_Type)) { Py_RETURN_FALSE; }
|
||||
eq = is_eq((Cursor*)obj1, (Cursor*)obj2);
|
||||
if (op == Py_NE) result = eq ? Py_False : Py_True;
|
||||
else result = eq ? Py_True : Py_False;
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
copy(Cursor *self, PyObject UNUSED *args) {
|
||||
#define CPY(x) ans->x = self->x; Py_XINCREF(self->x);
|
||||
|
||||
@ -69,6 +69,22 @@ typedef unsigned int index_type;
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define RICHCMP(type) \
|
||||
static PyObject * richcmp(PyObject *obj1, PyObject *obj2, int op) { \
|
||||
PyObject *result = NULL; \
|
||||
int eq; \
|
||||
if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } \
|
||||
if (!PyObject_TypeCheck(obj1, &type##_Type)) { Py_RETURN_FALSE; } \
|
||||
if (!PyObject_TypeCheck(obj2, &type##_Type)) { Py_RETURN_FALSE; } \
|
||||
eq = __eq__((type*)obj1, (type*)obj2); \
|
||||
if (op == Py_NE) result = eq ? Py_False : Py_True; \
|
||||
else result = eq ? Py_True : Py_False; \
|
||||
Py_INCREF(result); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
|
||||
14
kitty/line.c
14
kitty/line.c
@ -250,11 +250,22 @@ __len__(PyObject *self) {
|
||||
return (Py_ssize_t)(((Line*)self)->ynum);
|
||||
}
|
||||
|
||||
static int __eq__(Line *a, Line *b) {
|
||||
return a->xnum == b->xnum && \
|
||||
memcmp(a->chars, b->chars, sizeof(char_type) * a->xnum) == 0 && \
|
||||
memcmp(a->colors, b->colors, sizeof(color_type) * a->xnum) == 0 && \
|
||||
memcmp(a->decoration_fg, b->decoration_fg, sizeof(decoration_type) * a->xnum) == 0 && \
|
||||
memcmp(a->combining_chars, b->combining_chars, sizeof(combining_type) * a->xnum) == 0;
|
||||
}
|
||||
|
||||
// Boilerplate {{{
|
||||
static PyObject*
|
||||
copy_char(Line* self, PyObject *args);
|
||||
#define copy_char_doc "copy_char(src, to, dest) -> Copy the character at src to to the character dest in the line `to`"
|
||||
|
||||
static PyObject *
|
||||
richcmp(PyObject *obj1, PyObject *obj2, int op);
|
||||
|
||||
|
||||
static PySequenceMethods sequence_methods = {
|
||||
.sq_length = __len__,
|
||||
@ -282,6 +293,7 @@ static PyTypeObject Line_Type = {
|
||||
.tp_repr = (reprfunc)as_unicode,
|
||||
.tp_as_sequence = &sequence_methods,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_richcompare = richcmp,
|
||||
.tp_doc = "Lines",
|
||||
.tp_methods = methods,
|
||||
.tp_new = new
|
||||
@ -290,6 +302,8 @@ static PyTypeObject Line_Type = {
|
||||
Line *alloc_line() {
|
||||
return (Line*)PyType_GenericAlloc(&Line_Type, 0);
|
||||
}
|
||||
|
||||
RICHCMP(Line)
|
||||
// }}
|
||||
|
||||
static PyObject*
|
||||
|
||||
@ -20,6 +20,15 @@ def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()):
|
||||
return ans
|
||||
|
||||
|
||||
def filled_cursor():
|
||||
ans = Cursor()
|
||||
ans.bold = ans.italic = ans.reverse = ans.strikethrough = True
|
||||
ans.fg = 0x101
|
||||
ans.bg = 0x201
|
||||
ans.decoration_fg = 0x301
|
||||
return ans
|
||||
|
||||
|
||||
class BaseTest(TestCase):
|
||||
|
||||
ae = TestCase.assertEqual
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import codecs
|
||||
|
||||
from . import BaseTest, filled_line_buf
|
||||
from . import BaseTest, filled_line_buf, filled_cursor
|
||||
|
||||
from kitty.utils import is_simple_string, wcwidth, sanitize_title
|
||||
from kitty.fast_data_types import LineBuf, Cursor as C
|
||||
@ -13,10 +13,10 @@ from kitty.fast_data_types import LineBuf, Cursor as C
|
||||
class TestDataTypes(BaseTest):
|
||||
|
||||
def test_linebuf(self):
|
||||
old = filled_line_buf(2, 3)
|
||||
old = filled_line_buf(2, 3, filled_cursor())
|
||||
new = LineBuf(1, 3)
|
||||
new.copy_old(old)
|
||||
self.ae(str(new.line(0)), str(old.line(1)))
|
||||
self.ae(new.line(0), old.line(1))
|
||||
|
||||
def test_line(self):
|
||||
lb = LineBuf(2, 3)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user