LineBuf.delete_lines

This commit is contained in:
Kovid Goyal
2016-11-07 20:55:40 +05:30
parent 17e59ccc22
commit 9869b30ce5
3 changed files with 64 additions and 12 deletions

View File

@@ -249,24 +249,56 @@ static PyObject*
insert_lines(LineBuf *self, PyObject *args) { insert_lines(LineBuf *self, PyObject *args) {
#define insert_lines_doc "insert_lines(num, y, bottom) -> Insert num blank lines at y, only changing lines in the range [y, bottom]." #define insert_lines_doc "insert_lines(num, y, bottom) -> Insert num blank lines at y, only changing lines in the range [y, bottom]."
unsigned int y, num, bottom; unsigned int y, num, bottom;
index_type i;
if (!PyArg_ParseTuple(args, "III", &num, &y, &bottom)) return NULL; if (!PyArg_ParseTuple(args, "III", &num, &y, &bottom)) return NULL;
if (y >= self->ynum || y > bottom || bottom >= self->ynum) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; } if (y >= self->ynum || y > bottom || bottom >= self->ynum) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; }
index_type ylimit = bottom + 1; index_type ylimit = bottom + 1;
num = MIN(ylimit - y, num); num = MIN(ylimit - y, num);
if (num > 0) { if (num > 0) {
for (index_type i = ylimit - num; i < ylimit; i++) { for (i = ylimit - num; i < ylimit; i++) {
self->scratch[i] = self->line_map[i]; self->scratch[i] = self->line_map[i];
} }
for (index_type i = ylimit - 1; i >= y + num; i--) { for (i = ylimit - 1; i >= y + num; i--) {
self->line_map[i] = self->line_map[i - num]; self->line_map[i] = self->line_map[i - num];
self->continued_map[i] = self->continued_map[i - num]; self->continued_map[i] = self->continued_map[i - num];
} }
if (y + num < self->ynum) self->continued_map[y + num] = 0; if (y + num < self->ynum) self->continued_map[y + num] = 0;
for (index_type i = 0; i < num; i++) { for (i = 0; i < num; i++) {
self->line_map[y + i] = self->scratch[ylimit - num + i]; self->line_map[y + i] = self->scratch[ylimit - num + i];
} }
Line l; Line l;
for (index_type i = y; i < y + num; i++) { for (i = y; i < y + num; i++) {
INIT_LINE(self, &l, self->line_map[i]);
CLEAR_LINE(l);
self->continued_map[i] = 0;
}
}
Py_RETURN_NONE;
}
static PyObject*
delete_lines(LineBuf *self, PyObject *args) {
#define delete_lines_doc "delete_lines(num, y, bottom) -> Delete num blank lines at y, only changing lines in the range [y, bottom]."
unsigned int y, num, bottom;
index_type i;
if (!PyArg_ParseTuple(args, "III", &num, &y, &bottom)) return NULL;
if (y >= self->ynum || y > bottom || bottom >= self->ynum) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; }
index_type ylimit = bottom + 1;
num = MIN(ylimit - y, num);
if (num > 0) {
for (i = y; i < y + num; i++) {
self->scratch[i] = self->line_map[i];
}
for (i = y; i < ylimit; i++) {
self->line_map[i] = self->line_map[i + num];
self->continued_map[i] = self->continued_map[i + num];
}
self->continued_map[y] = 0;
for (i = 0; i < num; i++) {
self->line_map[ylimit - num + i] = self->scratch[y + i];
}
Line l;
for (i = ylimit - num; i < ylimit; i++) {
INIT_LINE(self, &l, self->line_map[i]); INIT_LINE(self, &l, self->line_map[i]);
CLEAR_LINE(l); CLEAR_LINE(l);
self->continued_map[i] = 0; self->continued_map[i] = 0;
@@ -275,7 +307,6 @@ insert_lines(LineBuf *self, PyObject *args) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
// Boilerplate {{{ // Boilerplate {{{
static PyObject* static PyObject*
copy_old(LineBuf *self, PyObject *y); copy_old(LineBuf *self, PyObject *y);
@@ -293,6 +324,7 @@ static PyMethodDef methods[] = {
METHOD(index, METH_VARARGS) METHOD(index, METH_VARARGS)
METHOD(reverse_index, METH_VARARGS) METHOD(reverse_index, METH_VARARGS)
METHOD(insert_lines, METH_VARARGS) METHOD(insert_lines, METH_VARARGS)
METHOD(delete_lines, METH_VARARGS)
METHOD(is_continued, METH_O) METHOD(is_continued, METH_O)
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };

View File

@@ -586,12 +586,8 @@ class Screen:
# If cursor is outside scrolling margins it -- do nothin'. # If cursor is outside scrolling margins it -- do nothin'.
if top <= self.cursor.y <= bottom: if top <= self.cursor.y <= bottom:
# v -- +1 to include the bottom margin. self.linebuf.delete_lines(count, self.cursor.y, bottom)
for _ in range(min(bottom - self.cursor.y + 1, count)):
self.linebuf.pop(self.cursor.y)
self.linebuf.insert(bottom, Line(self.columns))
self.update_line_range(self.cursor.y, bottom) self.update_line_range(self.cursor.y, bottom)
self.carriage_return() self.carriage_return()
def insert_characters(self, count=1): def insert_characters(self, count=1):

View File

@@ -36,7 +36,7 @@ class TestDataTypes(BaseTest):
lb2.copy_old(lb) lb2.copy_old(lb)
lb.index(0, 4) lb.index(0, 4)
for i in range(0, 4): for i in range(0, 4):
self.ae(lb.line(i), lb2.line(i+1)) self.ae(lb.line(i), lb2.line(i + 1))
self.ae(lb.line(4), lb2.line(0)) self.ae(lb.line(4), lb2.line(0))
lb = filled_line_buf(5, 5, filled_cursor()) lb = filled_line_buf(5, 5, filled_cursor())
lb.index(1, 3) lb.index(1, 3)
@@ -55,7 +55,7 @@ class TestDataTypes(BaseTest):
lb.reverse_index(0, 4) lb.reverse_index(0, 4)
self.ae(lb.line(0), lb2.line(4)) self.ae(lb.line(0), lb2.line(4))
for i in range(1, 5): for i in range(1, 5):
self.ae(lb.line(i), lb2.line(i-1)) self.ae(lb.line(i), lb2.line(i - 1))
lb = filled_line_buf(5, 5, filled_cursor()) lb = filled_line_buf(5, 5, filled_cursor())
clb = filled_line_buf(5, 5, filled_cursor()) clb = filled_line_buf(5, 5, filled_cursor())
@@ -83,6 +83,30 @@ class TestDataTypes(BaseTest):
self.ae(lb.line(3), clb.line(2)) self.ae(lb.line(3), clb.line(2))
self.ae(lb.line(4), clb.line(4)) self.ae(lb.line(4), clb.line(4))
lb = filled_line_buf(5, 5, filled_cursor())
lb.delete_lines(2, 1, lb.ynum - 1)
self.ae(lb.line(0), clb.line(0))
self.ae(lb.line(1), clb.line(3))
self.ae(lb.line(2), clb.line(4))
self.ae(lb.line(3), lb2.line(0))
self.ae(lb.line(4), lb2.line(0))
lb = filled_line_buf(5, 5, filled_cursor())
lb.delete_lines(10, 0, lb.ynum - 1)
for i in range(lb.ynum):
self.ae(lb.line(i), lb2.line(0))
lb = filled_line_buf(5, 5, filled_cursor())
lb.delete_lines(10, 1, lb.ynum - 1)
self.ae(lb.line(0), clb.line(0))
for i in range(1, lb.ynum):
self.ae(lb.line(i), lb2.line(0))
lb = filled_line_buf(5, 5, filled_cursor())
lb.delete_lines(1, 1, 3)
self.ae(lb.line(0), clb.line(0))
self.ae(lb.line(1), clb.line(2))
self.ae(lb.line(2), clb.line(3))
self.ae(lb.line(3), lb2.line(0))
self.ae(lb.line(4), clb.line(4))
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):