Line.clear_text()

This commit is contained in:
Kovid Goyal 2016-11-08 09:00:18 +05:30
parent 9869b30ce5
commit 3dc74413a5
4 changed files with 31 additions and 7 deletions

View File

@ -24,6 +24,7 @@ typedef unsigned int index_type;
#define CHAR_MASK 0xFFFFFF
#define ATTRS_SHIFT 24
#define ATTRS_MASK_WITHOUT_WIDTH 0xFC000000
#define WIDTH_MASK 0xFF
#define DECORATION_SHIFT 2
#define BOLD_SHIFT 4

View File

@ -159,6 +159,20 @@ cursor_from(Line* self, PyObject *args) {
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*
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."
@ -293,6 +307,7 @@ static PyMethodDef methods[] = {
METHOD(set_text, METH_VARARGS)
METHOD(cursor_from, METH_VARARGS)
METHOD(apply_cursor, METH_VARARGS)
METHOD(clear_text, METH_VARARGS)
METHOD(copy_char, METH_VARARGS)
METHOD(right_shift, METH_VARARGS)
METHOD(left_shift, METH_VARARGS)

View File

@ -607,7 +607,7 @@ class Screen:
# TODO: Check what to do if x is on the second char of a wide char
# pair.
num = min(self.columns - x, count)
line = self.linebuf[y]
line = self.linebuf.line(y)
line.right_shift(x, num)
line.apply_cursor(self.cursor, x, num, clear_char=True)
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
# at the second cell of a wide character, or delete only the first
# cell of a wide character?
line = self.linebuf[y]
line = self.linebuf.line(y)
line.left_shift(x, num)
line.apply_cursor(self.cursor, self.columns - num, num, clear_char=True)
self.update_cell_range(y, x, self.columns - 1)
@ -654,7 +654,8 @@ class Screen:
x, y = self.cursor.x, self.cursor.y
# TODO: Same set of wide character questions as for delete_characters()
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)
def erase_in_line(self, how=0, private=False):
@ -685,7 +686,7 @@ class Screen:
if n - s:
# TODO: Same set of questions as for delete_characters()
y = self.cursor.y
line = self.linebuf[y]
line = self.linebuf.line(y)
c = None if private else self.cursor
if private:
line.clear_text(s, n)
@ -723,9 +724,9 @@ class Screen:
if interval[1] > interval[0]:
for line in range(*interval):
if private:
self.linebuf[line].clear_text(0, self.columns)
self.linebuf.line(line).clear_text(0, self.columns)
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)
# 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):
"""Fills screen with uppercase E's for screen focus and alignment."""
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):
"""Set display attributes.

View File

@ -107,6 +107,13 @@ class TestDataTypes(BaseTest):
self.ae(lb.line(3), lb2.line(0))
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):
lb = LineBuf(2, 3)
for y in range(lb.ynum):