A new escape code that moves the current contents of the screen into the scrollback before clearing it

This commit is contained in:
Kovid Goyal 2023-05-09 09:32:39 +05:30
parent 8f15654985
commit e72975cc98
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 30 additions and 3 deletions

View File

@ -38,6 +38,8 @@ Detailed list of changes
0.28.2 [future] 0.28.2 [future]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new escape code ``<ESC>[22J`` that moves the current contents of the screen into the scrollback before clearing it
- unicode_input kitten: Fix a regression in 0.28.0 that caused the order of recent and favorites entries to not be respected (:iss:`6214`) - unicode_input kitten: Fix a regression in 0.28.0 that caused the order of recent and favorites entries to not be respected (:iss:`6214`)
- unicode_input kitten: Fix a regression in 0.28.0 that caused editing of favorites to sometimes hang - unicode_input kitten: Fix a regression in 0.28.0 that caused editing of favorites to sometimes hang

View File

@ -3997,8 +3997,7 @@ clearing the screen, for example, for ZSH add the following to :file:`~/.zshrc`:
.. code-block:: zsh .. code-block:: zsh
scroll-and-clear-screen() { scroll-and-clear-screen() {
printf '\\n%.0s' {1..$LINES} printf "\e[H\e[22J"
zle clear-screen
} }
zle -N scroll-and-clear-screen zle -N scroll-and-clear-screen
bindkey '^l' scroll-and-clear-screen bindkey '^l' scroll-and-clear-screen

View File

@ -1628,6 +1628,26 @@ screen_clear_scrollback(Screen *self) {
} }
} }
static Line* visual_line_(Screen *self, int y_);
static void
screen_move_into_scrollback(Screen *self) {
if (self->linebuf != self->main_linebuf || self->margin_top != 0 || self->margin_bottom != self->lines - 1) return;
unsigned int num_of_lines_to_move = self->lines;
while (num_of_lines_to_move) {
Line *line = visual_line_(self, num_of_lines_to_move-1);
if (!line_is_empty(line)) break;
num_of_lines_to_move--;
}
if (num_of_lines_to_move) {
unsigned int top, bottom;
for (; num_of_lines_to_move; num_of_lines_to_move--) {
top = 0, bottom = num_of_lines_to_move - 1;
INDEX_UP
}
}
}
void void
screen_erase_in_display(Screen *self, unsigned int how, bool private) { screen_erase_in_display(Screen *self, unsigned int how, bool private) {
/* Erases display in a specific way. /* Erases display in a specific way.
@ -1640,6 +1660,8 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
including cursor position. including cursor position.
* ``2`` -- Erases complete display. All lines are erased * ``2`` -- Erases complete display. All lines are erased
and changed to single-width. Cursor does not move. and changed to single-width. Cursor does not move.
* ``22`` -- Copy screen contents into scrollback if in main screen,
then do the same as ``2``.
* ``3`` -- Erase complete display and scrollback buffer as well. * ``3`` -- Erase complete display and scrollback buffer as well.
:param bool private: when ``True`` character attributes are left unchanged :param bool private: when ``True`` character attributes are left unchanged
*/ */
@ -1649,6 +1671,10 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
a = self->cursor->y + 1; b = self->lines; break; a = self->cursor->y + 1; b = self->lines; break;
case 1: case 1:
a = 0; b = self->cursor->y; break; a = 0; b = self->cursor->y; break;
case 22:
screen_move_into_scrollback(self);
how = 2;
/* fallthrough */
case 2: case 2:
case 3: case 3:
grman_clear(self->grman, how == 3, self->cell_size); grman_clear(self->grman, how == 3, self->cell_size);
@ -1671,7 +1697,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
self->is_dirty = true; self->is_dirty = true;
clear_selection(&self->selections); clear_selection(&self->selections);
} }
if (how != 2) { if (how < 2) {
screen_erase_in_line(self, how, private); screen_erase_in_line(self, how, private);
if (how == 1) linebuf_clear_attrs_and_dirty(self->linebuf, self->cursor->y); if (how == 1) linebuf_clear_attrs_and_dirty(self->linebuf, self->cursor->y);
} }