diff --git a/kitty/history.c b/kitty/history.c index 3b9e4e009..93ec91fb8 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -116,17 +116,30 @@ change_num_of_lines(HistoryBuf *self, PyObject *val) { } static PyObject* -line(HistoryBuf *self, PyObject *lnum) { -#define line_doc "Return the line with line number lnum. This buffer grows upwards, i.e. 0 is the most recently added line" - init_line(self, index_of(self, PyLong_AsUnsignedLong(lnum)), self->line); +line(HistoryBuf *self, PyObject *val) { +#define line_doc "Return the line with line number val. This buffer grows upwards, i.e. 0 is the most recently added line" + if (self->count == 0) { PyErr_SetString(PyExc_IndexError, "This buffer is empty"); return NULL; } + index_type lnum = PyLong_AsUnsignedLong(val); + if (lnum > self->count - 1) { PyErr_SetString(PyExc_IndexError, "Out of bounds"); return NULL; } + init_line(self, index_of(self, lnum), self->line); Py_INCREF(self->line); return (PyObject*)self->line; } +static PyObject* +push(HistoryBuf *self, PyObject *args) { +#define push_doc "Push a line into this buffer, removing the oldest line, if necessary" + Line *line; + if (!PyArg_ParseTuple(args, "O!", &Line_Type, &line)) return NULL; + historybuf_add_line(self, line); + Py_RETURN_NONE; +} + // Boilerplate {{{ static PyMethodDef methods[] = { METHOD(change_num_of_lines, METH_O) METHOD(line, METH_O) + METHOD(push, METH_VARARGS) {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/kitty_tests/__init__.py b/kitty_tests/__init__.py index 8920b656e..9e1d518c7 100644 --- a/kitty_tests/__init__.py +++ b/kitty_tests/__init__.py @@ -4,7 +4,7 @@ from unittest import TestCase -from kitty.fast_data_types import LineBuf, Cursor, Screen +from kitty.fast_data_types import LineBuf, Cursor, Screen, HistoryBuf def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()): @@ -25,6 +25,14 @@ def filled_cursor(): return ans +def filled_history_buf(ynum=5, xnum=5, cursor=Cursor()): + lb = filled_line_buf(ynum, xnum, cursor) + ans = HistoryBuf(ynum, xnum) + for i in range(ynum): + ans.push(lb.line(i)) + return ans + + class BaseTest(TestCase): ae = TestCase.assertEqual diff --git a/kitty_tests/datatypes.py b/kitty_tests/datatypes.py index 27e19c947..36ec9dd75 100644 --- a/kitty_tests/datatypes.py +++ b/kitty_tests/datatypes.py @@ -4,7 +4,7 @@ import codecs -from . import BaseTest, filled_line_buf, filled_cursor +from . import BaseTest, filled_line_buf, filled_cursor, filled_history_buf from kitty.config import build_ansi_color_table, defaults from kitty.utils import is_simple_string, wcwidth, sanitize_title @@ -236,12 +236,15 @@ class TestDataTypes(BaseTest): for i in range(lb2.ynum): self.ae(lb2.line(i), lb.line(i + 2)) - def line_comparison(self, lb, *lines): + def line_comparison(self, buf, *lines): + for i, l in enumerate(lines): + l2 = buf.line(i) + self.ae(l, str(l2)) + + def line_comparison_rewrap(self, lb, *lines): lb2 = LineBuf(len(lines), max(map(len, lines))) self.rewrap(lb, lb2) - for i, l in enumerate(lines): - l2 = lb2.line(i) - self.ae(l, str(l2)) + self.line_comparison(lb2, *lines) return lb2 def assertContinued(self, lb, *vals): @@ -250,17 +253,17 @@ class TestDataTypes(BaseTest): def test_rewrap_wider(self): ' New buffer wider ' lb = create_lbuf('0123 ', '56789') - lb2 = self.line_comparison(lb, '0123 5', '6789 ', ' ' * 6) + lb2 = self.line_comparison_rewrap(lb, '0123 5', '6789 ', ' ' * 6) self.assertContinued(lb2, False, True) lb = create_lbuf('12', 'abc') - lb2 = self.line_comparison(lb, '12 ', 'abc ') + lb2 = self.line_comparison_rewrap(lb, '12 ', 'abc ') self.assertContinued(lb2, False, False) def test_rewrap_narrower(self): ' New buffer narrower ' lb = create_lbuf('123 ', 'abcde') - lb2 = self.line_comparison(lb, '123', 'abc', 'de ') + lb2 = self.line_comparison_rewrap(lb, '123', 'abc', 'de ') self.assertContinued(lb2, False, False, True) def test_utils(self): @@ -292,3 +295,18 @@ class TestDataTypes(BaseTest): self.ae(s.position_for(0, 1), (0, 1, 1)) self.ae(s.position_for(0, 2), (1, 1, 1)) self.ae(s.position_for(0, 2), (1, 1, 1)) + + def test_historybuf(self): + lb = filled_line_buf() + hb = HistoryBuf(5, 5) + hb.push(lb.line(1)) + hb.push(lb.line(2)) + self.ae(hb.count, 2) + self.ae(hb.line(0), lb.line(2)) + self.ae(hb.line(1), lb.line(1)) + hb = filled_history_buf() + self.ae(str(hb.line(0)), '4' * hb.xnum) + self.ae(str(hb.line(4)), '0' * hb.xnum) + hb.push(lb.line(2)) + self.ae(str(hb.line(0)), '2' * hb.xnum) + self.ae(str(hb.line(4)), '1' * hb.xnum)