Line.clear_text()
This commit is contained in:
parent
9869b30ce5
commit
3dc74413a5
@ -24,6 +24,7 @@ typedef unsigned int index_type;
|
|||||||
|
|
||||||
#define CHAR_MASK 0xFFFFFF
|
#define CHAR_MASK 0xFFFFFF
|
||||||
#define ATTRS_SHIFT 24
|
#define ATTRS_SHIFT 24
|
||||||
|
#define ATTRS_MASK_WITHOUT_WIDTH 0xFC000000
|
||||||
#define WIDTH_MASK 0xFF
|
#define WIDTH_MASK 0xFF
|
||||||
#define DECORATION_SHIFT 2
|
#define DECORATION_SHIFT 2
|
||||||
#define BOLD_SHIFT 4
|
#define BOLD_SHIFT 4
|
||||||
|
|||||||
15
kitty/line.c
15
kitty/line.c
@ -159,6 +159,20 @@ cursor_from(Line* self, PyObject *args) {
|
|||||||
return (PyObject*)ans;
|
return (PyObject*)ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
clear_text(Line* self, PyObject *args) {
|
||||||
|
#define clear_text_doc "clear_text(at, num, ch=' ') -> Clear characters in the specified range, preserving formatting."
|
||||||
|
unsigned int at, num;
|
||||||
|
int ch = 32;
|
||||||
|
if (!PyArg_ParseTuple(args, "II|C", &at, &num, &ch)) return NULL;
|
||||||
|
const char_type repl = ((char_type)ch & CHAR_MASK) | (1 << ATTRS_SHIFT);
|
||||||
|
for (index_type i = at; i < MIN(self->xnum, at + num); i++) {
|
||||||
|
self->chars[i] = (self->chars[i] & ATTRS_MASK_WITHOUT_WIDTH) | repl;
|
||||||
|
}
|
||||||
|
memset(self->combining_chars + at, 0, MIN(num, self->xnum - at) * sizeof(combining_type));
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
apply_cursor(Line* self, PyObject *args) {
|
apply_cursor(Line* self, PyObject *args) {
|
||||||
#define apply_cursor_doc "apply_cursor(cursor, at=0, num=1, clear_char=False) -> Apply the formatting attributes from cursor to the specified characters in this line."
|
#define apply_cursor_doc "apply_cursor(cursor, at=0, num=1, clear_char=False) -> Apply the formatting attributes from cursor to the specified characters in this line."
|
||||||
@ -293,6 +307,7 @@ static PyMethodDef methods[] = {
|
|||||||
METHOD(set_text, METH_VARARGS)
|
METHOD(set_text, METH_VARARGS)
|
||||||
METHOD(cursor_from, METH_VARARGS)
|
METHOD(cursor_from, METH_VARARGS)
|
||||||
METHOD(apply_cursor, METH_VARARGS)
|
METHOD(apply_cursor, METH_VARARGS)
|
||||||
|
METHOD(clear_text, METH_VARARGS)
|
||||||
METHOD(copy_char, METH_VARARGS)
|
METHOD(copy_char, METH_VARARGS)
|
||||||
METHOD(right_shift, METH_VARARGS)
|
METHOD(right_shift, METH_VARARGS)
|
||||||
METHOD(left_shift, METH_VARARGS)
|
METHOD(left_shift, METH_VARARGS)
|
||||||
|
|||||||
@ -607,7 +607,7 @@ class Screen:
|
|||||||
# TODO: Check what to do if x is on the second char of a wide char
|
# TODO: Check what to do if x is on the second char of a wide char
|
||||||
# pair.
|
# pair.
|
||||||
num = min(self.columns - x, count)
|
num = min(self.columns - x, count)
|
||||||
line = self.linebuf[y]
|
line = self.linebuf.line(y)
|
||||||
line.right_shift(x, num)
|
line.right_shift(x, num)
|
||||||
line.apply_cursor(self.cursor, x, num, clear_char=True)
|
line.apply_cursor(self.cursor, x, num, clear_char=True)
|
||||||
self.update_cell_range(y, x, self.columns - 1)
|
self.update_cell_range(y, x, self.columns - 1)
|
||||||
@ -631,7 +631,7 @@ class Screen:
|
|||||||
# for this control code. Also, what happens if we start deleting
|
# for this control code. Also, what happens if we start deleting
|
||||||
# at the second cell of a wide character, or delete only the first
|
# at the second cell of a wide character, or delete only the first
|
||||||
# cell of a wide character?
|
# cell of a wide character?
|
||||||
line = self.linebuf[y]
|
line = self.linebuf.line(y)
|
||||||
line.left_shift(x, num)
|
line.left_shift(x, num)
|
||||||
line.apply_cursor(self.cursor, self.columns - num, num, clear_char=True)
|
line.apply_cursor(self.cursor, self.columns - num, num, clear_char=True)
|
||||||
self.update_cell_range(y, x, self.columns - 1)
|
self.update_cell_range(y, x, self.columns - 1)
|
||||||
@ -654,7 +654,8 @@ class Screen:
|
|||||||
x, y = self.cursor.x, self.cursor.y
|
x, y = self.cursor.x, self.cursor.y
|
||||||
# TODO: Same set of wide character questions as for delete_characters()
|
# TODO: Same set of wide character questions as for delete_characters()
|
||||||
num = min(self.columns - x, count)
|
num = min(self.columns - x, count)
|
||||||
self.linebuf[y].apply_cursor(self.cursor, x, num, clear_char=True)
|
l = self.linebuf.line(y)
|
||||||
|
l.apply_cursor(self.cursor, x, num, clear_char=True)
|
||||||
self.update_cell_range(y, x, min(x + num, self.columns) - 1)
|
self.update_cell_range(y, x, min(x + num, self.columns) - 1)
|
||||||
|
|
||||||
def erase_in_line(self, how=0, private=False):
|
def erase_in_line(self, how=0, private=False):
|
||||||
@ -685,7 +686,7 @@ class Screen:
|
|||||||
if n - s:
|
if n - s:
|
||||||
# TODO: Same set of questions as for delete_characters()
|
# TODO: Same set of questions as for delete_characters()
|
||||||
y = self.cursor.y
|
y = self.cursor.y
|
||||||
line = self.linebuf[y]
|
line = self.linebuf.line(y)
|
||||||
c = None if private else self.cursor
|
c = None if private else self.cursor
|
||||||
if private:
|
if private:
|
||||||
line.clear_text(s, n)
|
line.clear_text(s, n)
|
||||||
@ -723,9 +724,9 @@ class Screen:
|
|||||||
if interval[1] > interval[0]:
|
if interval[1] > interval[0]:
|
||||||
for line in range(*interval):
|
for line in range(*interval):
|
||||||
if private:
|
if private:
|
||||||
self.linebuf[line].clear_text(0, self.columns)
|
self.linebuf.line(line).clear_text(0, self.columns)
|
||||||
else:
|
else:
|
||||||
self.linebuf[line].apply_cursor(self.cursor, 0, self.columns, clear_char=True)
|
self.linebuf.line(line).apply_cursor(self.cursor, 0, self.columns, clear_char=True)
|
||||||
self.update_line_range(interval[0], interval[1] - 1)
|
self.update_line_range(interval[0], interval[1] - 1)
|
||||||
|
|
||||||
# In case of 0 or 1 we have to erase the line with the cursor also
|
# In case of 0 or 1 we have to erase the line with the cursor also
|
||||||
@ -894,7 +895,7 @@ class Screen:
|
|||||||
def alignment_display(self):
|
def alignment_display(self):
|
||||||
"""Fills screen with uppercase E's for screen focus and alignment."""
|
"""Fills screen with uppercase E's for screen focus and alignment."""
|
||||||
for i in range(self.lines):
|
for i in range(self.lines):
|
||||||
self.linebuf[i].clear_text(0, self.columns, 'E')
|
self.linebuf.line(i).clear_text(0, self.columns, 'E')
|
||||||
|
|
||||||
def select_graphic_rendition(self, *attrs):
|
def select_graphic_rendition(self, *attrs):
|
||||||
"""Set display attributes.
|
"""Set display attributes.
|
||||||
|
|||||||
@ -107,6 +107,13 @@ class TestDataTypes(BaseTest):
|
|||||||
self.ae(lb.line(3), lb2.line(0))
|
self.ae(lb.line(3), lb2.line(0))
|
||||||
self.ae(lb.line(4), clb.line(4))
|
self.ae(lb.line(4), clb.line(4))
|
||||||
|
|
||||||
|
lb = filled_line_buf(5, 5, filled_cursor())
|
||||||
|
l = lb.line(0)
|
||||||
|
l.add_combining_char(1, 'a')
|
||||||
|
l.clear_text(1, 2)
|
||||||
|
self.ae(str(l), '0 00')
|
||||||
|
self.assertEqualAttributes(l.cursor_from(1), l.cursor_from(0))
|
||||||
|
|
||||||
def test_line(self):
|
def test_line(self):
|
||||||
lb = LineBuf(2, 3)
|
lb = LineBuf(2, 3)
|
||||||
for y in range(lb.ynum):
|
for y in range(lb.ynum):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user