When reflowing the screen, also reflow the saved cursor position
This commit is contained in:
parent
c60a941d1b
commit
4ab299d0af
@ -544,7 +544,7 @@ copy_old(LineBuf *self, PyObject *y) {
|
|||||||
#include "rewrap.h"
|
#include "rewrap.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *num_content_lines_before, index_type *num_content_lines_after, HistoryBuf *historybuf, index_type *track_x, index_type *track_y, ANSIBuf *as_ansi_buf) {
|
linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *num_content_lines_before, index_type *num_content_lines_after, HistoryBuf *historybuf, index_type *track_x, index_type *track_y, index_type *track_x2, index_type *track_y2, ANSIBuf *as_ansi_buf) {
|
||||||
index_type first, i;
|
index_type first, i;
|
||||||
bool is_empty = true;
|
bool is_empty = true;
|
||||||
|
|
||||||
@ -574,9 +574,10 @@ linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *num_content_lines_befo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackCursor tcarr[2] = {{.x = *track_x, .y = *track_y }, {.is_sentinel = true}};
|
TrackCursor tcarr[3] = {{.x = *track_x, .y = *track_y }, {.x = *track_x2, .y = *track_y2}, {.is_sentinel = true}};
|
||||||
rewrap_inner(self, other, first + 1, historybuf, (TrackCursor*)tcarr, as_ansi_buf);
|
rewrap_inner(self, other, first + 1, historybuf, (TrackCursor*)tcarr, as_ansi_buf);
|
||||||
*track_x = tcarr[0].x; *track_y = tcarr[0].y;
|
*track_x = tcarr[0].x; *track_y = tcarr[0].y;
|
||||||
|
*track_x2 = tcarr[1].x; *track_y2 = tcarr[1].y;
|
||||||
*num_content_lines_after = other->line->ynum + 1;
|
*num_content_lines_after = other->line->ynum + 1;
|
||||||
for (i = 0; i < *num_content_lines_after; i++) other->line_attrs[i] |= TEXT_DIRTY_MASK;
|
for (i = 0; i < *num_content_lines_after; i++) other->line_attrs[i] |= TEXT_DIRTY_MASK;
|
||||||
*num_content_lines_before = first + 1;
|
*num_content_lines_before = first + 1;
|
||||||
@ -589,9 +590,9 @@ rewrap(LineBuf *self, PyObject *args) {
|
|||||||
unsigned int nclb, ncla;
|
unsigned int nclb, ncla;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O!O!", &LineBuf_Type, &other, &HistoryBuf_Type, &historybuf)) return NULL;
|
if (!PyArg_ParseTuple(args, "O!O!", &LineBuf_Type, &other, &HistoryBuf_Type, &historybuf)) return NULL;
|
||||||
index_type x = 0, y = 0;
|
index_type x = 0, y = 0, x2 = 0, y2 = 0;
|
||||||
ANSIBuf as_ansi_buf = {0};
|
ANSIBuf as_ansi_buf = {0};
|
||||||
linebuf_rewrap(self, other, &nclb, &ncla, historybuf, &x, &y, &as_ansi_buf);
|
linebuf_rewrap(self, other, &nclb, &ncla, historybuf, &x, &y, &x2, &y2, &as_ansi_buf);
|
||||||
free(as_ansi_buf.buf);
|
free(as_ansi_buf.buf);
|
||||||
|
|
||||||
return Py_BuildValue("II", nclb, ncla);
|
return Py_BuildValue("II", nclb, ncla);
|
||||||
|
|||||||
@ -95,7 +95,7 @@ void linebuf_insert_lines(LineBuf *self, unsigned int num, unsigned int y, unsig
|
|||||||
void linebuf_delete_lines(LineBuf *self, index_type num, index_type y, index_type bottom);
|
void linebuf_delete_lines(LineBuf *self, index_type num, index_type y, index_type bottom);
|
||||||
void linebuf_copy_line_to(LineBuf *, Line *, index_type);
|
void linebuf_copy_line_to(LineBuf *, Line *, index_type);
|
||||||
void linebuf_set_attribute(LineBuf *, unsigned int , unsigned int );
|
void linebuf_set_attribute(LineBuf *, unsigned int , unsigned int );
|
||||||
void linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *, index_type *, HistoryBuf *, index_type *, index_type *, ANSIBuf*);
|
void linebuf_rewrap(LineBuf *self, LineBuf *other, index_type *, index_type *, HistoryBuf *, index_type *, index_type *, index_type *, index_type *, ANSIBuf*);
|
||||||
void linebuf_mark_line_dirty(LineBuf *self, index_type y);
|
void linebuf_mark_line_dirty(LineBuf *self, index_type y);
|
||||||
void linebuf_mark_line_clean(LineBuf *self, index_type y);
|
void linebuf_mark_line_clean(LineBuf *self, index_type y);
|
||||||
void linebuf_mark_line_as_not_continued(LineBuf *self, index_type y);
|
void linebuf_mark_line_as_not_continued(LineBuf *self, index_type y);
|
||||||
|
|||||||
@ -204,11 +204,22 @@ realloc_hb(HistoryBuf *old, unsigned int lines, unsigned int columns, ANSIBuf *a
|
|||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct CursorTrack {
|
||||||
|
index_type num_content_lines;
|
||||||
|
bool is_beyond_content;
|
||||||
|
struct { index_type x, y; } before;
|
||||||
|
struct { index_type x, y; } after;
|
||||||
|
struct { index_type x, y; } temp;
|
||||||
|
} CursorTrack;
|
||||||
|
|
||||||
static inline LineBuf*
|
static inline LineBuf*
|
||||||
realloc_lb(LineBuf *old, unsigned int lines, unsigned int columns, index_type *nclb, index_type *ncla, HistoryBuf *hb, index_type *x, index_type *y, ANSIBuf *as_ansi_buf) {
|
realloc_lb(LineBuf *old, unsigned int lines, unsigned int columns, index_type *nclb, index_type *ncla, HistoryBuf *hb, CursorTrack *a, CursorTrack *b, ANSIBuf *as_ansi_buf) {
|
||||||
LineBuf *ans = alloc_linebuf(lines, columns);
|
LineBuf *ans = alloc_linebuf(lines, columns);
|
||||||
if (ans == NULL) { PyErr_NoMemory(); return NULL; }
|
if (ans == NULL) { PyErr_NoMemory(); return NULL; }
|
||||||
linebuf_rewrap(old, ans, nclb, ncla, hb, x, y, as_ansi_buf);
|
a->temp.x = a->before.x; a->temp.y = a->before.y;
|
||||||
|
b->temp.x = b->before.x; b->temp.y = b->before.y;
|
||||||
|
linebuf_rewrap(old, ans, nclb, ncla, hb, &a->temp.x, &a->temp.y, &b->temp.x, &b->temp.y, as_ansi_buf);
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,21 +274,21 @@ index_selection(const Screen *self, Selections *selections, bool up) {
|
|||||||
self->is_dirty = true; \
|
self->is_dirty = true; \
|
||||||
index_selection(self, &self->selections, false);
|
index_selection(self, &self->selections, false);
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
||||||
if (self->overlay_line.is_active) deactivate_overlay_line(self);
|
if (self->overlay_line.is_active) deactivate_overlay_line(self);
|
||||||
lines = MAX(1u, lines); columns = MAX(1u, columns);
|
lines = MAX(1u, lines); columns = MAX(1u, columns);
|
||||||
|
|
||||||
bool is_main = self->linebuf == self->main_linebuf;
|
bool is_main = self->linebuf == self->main_linebuf;
|
||||||
index_type num_content_lines_before, num_content_lines_after, num_content_lines;
|
index_type num_content_lines_before, num_content_lines_after;
|
||||||
unsigned int cursor_x = 0, cursor_y = 0;
|
|
||||||
bool cursor_is_beyond_content = false;
|
|
||||||
unsigned int lines_after_cursor_before_resize = self->lines - self->cursor->y;
|
unsigned int lines_after_cursor_before_resize = self->lines - self->cursor->y;
|
||||||
#define setup_cursor() { \
|
CursorTrack cursor = {.before = {self->cursor->x, self->cursor->y}};
|
||||||
cursor_x = x; cursor_y = y; \
|
CursorTrack main_saved_cursor = {.before = {self->main_savepoint.cursor.x, self->main_savepoint.cursor.y}};
|
||||||
cursor_is_beyond_content = num_content_lines_before > 0 && self->cursor->y >= num_content_lines_before; \
|
CursorTrack alt_saved_cursor = {.before = {self->alt_savepoint.cursor.x, self->alt_savepoint.cursor.y}};
|
||||||
num_content_lines = num_content_lines_after; \
|
#define setup_cursor(which) { \
|
||||||
|
which.after.x = which.temp.x; which.after.y = which.temp.y; \
|
||||||
|
which.is_beyond_content = num_content_lines_before > 0 && self->cursor->y >= num_content_lines_before; \
|
||||||
|
which.num_content_lines = num_content_lines_after; \
|
||||||
}
|
}
|
||||||
// Resize overlay line
|
// Resize overlay line
|
||||||
if (!init_overlay_line(self, columns)) return false;
|
if (!init_overlay_line(self, columns)) return false;
|
||||||
@ -286,21 +297,19 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
|||||||
HistoryBuf *nh = realloc_hb(self->historybuf, self->historybuf->ynum, columns, &self->as_ansi_buf);
|
HistoryBuf *nh = realloc_hb(self->historybuf, self->historybuf->ynum, columns, &self->as_ansi_buf);
|
||||||
if (nh == NULL) return false;
|
if (nh == NULL) return false;
|
||||||
Py_CLEAR(self->historybuf); self->historybuf = nh;
|
Py_CLEAR(self->historybuf); self->historybuf = nh;
|
||||||
index_type x = self->cursor->x, y = self->cursor->y;
|
LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, self->historybuf, &cursor, &main_saved_cursor, &self->as_ansi_buf);
|
||||||
LineBuf *n = realloc_lb(self->main_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, self->historybuf, &x, &y, &self->as_ansi_buf);
|
|
||||||
if (n == NULL) return false;
|
if (n == NULL) return false;
|
||||||
|
|
||||||
|
|
||||||
Py_CLEAR(self->main_linebuf); self->main_linebuf = n;
|
Py_CLEAR(self->main_linebuf); self->main_linebuf = n;
|
||||||
if (is_main) setup_cursor();
|
if (is_main) setup_cursor(cursor);
|
||||||
|
setup_cursor(main_saved_cursor);
|
||||||
grman_resize(self->main_grman, self->lines, lines, self->columns, columns);
|
grman_resize(self->main_grman, self->lines, lines, self->columns, columns);
|
||||||
|
|
||||||
// Resize alt linebuf
|
// Resize alt linebuf
|
||||||
x = self->cursor->x, y = self->cursor->y;
|
n = realloc_lb(self->alt_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, NULL, &cursor, &alt_saved_cursor, &self->as_ansi_buf);
|
||||||
n = realloc_lb(self->alt_linebuf, lines, columns, &num_content_lines_before, &num_content_lines_after, NULL, &x, &y, &self->as_ansi_buf);
|
|
||||||
if (n == NULL) return false;
|
if (n == NULL) return false;
|
||||||
Py_CLEAR(self->alt_linebuf); self->alt_linebuf = n;
|
Py_CLEAR(self->alt_linebuf); self->alt_linebuf = n;
|
||||||
if (!is_main) setup_cursor();
|
if (!is_main) setup_cursor(cursor);
|
||||||
|
setup_cursor(alt_saved_cursor);
|
||||||
grman_resize(self->alt_grman, self->lines, lines, self->columns, columns);
|
grman_resize(self->alt_grman, self->lines, lines, self->columns, columns);
|
||||||
#undef setup_cursor
|
#undef setup_cursor
|
||||||
|
|
||||||
@ -320,19 +329,24 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
|
|||||||
clear_selection(&self->selections);
|
clear_selection(&self->selections);
|
||||||
clear_selection(&self->url_ranges);
|
clear_selection(&self->url_ranges);
|
||||||
/* 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); */
|
/* 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); */
|
||||||
self->cursor->x = MIN(cursor_x, self->columns - 1);
|
#define S(c, w) c->x = MIN(w.after.x, self->columns - 1); c->y = MIN(w.after.y, self->lines - 1);
|
||||||
self->cursor->y = MIN(cursor_y, self->lines - 1);
|
S(self->cursor, cursor);
|
||||||
if (cursor_is_beyond_content) {
|
S((&(self->main_savepoint.cursor)), main_saved_cursor);
|
||||||
self->cursor->y = num_content_lines;
|
S((&(self->alt_savepoint.cursor)), alt_saved_cursor);
|
||||||
|
#undef S
|
||||||
|
if (cursor.is_beyond_content) {
|
||||||
|
self->cursor->y = cursor.num_content_lines;
|
||||||
if (self->cursor->y >= self->lines) { self->cursor->y = self->lines - 1; screen_index(self); }
|
if (self->cursor->y >= self->lines) { self->cursor->y = self->lines - 1; screen_index(self); }
|
||||||
}
|
}
|
||||||
if (is_main && OPT(scrollback_fill_enlarged_window)) {
|
if (is_main && OPT(scrollback_fill_enlarged_window)) {
|
||||||
const unsigned int top = 0, bottom = self->lines-1;
|
const unsigned int top = 0, bottom = self->lines-1;
|
||||||
|
Savepoint *sp = is_main ? &self->main_savepoint : &self->alt_savepoint;
|
||||||
while (self->cursor->y + 1 < self->lines && self->lines - self->cursor->y > lines_after_cursor_before_resize) {
|
while (self->cursor->y + 1 < self->lines && self->lines - self->cursor->y > lines_after_cursor_before_resize) {
|
||||||
if (!historybuf_pop_line(self->historybuf, self->alt_linebuf->line)) break;
|
if (!historybuf_pop_line(self->historybuf, self->alt_linebuf->line)) break;
|
||||||
INDEX_DOWN;
|
INDEX_DOWN;
|
||||||
linebuf_copy_line_to(self->main_linebuf, self->alt_linebuf->line, 0);
|
linebuf_copy_line_to(self->main_linebuf, self->alt_linebuf->line, 0);
|
||||||
self->cursor->y++;
|
self->cursor->y++;
|
||||||
|
sp->cursor.y = MIN(sp->cursor.y + 1, self->lines - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user