From fc3bd2d15fa2b5385fa3d054a4dc4312ba31e45c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 3 Nov 2018 14:18:09 +0530 Subject: [PATCH] Add an action to the ``clear_terminal`` function to scroll the screen contents into the scrollback buffer Now if you want to map a key combination that will both scroll the current screen contents into the scrollback buffer and clear the screen, you can do something like: map ctrl+l combine : clear_terminal scroll active : send_text normal,application \x0c Fixes #1113 --- docs/changelog.rst | 3 +++ kitty/boss.py | 3 +++ kitty/config_data.py | 8 ++++++-- kitty/screen.c | 11 +++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 283be1d92..d4d675789 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -208,6 +208,9 @@ Changelog - Add an option :opt:`env` to set environment variables in child processes from kitty.conf +- Add an action to the ``clear_terminal`` function to scroll the screen + contents into the scrollback buffer (:iss:`1113`) + - Implement high precision scrolling with the trackpad on platforms such as macOS and Wayland that implement it. (:pull:`819`) diff --git a/kitty/boss.py b/kitty/boss.py index 9caaca67f..ac7ea6ab8 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -373,6 +373,9 @@ class Boss: reset = action == 'reset' how = 3 if action == 'scrollback' else 2 for w in windows: + if action == 'scroll': + w.screen.scroll_until_empty() + continue w.screen.cursor.x = w.screen.cursor.y = 0 if reset: w.screen.reset() diff --git a/kitty/config_data.py b/kitty/config_data.py index f23ceca23..87c580038 100644 --- a/kitty/config_data.py +++ b/kitty/config_data.py @@ -992,12 +992,16 @@ k('reset_terminal', 'kitty_mod+delete', 'clear_terminal reset active', _('Reset long_text=_(''' You can create shortcuts to clear/reset the terminal. For example:: + # Reset the terminal map kitty_mod+f9 clear_terminal reset active + # Clear the terminal screen by erasing all contents map kitty_mod+f10 clear_terminal clear active + # Clear the terminal scrollback by erasing it map kitty_mod+f11 clear_terminal scrollback active + # Clear the terminal screen by scrolling its contents into the scrollback + map kitty_mod+f12 clear_terminal scroll active -These will reset screen/clear screen/clear screen+scrollback respectively. If you want to -operate on all windows instead of just the current one, use :italic:`all` instead of :italic`active`. +If you want to operate on all windows instead of just the current one, use :italic:`all` instead of :italic`active`. ''')) k('send_text', 'ctrl+shift+alt+h', 'send_text all Hello World', _('Send arbitrary text on key presses'), add_to_default=False, long_text=_(''' diff --git a/kitty/screen.c b/kitty/screen.c index 0c1c17da3..a41092826 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1128,6 +1128,15 @@ screen_insert_lines(Screen *self, unsigned int count) { } } +void +screen_scroll_until_empty(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; +} + void screen_delete_lines(Screen *self, unsigned int count) { unsigned int top = self->margin_top, bottom = self->margin_bottom; @@ -1864,6 +1873,7 @@ is_using_alternate_linebuf(Screen *self, PyObject *a UNUSED) { WRAP1E(cursor_back, 1, -1) WRAP1B(erase_in_line, 0) WRAP1B(erase_in_display, 0) +WRAP0(scroll_until_empty) #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; } \ @@ -2170,6 +2180,7 @@ static PyMethodDef methods[] = { MND(cursor_back, METH_VARARGS) MND(erase_in_line, METH_VARARGS) MND(erase_in_display, METH_VARARGS) + MND(scroll_until_empty, METH_NOARGS) METHOD(current_char_width, METH_NOARGS) MND(insert_lines, METH_VARARGS) MND(delete_lines, METH_VARARGS)