summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2020-05-16 15:49:21 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2020-05-16 15:49:21 +0000
commitbdaee778bc193eeb3f3772c21c3ec29ed9608370 (patch)
tree727d1360e562d4aab132bb022d6333fb2a83f76e /usr.bin
parent6b5c6560df7d128b699f34104b5af425a531e724 (diff)
Store and restore cursor position when copy mode is resized, from
Anindya Mukherjee.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/grid.c4
-rw-r--r--usr.bin/tmux/screen.c54
-rw-r--r--usr.bin/tmux/tmux.h5
-rw-r--r--usr.bin/tmux/window-copy.c57
4 files changed, 75 insertions, 45 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c
index 1141e6c9220..6495da31f22 100644
--- a/usr.bin/tmux/grid.c
+++ b/usr.bin/tmux/grid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid.c,v 1.107 2020/05/16 14:53:23 nicm Exp $ */
+/* $OpenBSD: grid.c,v 1.108 2020/05/16 15:49:20 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1285,7 +1285,7 @@ grid_reflow(struct grid *gd, u_int sx)
/*
* If the line is exactly right or the first character is wider
- * than the targe width, just move it across unchanged.
+ * than the target width, just move it across unchanged.
*/
if (width == sx || first > sx) {
grid_reflow_move(target, gl);
diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c
index c8404e917f8..48bf924b69c 100644
--- a/usr.bin/tmux/screen.c
+++ b/usr.bin/tmux/screen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.66 2020/04/22 08:48:44 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.67 2020/05/16 15:49:20 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -49,7 +49,7 @@ struct screen_title_entry {
TAILQ_HEAD(screen_titles, screen_title_entry);
static void screen_resize_y(struct screen *, u_int, int, u_int *);
-static void screen_reflow(struct screen *, u_int, u_int *, u_int *);
+static void screen_reflow(struct screen *, u_int, u_int *, u_int *, int);
/* Free titles stack. */
static void
@@ -220,27 +220,19 @@ screen_pop_title(struct screen *s)
}
}
-/* Resize screen and return cursor position. */
+/* Resize screen with options. */
void
screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
- int eat_empty, u_int *cx, u_int *cy)
+ int eat_empty, int cursor)
{
- u_int tcx, tcy;
+ u_int cx = s->cx, cy = s->grid->hsize + s->cy;
if (s->write_list != NULL)
screen_write_free_list(s);
- if (cx == NULL)
- cx = &tcx;
- *cx = s->cx;
-
- if (cy == NULL)
- cy = &tcy;
- *cy = s->grid->hsize + s->cy;
-
log_debug("%s: new size %ux%u, now %ux%u (cursor %u,%u = %u,%u)",
__func__, sx, sy, screen_size_x(s), screen_size_y(s), s->cx, s->cy,
- *cx, *cy);
+ cx, cy);
if (sx < 1)
sx = 1;
@@ -254,20 +246,21 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
reflow = 0;
if (sy != screen_size_y(s))
- screen_resize_y(s, sy, eat_empty, cy);
+ screen_resize_y(s, sy, eat_empty, &cy);
if (reflow)
- screen_reflow(s, sx, cx, cy);
+ screen_reflow(s, sx, &cx, &cy, cursor);
- if (*cy >= s->grid->hsize) {
- s->cx = *cx;
- s->cy = (*cy) - s->grid->hsize;
+ if (cy >= s->grid->hsize) {
+ s->cx = cx;
+ s->cy = cy - s->grid->hsize;
} else {
s->cx = 0;
s->cy = 0;
}
+
log_debug("%s: cursor finished at %u,%u = %u,%u", __func__, s->cx,
- s->cy, *cx, *cy);
+ s->cy, cx, cy);
if (s->write_list != NULL)
screen_write_make_list(s);
@@ -277,7 +270,7 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
void
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
{
- screen_resize_cursor(s, sx, sy, reflow, 1, NULL, NULL);
+ screen_resize_cursor(s, sx, sy, reflow, 1, 1);
}
static void
@@ -525,17 +518,26 @@ screen_select_cell(struct screen *s, struct grid_cell *dst,
/* Reflow wrapped lines. */
static void
-screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy)
+screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy, int cursor)
{
u_int wx, wy;
- grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
- log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx, wy);
+ if (cursor) {
+ grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
+ log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx,
+ wy);
+ }
grid_reflow(s->grid, new_x);
- grid_unwrap_position(s->grid, cx, cy, wx, wy);
- log_debug("%s: new cursor is %u,%u", __func__, *cx,* cy);
+ if (cursor) {
+ grid_unwrap_position(s->grid, cx, cy, wx, wy);
+ log_debug("%s: new cursor is %u,%u", __func__, *cx, *cy);
+ }
+ else {
+ *cx = 0;
+ *cy = s->grid->hsize;
+ }
}
/*
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 426025f92f7..17674a7fff4 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1034 2020/05/16 15:47:22 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1035 2020/05/16 15:49:20 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -2529,8 +2529,7 @@ void screen_set_path(struct screen *, const char *);
void screen_push_title(struct screen *);
void screen_pop_title(struct screen *);
void screen_resize(struct screen *, u_int, u_int, int);
-void screen_resize_cursor(struct screen *, u_int, u_int, int, int, u_int *,
- u_int *);
+void screen_resize_cursor(struct screen *, u_int, u_int, int, int, int);
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
u_int, int, struct grid_cell *);
void screen_clear_selection(struct screen *);
diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c
index 03360a645b9..02d7738d419 100644
--- a/usr.bin/tmux/window-copy.c
+++ b/usr.bin/tmux/window-copy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-copy.c,v 1.284 2020/05/16 15:38:14 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.285 2020/05/16 15:49:20 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -306,8 +306,9 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
u_int *cy, int trim)
{
struct screen *dst;
- u_int sy;
const struct grid_line *gl;
+ u_int sy, wx, wy;
+ int reflow;
dst = xcalloc(1, sizeof *dst);
@@ -324,6 +325,12 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
screen_size_x(src), sy, screen_size_x(hint),
screen_hsize(src) + screen_size_y(src));
screen_init(dst, screen_size_x(src), sy, screen_hlimit(src));
+
+ /*
+ * Ensure history is on for the backing grid so lines are not deleted
+ * during resizing.
+ */
+ dst->grid->flags |= GRID_HISTORY;
grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
dst->grid->sy = sy - screen_hsize(src);
@@ -337,8 +344,19 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
dst->cy = src->cy;
}
+ if (cx != NULL && cy != NULL) {
+ *cx = dst->cx;
+ *cy = screen_hsize(dst) + dst->cy;
+ reflow = (screen_size_x(hint) != screen_size_x(dst));
+ }
+ else
+ reflow = 0;
+ if (reflow)
+ grid_wrap_position(dst->grid, *cx, *cy, &wx, &wy);
screen_resize_cursor(dst, screen_size_x(hint), screen_size_y(hint), 1,
- 0, cx, cy);
+ 0, 0);
+ if (reflow)
+ grid_unwrap_position(dst->grid, cx, cy, wx, wy);
return (dst);
}
@@ -392,13 +410,12 @@ window_copy_init(struct window_mode_entry *wme,
data->backing = window_copy_clone_screen(base, &data->screen, &cx, &cy,
wme->swp != wme->wp);
+ data->cx = cx;
if (cy < screen_hsize(data->backing)) {
- data->cx = cx;
data->cy = 0;
data->oy = screen_hsize(data->backing) - cy;
} else {
- data->cx = data->backing->cx;
- data->cy = data->backing->cy;
+ data->cy = cy - screen_hsize(data->backing);
data->oy = 0;
}
@@ -731,16 +748,28 @@ window_copy_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
{
struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen;
+ struct grid *gd = data->backing->grid;
+ u_int cx, cy, wx, wy;
+ int reflow;
screen_resize(s, sx, sy, 0);
- screen_resize_cursor(data->backing, sx, sy, 1, 0, NULL, NULL);
-
- if (data->cy > sy - 1)
- data->cy = sy - 1;
- if (data->cx > sx)
- data->cx = sx;
- if (data->oy > screen_hsize(data->backing))
- data->oy = screen_hsize(data->backing);
+ cx = data->cx;
+ cy = gd->hsize + data->cy - data->oy;
+ reflow = (gd->sx != sx);
+ if (reflow)
+ grid_wrap_position(gd, cx, cy, &wx, &wy);
+ screen_resize_cursor(data->backing, sx, sy, 1, 0, 0);
+ if (reflow)
+ grid_unwrap_position(gd, &cx, &cy, wx, wy);
+
+ data->cx = cx;
+ if (cy < gd->hsize) {
+ data->cy = 0;
+ data->oy = gd->hsize - cy;
+ } else {
+ data->cy = cy - gd->hsize;
+ data->oy = 0;
+ }
window_copy_size_changed(wme);
window_copy_redraw_screen(wme);