Save the last jumped prompt position

This commit is contained in:
pagedown 2021-11-14 15:09:32 +08:00 committed by Kovid Goyal
parent bc454b4417
commit 9fe9c74021
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 32 additions and 15 deletions

View File

@ -64,6 +64,11 @@ init_overlay_line(Screen *self, index_type columns) {
return true;
}
static void
clear_last_visited_prompt(Screen *self) {
self->last_visited_prompt_scrolled_by = self->historybuf->count + 1;
}
#define RESET_CHARSETS \
self->g0_charset = translation_table(0); \
self->g1_charset = self->g0_charset; \
@ -143,6 +148,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
self->hyperlink_pool = alloc_hyperlink_pool();
if (!self->hyperlink_pool) { Py_CLEAR(self); return PyErr_NoMemory(); }
self->as_ansi_buf.hyperlink_pool = self->hyperlink_pool;
clear_last_visited_prompt(self);
}
return (PyObject*) self;
}
@ -389,6 +395,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
self->is_dirty = true;
clear_selection(&self->selections);
clear_selection(&self->url_ranges);
clear_last_visited_prompt(self);
/* printf("old_cursor: (%u, %u) new_cursor: (%u, %u) beyond_content: %d\n", self->cursor->x, self->cursor->y, cursor_x, cursor_y, cursor_is_beyond_content); */
#define S(c, w) c->x = MIN(w.after.x, self->columns - 1); c->y = MIN(w.after.y, self->lines - 1);
S(self->cursor, cursor);
@ -1268,6 +1275,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
linebuf_init_line(self->linebuf, bottom); \
historybuf_add_line(self->historybuf, self->linebuf->line, &self->as_ansi_buf); \
self->history_line_added_count++; \
if (self->last_visited_prompt_scrolled_by <= self->historybuf->count) self->last_visited_prompt_scrolled_by++; \
} \
linebuf_clear_line(self->linebuf, bottom, true); \
self->is_dirty = true; \
@ -2017,7 +2025,12 @@ shell_prompt_marking(Screen *self, PyObject *data) {
static bool
screen_history_scroll_to_prompt(Screen *self, int num_of_prompts_to_jump) {
if (self->linebuf != self->main_linebuf || !num_of_prompts_to_jump) return false;
if (self->linebuf != self->main_linebuf) return false;
unsigned int old = self->scrolled_by;
if (num_of_prompts_to_jump == 0) {
if (self->last_visited_prompt_scrolled_by > self->historybuf->count) return false;
self->scrolled_by = self->last_visited_prompt_scrolled_by;
} else {
int delta = num_of_prompts_to_jump < 0 ? -1 : 1;
num_of_prompts_to_jump = num_of_prompts_to_jump < 0 ? -num_of_prompts_to_jump : num_of_prompts_to_jump;
int y = -self->scrolled_by;
@ -2031,8 +2044,9 @@ screen_history_scroll_to_prompt(Screen *self, int num_of_prompts_to_jump) {
}
}
#undef ensure_y_ok
unsigned int old = self->scrolled_by;
self->scrolled_by = y >= 0 ? 0 : -y;
self->last_visited_prompt_scrolled_by = self->scrolled_by;
}
if (old != self->scrolled_by) self->scroll_changed = true;
return old != self->scrolled_by;
}

View File

@ -144,6 +144,7 @@ typedef struct {
uint8_t *canvas;
size_t requested_height, width_px, height_px;
} last_rendered_window_char;
unsigned int last_visited_prompt_scrolled_by;
} Screen;

View File

@ -1180,10 +1180,12 @@ class Window:
Allows easy jumping from one command to the next. Requires working
:ref:`shell_integration`. Takes a single, optional, number as argument which is
the number of prompts to jump, negative values jump up and positive values jump down.
A value of zero will jump to the last prompt visited by this action.
For example::
map ctrl+p scroll_to_prompt -1 # jump to previous
map ctrl+n scroll_to_prompt 1 # jump to next
map ctrl+o scroll_to_prompt 0 # jump to last visited
''')
def scroll_to_prompt(self, num_of_prompts: int = -1) -> None:
if self.screen.is_main_linebuf():