Allow using dump_lines_with_attrs on either screen

This commit is contained in:
Kovid Goyal 2024-10-19 12:49:04 +05:30
parent 56c7555a25
commit 661d8bc5a7
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 41 additions and 37 deletions

View file

@ -1226,7 +1226,7 @@ class Screen:
def draw(self, text: str) -> None:
pass
def dump_lines_with_attrs(self, acc: Callable[[str], None]) -> None:
def dump_lines_with_attrs(self, acc: Callable[[str], None], which_screen: int = -1) -> None:
pass
def apply_sgr(self, text: str) -> None:

View file

@ -4701,40 +4701,42 @@ scroll_prompt_to_bottom(Screen *self, PyObject *args UNUSED) {
Py_RETURN_NONE;
}
static PyObject*
dump_lines_with_attrs(Screen *self, PyObject *accum) {
int y = (self->linebuf == self->main_linebuf) ? -self->historybuf->count : 0;
PyObject *t;
while (y < (int)self->lines) {
Line *line = range_line_(self, y);
t = PyUnicode_FromFormat("\x1b[31m%d: \x1b[39m", y++);
if (t) {
PyObject_CallFunctionObjArgs(accum, t, NULL);
Py_DECREF(t);
}
switch (line->attrs.prompt_kind) {
case UNKNOWN_PROMPT_KIND:
break;
case PROMPT_START:
PyObject_CallFunction(accum, "s", "\x1b[32mprompt \x1b[39m");
break;
case SECONDARY_PROMPT:
PyObject_CallFunction(accum, "s", "\x1b[32msecondary_prompt \x1b[39m");
break;
case OUTPUT_START:
PyObject_CallFunction(accum, "s", "\x1b[33moutput \x1b[39m");
break;
}
if (line->attrs.is_continued) PyObject_CallFunction(accum, "s", "continued ");
if (line->attrs.has_dirty_text) PyObject_CallFunction(accum, "s", "dirty ");
PyObject_CallFunction(accum, "s", "\n");
t = line_as_unicode(line, false);
if (t) {
PyObject_CallFunctionObjArgs(accum, t, NULL);
Py_DECREF(t);
}
PyObject_CallFunction(accum, "s", "\n");
static void
dump_line_with_attrs(Screen *self, int y, PyObject *accum) {
Line *line = range_line_(self, y);
RAII_PyObject(u, PyUnicode_FromFormat("\x1b[31m%d: \x1b[39m", y++));
if (!u) return;
RAII_PyObject(r1, PyObject_CallOneArg(accum, u));
if (!r1) return;
#define call_string(s) { RAII_PyObject(ret, PyObject_CallFunction(accum, "s", s)); if (!ret) return; }
switch (line->attrs.prompt_kind) {
case UNKNOWN_PROMPT_KIND: break;
case PROMPT_START: call_string("\x1b[32mprompt \x1b[39m"); break;
case SECONDARY_PROMPT: call_string("\x1b[32msecondary_prompt \x1b[39m"); break;
case OUTPUT_START: call_string("\x1b[33moutput \x1b[39m"); break;
}
if (line->attrs.is_continued) call_string("continued ");
if (line->attrs.has_dirty_text) call_string("dirty ");
call_string("\n");
RAII_PyObject(t, line_as_unicode(line, false)); if (!t) return;
RAII_PyObject(r2, PyObject_CallOneArg(accum, t)); if (!r2) return;
call_string("\n");
#undef call_string
}
static PyObject*
dump_lines_with_attrs(Screen *self, PyObject *args) {
PyObject *accum; int which_screen = -1;
if (!PyArg_ParseTuple(args, "O|i", &accum, &which_screen)) return NULL;
LineBuf *orig = self->linebuf;
switch(which_screen) {
case 0: self->linebuf = self->main_linebuf; break;
case 1: self->linebuf = self->alt_linebuf; break;
}
int y = (self->linebuf == self->main_linebuf) ? -self->historybuf->count : 0;
while (y < (int)self->lines && !PyErr_Occurred()) dump_line_with_attrs(self, y++, accum);
self->linebuf = orig;
if (PyErr_Occurred()) return NULL;
Py_RETURN_NONE;
}
@ -4790,7 +4792,7 @@ static PyMethodDef methods[] = {
METHODB(test_parse_written_data, METH_VARARGS),
MND(line_edge_colors, METH_NOARGS)
MND(line, METH_O)
MND(dump_lines_with_attrs, METH_O)
MND(dump_lines_with_attrs, METH_VARARGS)
MND(cursor_at_prompt, METH_NOARGS)
MND(visual_line, METH_VARARGS)
MND(current_url_text, METH_NOARGS)

View file

@ -20,6 +20,7 @@
Any,
Callable,
Deque,
Literal,
NamedTuple,
Optional,
Union,
@ -1005,9 +1006,10 @@ def send_key_sequence(self, *keys: KeyEvent, synthesize_release_events: bool = T
self.write_to_child(enc)
@ac('debug', 'Show a dump of the current lines in the scrollback + screen with their line attributes')
def dump_lines_with_attrs(self) -> None:
def dump_lines_with_attrs(self, which_screen: Literal['main', 'alternate', 'current'] = 'current') -> None:
strings: list[str] = []
self.screen.dump_lines_with_attrs(strings.append)
ws = 0 if which_screen == 'main' else (1 if which_screen == 'alternate' else -1)
self.screen.dump_lines_with_attrs(strings.append, ws)
text = ''.join(strings)
get_boss().display_scrollback(self, text, title='Dump of lines', report_cursor=False)