summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2019-04-02 08:45:33 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2019-04-02 08:45:33 +0000
commit5ea38ce071eefcbbe25b2e24977eb1cd1c810c33 (patch)
tree27ba07e9dd1738c5455ad28b9d03986330955c75 /usr.bin
parent45df6659c1fb4e7220083ed979a7903080b2d308 (diff)
Store and restore cursor across reflow by working out a position based
on unwrapped lines, rather than a grid offset. Fixes problems reported by Thomas Sattler and Paul de Weerd.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/grid.c73
-rw-r--r--usr.bin/tmux/screen.c10
-rw-r--r--usr.bin/tmux/tmux.h6
3 files changed, 55 insertions, 34 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c
index e4edba4367b..47c5ded3f96 100644
--- a/usr.bin/tmux/grid.c
+++ b/usr.bin/tmux/grid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid.c,v 1.92 2019/04/01 19:33:38 nicm Exp $ */
+/* $OpenBSD: grid.c,v 1.93 2019/04/02 08:45:32 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1291,40 +1291,61 @@ grid_reflow(struct grid *gd, u_int sx)
free(target);
}
-/* Convert point position to offset from the start of the grid. */
-u_int
-grid_to_offset(struct grid *gd, u_int px, u_int py)
+/* Convert to position based on wrapped lines. */
+void
+grid_wrap_position(struct grid *gd, u_int px, u_int py, u_int *wx, u_int *wy)
{
- u_int yy, offset = 0;
-
- if (py > gd->hsize + gd->sy - 1) {
- px = UINT_MAX;
- py = gd->hsize + gd->sy - 1;
+ u_int ax = 0, ay = 0, yy;
+
+ for (yy = 0; yy < py; yy++) {
+ if (gd->linedata[yy].flags & GRID_LINE_WRAPPED)
+ ax += gd->linedata[yy].cellused;
+ else {
+ ax = 0;
+ ay++;
+ }
}
-
- for (yy = 0; yy < py; yy++)
- offset += gd->linedata[yy].cellused;
- if (px > gd->linedata[yy].cellused)
- px = gd->linedata[yy].cellused;
- return (offset + px);
+ if (px >= gd->linedata[yy].cellused)
+ ax = UINT_MAX;
+ else
+ ax += px;
+ *wx = ax;
+ *wy = ay;
}
-/* Convert offset from the start of the grid to point position. */
+/* Convert position based on wrapped lines back. */
void
-grid_from_offset(struct grid *gd, u_int offset, u_int *px, u_int *py)
+grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy)
{
- u_int yy;
-
- *px = *py = 0;
+ u_int yy, ax = 0, ay = 0;
for (yy = 0; yy < gd->hsize + gd->sy - 1; yy++) {
- if (offset <= gd->linedata[yy].cellused)
+ if (ay == wy)
break;
- offset -= gd->linedata[yy].cellused;
+ if (gd->linedata[yy].flags & GRID_LINE_WRAPPED)
+ ax += gd->linedata[yy].cellused;
+ else {
+ ax = 0;
+ ay++;
+ }
}
- if (offset < gd->linedata[yy].cellused)
- *px = offset;
- else
- *px = gd->linedata[yy].cellused;
+
+ /*
+ * yy is now 0 on the unwrapped line which contains wx. Walk forwards
+ * until we find the end or the line now containing wx.
+ */
+ if (wx == UINT_MAX) {
+ while (gd->linedata[yy].flags & GRID_LINE_WRAPPED)
+ yy++;
+ wx = gd->linedata[yy].cellused;
+ } else {
+ while (gd->linedata[yy].flags & GRID_LINE_WRAPPED) {
+ if (wx < gd->linedata[yy].cellused)
+ break;
+ wx -= gd->linedata[yy].cellused;
+ yy++;
+ }
+ }
+ *px = wx;
*py = yy;
}
diff --git a/usr.bin/tmux/screen.c b/usr.bin/tmux/screen.c
index 14872531dba..a0bb5bb639e 100644
--- a/usr.bin/tmux/screen.c
+++ b/usr.bin/tmux/screen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen.c,v 1.54 2019/03/20 19:19:11 nicm Exp $ */
+/* $OpenBSD: screen.c,v 1.55 2019/04/02 08:45:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -464,17 +464,17 @@ screen_select_cell(struct screen *s, struct grid_cell *dst,
static void
screen_reflow(struct screen *s, u_int new_x)
{
- u_int offset, cx = s->cx, cy = s->grid->hsize + s->cy;
+ u_int cx = s->cx, cy = s->grid->hsize + s->cy, wx, wy;
struct timeval start, tv;
gettimeofday(&start, NULL);
- offset = grid_to_offset(s->grid, cx, cy);
- log_debug("%s: cursor %u,%u offset is %u", __func__, cx, cy, offset);
+ 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_from_offset(s->grid, offset, &cx, &cy);
+ grid_unwrap_position(s->grid, &cx, &cy, wx, wy);
log_debug("%s: new cursor is %u,%u", __func__, cx, cy);
if (cy >= s->grid->hsize) {
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 86f5a58b8f6..750ac755722 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.877 2019/03/25 18:59:55 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.878 2019/04/02 08:45:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -2101,8 +2101,8 @@ char *grid_string_cells(struct grid *, u_int, u_int, u_int,
void grid_duplicate_lines(struct grid *, u_int, struct grid *, u_int,
u_int);
void grid_reflow(struct grid *, u_int);
-u_int grid_to_offset(struct grid *, u_int, u_int);
-void grid_from_offset(struct grid *, u_int, u_int *, u_int *);
+void grid_wrap_position(struct grid *, u_int, u_int, u_int *, u_int *);
+void grid_unwrap_position(struct grid *, u_int *, u_int *, u_int, u_int);
/* grid-view.c */
void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);