Automatically reflow wrapped lines when a pane is resized, requested by

many over the years and finally implemented by Richard Woodbury.
pull/1/head
Nicholas Marriott 2013-02-05 11:08:59 +00:00
parent a5521597b0
commit 8903c1f167
7 changed files with 71 additions and 10 deletions

41
grid.c
View File

@ -460,3 +460,44 @@ grid_duplicate_lines(
dy++;
}
}
/*
* Reflow lines from src grid into dst grid based on width sx. Returns number
* of lines fewer in the visible area, or zero.
*/
u_int
grid_reflow(struct grid *dst, const struct grid *src, u_int sx)
{
u_int px, py, line, cell;
int previous_wrapped;
struct grid_line *gl;
px = py = 0;
previous_wrapped = 1;
for (line = 0; line < src->sy + src->hsize; line++) {
gl = src->linedata + line;
if (!previous_wrapped) {
px = 0;
py++;
if (py >= dst->hsize + dst->sy)
grid_scroll_history(dst);
}
for (cell = 0; cell < gl->cellsize; cell++) {
if (px == sx) {
dst->linedata[py].flags |= GRID_LINE_WRAPPED;
px = 0;
py++;
if (py >= dst->hsize + dst->sy)
grid_scroll_history(dst);
}
grid_set_cell(dst, px, py, gl->celldata + cell);
px++;
}
previous_wrapped = gl->flags & GRID_LINE_WRAPPED;
}
py++; /* account for final line, which never wraps */
if (py > src->sy)
return (0);
return (src->sy - py);
}

View File

@ -120,7 +120,7 @@ screen_set_title(struct screen *s, const char *title)
/* Resize screen. */
void
screen_resize(struct screen *s, u_int sx, u_int sy)
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
{
if (sx < 1)
sx = 1;
@ -140,6 +140,9 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
if (sy != screen_size_y(s))
screen_resize_y(s, sy);
if (reflow)
screen_reflow(s, sx);
}
void
@ -356,3 +359,18 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
return (1);
}
/* Reflow wrapped lines. */
void
screen_reflow(struct screen *s, u_int sx)
{
struct grid *old, *new;
old = s->grid;
new = grid_create(old->sx, old->sy, old->hlimit);
s->cy -= grid_reflow(new, old, sx);
s->grid = new;
grid_destroy(old);
}

4
tmux.h
View File

@ -1964,6 +1964,7 @@ void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int);
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);
u_int grid_reflow(struct grid *, const struct grid *, u_int);
/* grid-cell.c */
u_int grid_cell_width(const struct grid_cell *);
@ -2057,11 +2058,12 @@ void screen_reset_tabs(struct screen *);
void screen_set_cursor_style(struct screen *, u_int);
void screen_set_cursor_colour(struct screen *, const char *);
void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int);
void screen_resize(struct screen *, u_int, u_int, int);
void screen_set_selection(struct screen *,
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
void screen_reflow(struct screen *, u_int);
/* window.c */
extern struct windows windows;

View File

@ -203,7 +203,7 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy)
if (data->selected > sy - 1)
data->top = data->selected - (sy - 1);
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
window_choose_redraw_screen(wp);
}

View File

@ -79,7 +79,7 @@ window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
struct window_clock_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
window_clock_draw_screen(wp);
}

View File

@ -335,9 +335,9 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
if (data->backing != &wp->base)
screen_resize(data->backing, sx, sy);
screen_resize(data->backing, sx, sy, 0);
if (data->cy > sy - 1)
data->cy = sy - 1;

View File

@ -853,7 +853,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
ws.ws_col = sx;
ws.ws_row = sy;
screen_resize(&wp->base, sx, sy);
screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
if (wp->mode != NULL)
wp->mode->resize(wp, sx, sy);
@ -914,7 +914,7 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
* before copying back.
*/
if (sy > wp->saved_grid->sy)
screen_resize(s, sx, wp->saved_grid->sy);
screen_resize(s, sx, wp->saved_grid->sy, 1);
/* Restore the grid, cursor position and cell. */
grid_duplicate_lines(s->grid, screen_hsize(s), wp->saved_grid, 0, sy);
@ -933,8 +933,8 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
* the current size.
*/
wp->base.grid->flags |= GRID_HISTORY;
if (sy > wp->saved_grid->sy)
screen_resize(s, sx, sy);
if (sy > wp->saved_grid->sy || sx != wp->saved_grid->sx)
screen_resize(s, sx, sy, 1);
grid_destroy(wp->saved_grid);
wp->saved_grid = NULL;