A new action to clear scrollback+screen upto the line with the cursor

This commit is contained in:
Kovid Goyal 2022-02-04 11:42:42 +05:30
parent 8960bfebc0
commit 42fbd0a1af
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 24 additions and 9 deletions

View File

@ -82,6 +82,9 @@ Detailed list of changes
- ssh kitten: Fix location of generated terminfo files on NetBSD (:iss:`4622`)
- A new action to clear the screen up to the line containing the cursor, see
:ac:`clear_terminal`
0.24.2 [2022-02-03]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -779,7 +779,8 @@ def on_window_resize(self, os_window_id: int, w: int, h: int, dpi_changed: bool)
map kitty_mod+f11 clear_terminal scrollback active
# Scroll the contents of the screen into the scrollback
map kitty_mod+f12 clear_terminal scroll active
# Clear everything up to the line with the cursor
map kitty_mod+f9 clear_terminal to_cursor active
''')
def clear_terminal(self, action: str, only_active: bool) -> None:
if only_active:
@ -792,8 +793,10 @@ def clear_terminal(self, action: str, only_active: bool) -> None:
reset = action == 'reset'
how = 3 if action == 'scrollback' else 2
for w in windows:
if action == 'scroll':
if action in ('to_cursor', 'scroll'):
w.screen.scroll_until_cursor()
if action == 'to_cursor':
w.screen.clear_scrollback()
continue
w.screen.cursor.x = w.screen.cursor.y = 0
if reset:

View File

@ -1136,6 +1136,9 @@ class Screen:
def erase_in_display(self, how: int = 0, private: bool = False) -> None:
pass
def clear_scrollback(self) -> None:
pass
def focus_changed(self, focused: bool) -> bool:
pass

View File

@ -1616,6 +1616,15 @@ screen_erase_in_line(Screen *self, unsigned int how, bool private) {
}
}
static void
screen_clear_scrollback(Screen *self) {
historybuf_clear(self->historybuf);
if (self->scrolled_by != 0) {
self->scrolled_by = 0;
self->scroll_changed = true;
}
}
void
screen_erase_in_display(Screen *self, unsigned int how, bool private) {
/* Erases display in a specific way.
@ -1662,11 +1671,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
if (how == 1) linebuf_clear_attrs_and_dirty(self->linebuf, self->cursor->y);
}
if (how == 3 && self->linebuf == self->main_linebuf) {
historybuf_clear(self->historybuf);
if (self->scrolled_by != 0) {
self->scrolled_by = 0;
self->scroll_changed = true;
}
screen_clear_scrollback(self);
}
}
@ -1685,10 +1690,9 @@ screen_insert_lines(Screen *self, unsigned int count) {
void
screen_scroll_until_cursor(Screen *self) {
unsigned int num_lines_to_scroll = MIN(self->margin_bottom, self->cursor->y + 1);
index_type y = self->cursor->y;
self->cursor->y = self->margin_bottom;
while (num_lines_to_scroll--) screen_index(self);
self->cursor->y = y;
self->cursor->y = self->margin_top;
}
void
@ -2957,6 +2961,7 @@ WRAP1E(cursor_back, 1, -1)
WRAP1B(erase_in_line, 0)
WRAP1B(erase_in_display, 0)
WRAP0(scroll_until_cursor)
WRAP0(clear_scrollback)
#define MODE_GETSET(name, uname) \
static PyObject* name##_get(Screen *self, void UNUSED *closure) { PyObject *ans = self->modes.m##uname ? Py_True : Py_False; Py_INCREF(ans); return ans; } \
@ -3777,6 +3782,7 @@ static PyMethodDef methods[] = {
MND(cursor_back, METH_VARARGS)
MND(erase_in_line, METH_VARARGS)
MND(erase_in_display, METH_VARARGS)
MND(clear_scrollback, METH_NOARGS)
MND(scroll_until_cursor, METH_NOARGS)
MND(hyperlinks_as_list, METH_NOARGS)
MND(garbage_collect_hyperlink_pool, METH_NOARGS)