Horizontal history/scrolling.

This commit is contained in:
Nicholas Marriott 2007-11-21 15:35:53 +00:00
parent e4f01009a3
commit d5edaf988e
6 changed files with 88 additions and 45 deletions

View File

@ -1,5 +1,6 @@
21 November 2007 21 November 2007
* Full line width memory and horizontal scrolling in history.
* Initial support for scroll history. = to enter scrolling mode, and then * Initial support for scroll history. = to enter scrolling mode, and then
vi keys or up/down/pgup/pgdown to navigate. Q to exit. No horizontal history vi keys or up/down/pgup/pgdown to navigate. Q to exit. No horizontal history
yet (need per-line sizes) and a few kinks to be worked out (resizing while in yet (need per-line sizes) and a few kinks to be worked out (resizing while in
@ -240,4 +241,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.76 2007-11-21 13:11:41 nicm Exp $ $Id: CHANGES,v 1.77 2007-11-21 15:35:53 nicm Exp $

View File

@ -1,4 +1,4 @@
/* $Id: screen-display.c,v 1.2 2007-11-21 13:11:41 nicm Exp $ */ /* $Id: screen-display.c,v 1.3 2007-11-21 15:35:53 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -193,6 +193,8 @@ screen_display_scroll_region_up(struct screen *s)
s->grid_attr, sy + 1, sizeof *s->grid_attr); s->grid_attr, sy + 1, sizeof *s->grid_attr);
s->grid_colr = xrealloc( s->grid_colr = xrealloc(
s->grid_colr, sy + 1, sizeof *s->grid_colr); s->grid_colr, sy + 1, sizeof *s->grid_colr);
s->grid_size = xrealloc(
s->grid_size, sy + 1, sizeof *s->grid_size);
} }
screen_display_make_lines(s, screen_last_y(s), 1); screen_display_make_lines(s, screen_last_y(s), 1);
return; return;

View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.30 2007-11-21 14:55:31 nicm Exp $ */ /* $Id: screen.c,v 1.31 2007-11-21 15:35:53 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -102,6 +102,7 @@ screen_create(struct screen *s, u_int dx, u_int dy)
s->grid_data = xmalloc(dy * (sizeof *s->grid_data)); s->grid_data = xmalloc(dy * (sizeof *s->grid_data));
s->grid_attr = xmalloc(dy * (sizeof *s->grid_attr)); s->grid_attr = xmalloc(dy * (sizeof *s->grid_attr));
s->grid_colr = xmalloc(dy * (sizeof *s->grid_colr)); s->grid_colr = xmalloc(dy * (sizeof *s->grid_colr));
s->grid_size = xmalloc(dy * (sizeof *s->grid_size));
screen_make_lines(s, 0, dy); screen_make_lines(s, 0, dy);
} }
@ -125,12 +126,17 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
* X dimension. * X dimension.
*/ */
if (sx != ox) { if (sx != ox) {
/* Resize all lines including history. */ /* Resize on-screen lines. */
/* XXX need per-line sizes! */ for (i = s->hsize; i < s->hsize + oy; i++) {
for (i = 0; i < s->hsize + oy; i++) { if (sx > s->grid_size[i]) {
s->grid_data[i] = xrealloc(s->grid_data[i], sx, 1); s->grid_data[i] =
s->grid_attr[i] = xrealloc(s->grid_attr[i], sx, 1); xrealloc(s->grid_data[i], sx, 1);
s->grid_colr[i] = xrealloc(s->grid_colr[i], sx, 1); s->grid_attr[i] =
xrealloc(s->grid_attr[i], sx, 1);
s->grid_colr[i] =
xrealloc(s->grid_colr[i], sx, 1);
s->grid_size[i] = sx;
}
if (sx > ox) { if (sx > ox) {
screen_fill_cells(s, ox, i, sx - ox, screen_fill_cells(s, ox, i, sx - ox,
SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFDATA, SCREEN_DEFATTR,
@ -184,6 +190,7 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
s->grid_data = xrealloc(s->grid_data, ny, sizeof *s->grid_data); s->grid_data = xrealloc(s->grid_data, ny, sizeof *s->grid_data);
s->grid_attr = xrealloc(s->grid_attr, ny, sizeof *s->grid_attr); s->grid_attr = xrealloc(s->grid_attr, ny, sizeof *s->grid_attr);
s->grid_colr = xrealloc(s->grid_colr, ny, sizeof *s->grid_colr); s->grid_colr = xrealloc(s->grid_colr, ny, sizeof *s->grid_colr);
s->grid_size = xrealloc(s->grid_size, ny, sizeof *s->grid_size);
s->dy = sy; s->dy = sy;
/* Size increasing. */ /* Size increasing. */
@ -202,14 +209,16 @@ screen_destroy(struct screen *s)
xfree(s->grid_data); xfree(s->grid_data);
xfree(s->grid_attr); xfree(s->grid_attr);
xfree(s->grid_colr); xfree(s->grid_colr);
xfree(s->grid_size);
} }
/* Draw a set of lines on the screen. */ /* Draw a set of lines on the screen. */
void void
screen_draw(struct screen *s, struct buffer *b, u_int py, u_int ny, u_int off) screen_draw(
struct screen *s, struct buffer *b, u_int py, u_int ny, u_int ox, u_int oy)
{ {
u_char attr, colr; u_char attr, colr;
u_int i, j, base; u_int i, j, nx, base;
/* XXX. This is naive and rough right now. */ /* XXX. This is naive and rough right now. */
attr = 0; attr = 0;
@ -221,24 +230,33 @@ screen_draw(struct screen *s, struct buffer *b, u_int py, u_int ny, u_int off)
input_store_two(b, CODE_ATTRIBUTES, attr, colr); input_store_two(b, CODE_ATTRIBUTES, attr, colr);
base = screen_y(s, 0); base = screen_y(s, 0);
if (off > base) if (oy > base)
base = 0; base = 0;
else else
base -= off; base -= oy;
for (j = py; j < py + ny; j++) { for (j = py; j < py + ny; j++) {
input_store_two(b, CODE_CURSORMOVE, j + 1, 1); input_store_two(b, CODE_CURSORMOVE, j + 1, 1);
for (i = 0; i <= screen_last_x(s); i++) { nx = s->grid_size[base + j] - ox;
if (s->grid_attr[base + j][i] != attr || if (nx > screen_size_x(s))
s->grid_colr[base + j][i] != colr) { nx = screen_size_x(s);
for (i = 0; i < nx; i++) {
if (s->grid_attr[base + j][ox + i] != attr ||
s->grid_colr[base + j][ox + i] != colr) {
input_store_two(b, CODE_ATTRIBUTES, input_store_two(b, CODE_ATTRIBUTES,
s->grid_attr[base + j][i], s->grid_attr[base + j][ox + i],
s->grid_colr[base + j][i]); s->grid_colr[base + j][ox + i]);
attr = s->grid_attr[base + j][i]; attr = s->grid_attr[base + j][ox + i];
colr = s->grid_colr[base + j][i]; colr = s->grid_colr[base + j][ox + i];
} }
input_store8(b, s->grid_data[base + j][i]); input_store8(b, s->grid_data[base + j][ox + i]);
}
if (nx != screen_size_x(s)) {
input_store_two(
b, CODE_ATTRIBUTES, SCREEN_DEFATTR, SCREEN_DEFCOLR);
for (i = nx; i < screen_size_x(s); i++)
input_store8(b, SCREEN_DEFDATA);
} }
} }
input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1); input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
@ -258,6 +276,7 @@ screen_make_lines(struct screen *s, u_int py, u_int ny)
s->grid_data[i] = xmalloc(s->dx); s->grid_data[i] = xmalloc(s->dx);
s->grid_attr[i] = xmalloc(s->dx); s->grid_attr[i] = xmalloc(s->dx);
s->grid_colr[i] = xmalloc(s->dx); s->grid_colr[i] = xmalloc(s->dx);
s->grid_size[i] = s->dx;
} }
screen_fill_lines( screen_fill_lines(
s, py, ny, SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFCOLR); s, py, ny, SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFCOLR);
@ -274,6 +293,7 @@ screen_free_lines(struct screen *s, u_int py, u_int ny)
xfree(s->grid_data[i]); xfree(s->grid_data[i]);
xfree(s->grid_attr[i]); xfree(s->grid_attr[i]);
xfree(s->grid_colr[i]); xfree(s->grid_colr[i]);
s->grid_size[i] = 0;
} }
} }
@ -287,6 +307,8 @@ screen_move_lines(struct screen *s, u_int dy, u_int py, u_int ny)
&s->grid_attr[dy], &s->grid_attr[py], ny * (sizeof *s->grid_attr)); &s->grid_attr[dy], &s->grid_attr[py], ny * (sizeof *s->grid_attr));
memmove( memmove(
&s->grid_colr[dy], &s->grid_colr[py], ny * (sizeof *s->grid_colr)); &s->grid_colr[dy], &s->grid_colr[py], ny * (sizeof *s->grid_colr));
memmove(
&s->grid_size[dy], &s->grid_size[py], ny * (sizeof *s->grid_size));
} }
/* Fill a range of lines. */ /* Fill a range of lines. */

6
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.86 2007-11-21 14:01:53 nicm Exp $ */ /* $Id: tmux.h,v 1.87 2007-11-21 15:35:53 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -354,6 +354,7 @@ struct screen {
u_char **grid_data; u_char **grid_data;
u_char **grid_attr; u_char **grid_attr;
u_char **grid_colr; u_char **grid_colr;
u_int *grid_size;
u_int dx; /* display x size */ u_int dx; /* display x size */
u_int dy; /* display y size */ u_int dy; /* display y size */
@ -748,7 +749,8 @@ u_char screen_stringcolour(const char *);
void screen_create(struct screen *, u_int, u_int); void screen_create(struct screen *, u_int, u_int);
void screen_destroy(struct screen *); void screen_destroy(struct screen *);
void screen_resize(struct screen *, u_int, u_int); void screen_resize(struct screen *, u_int, u_int);
void screen_draw(struct screen *, struct buffer *, u_int, u_int, u_int); void screen_draw(
struct screen *, struct buffer *, u_int, u_int, u_int, u_int);
void screen_make_lines(struct screen *, u_int, u_int); void screen_make_lines(struct screen *, u_int, u_int);
void screen_free_lines(struct screen *, u_int, u_int); void screen_free_lines(struct screen *, u_int, u_int);
void screen_move_lines(struct screen *, u_int, u_int, u_int); void screen_move_lines(struct screen *, u_int, u_int, u_int);

View File

@ -1,4 +1,4 @@
/* $Id: window-scroll.c,v 1.4 2007-11-21 14:57:08 nicm Exp $ */ /* $Id: window-scroll.c,v 1.5 2007-11-21 15:35:53 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -33,7 +33,8 @@ const struct window_mode window_scroll_mode = {
}; };
struct window_scroll_mode_data { struct window_scroll_mode_data {
u_int off; u_int ox;
u_int oy;
u_int size; u_int size;
}; };
@ -43,7 +44,7 @@ window_scroll_init(struct window *w)
struct window_scroll_mode_data *data; struct window_scroll_mode_data *data;
w->modedata = data = xmalloc(sizeof *data); w->modedata = data = xmalloc(sizeof *data);
data->off = 0; data->ox = data->oy = 0;
data->size = w->screen.hsize; data->size = w->screen.hsize;
} }
@ -61,19 +62,19 @@ window_scroll_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
size_t len; size_t len;
if (s->hsize != data->size) { if (s->hsize != data->size) {
data->off += s->hsize - data->size; data->ox += s->hsize - data->size;
data->size = s->hsize; data->size = s->hsize;
} }
screen_draw(s, b, py, ny, data->off); screen_draw(s, b, py, ny, data->ox, data->oy);
input_store_zero(b, CODE_CURSOROFF); input_store_zero(b, CODE_CURSOROFF);
if (py == 0 && ny > 0) { if (py == 0 && ny > 0) {
len = screen_size_x(s); len = screen_size_x(s);
if (len > (sizeof buf) - 1) if (len > (sizeof buf) - 1)
len = (sizeof buf) - 1; len = (sizeof buf) - 1;
len = xsnprintf(buf, len + 1, "{%u/%u}", len = xsnprintf(
data->off, s->hsize); buf, len + 1, "[%u,%u/%u]", data->ox, data->oy, s->hsize);
input_store_two( input_store_two(
b, CODE_CURSORMOVE, 0, screen_size_x(s) - len + 1); b, CODE_CURSORMOVE, 0, screen_size_x(s) - len + 1);
@ -86,9 +87,14 @@ void
window_scroll_key(struct window *w, int key) window_scroll_key(struct window *w, int key)
{ {
struct window_scroll_mode_data *data = w->modedata; struct window_scroll_mode_data *data = w->modedata;
u_int off, sy = screen_size_y(&w->screen); u_int ox, oy, sx, sy;
sx = screen_size_x(&w->screen);
sy = screen_size_y(&w->screen);
ox = data->ox;
oy = data->oy;
off = data->off;
switch (key) { switch (key) {
case 'Q': case 'Q':
case 'q': case 'q':
@ -98,33 +104,43 @@ window_scroll_key(struct window *w, int key)
recalculate_sizes(); recalculate_sizes();
server_redraw_window_all(w); server_redraw_window_all(w);
return; return;
case 'h':
case KEYC_LEFT:
if (data->ox > 0)
data->ox--;
break;
case 'l':
case KEYC_RIGHT:
if (data->ox < SHRT_MAX)
data->ox++;
break;
case 'k': case 'k':
case 'K': case 'K':
case KEYC_UP: case KEYC_UP:
if (data->off < data->size) if (data->oy < data->size)
data->off++; data->oy++;
break; break;
case 'j': case 'j':
case 'J': case 'J':
case KEYC_DOWN: case KEYC_DOWN:
if (data->off > 0) if (data->oy > 0)
data->off--; data->oy--;
break; break;
case '\025': case '\025':
case KEYC_PPAGE: case KEYC_PPAGE:
if (data->off + sy > data->size) if (data->oy + sy > data->size)
data->off = data->size; data->oy = data->size;
else else
data->off += sy; data->oy += sy;
break; break;
case '\006': case '\006':
case KEYC_NPAGE: case KEYC_NPAGE:
if (data->off < sy) if (data->oy < sy)
data->off = 0; data->oy = 0;
else else
data->off -= sy; data->oy -= sy;
break; break;
} }
if (off != data->off) if (ox != data->ox || oy != data->oy)
server_redraw_window_all(w); server_redraw_window_all(w);
} }

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.28 2007-11-21 13:11:41 nicm Exp $ */ /* $Id: window.c,v 1.29 2007-11-21 15:35:53 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -287,7 +287,7 @@ window_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
if (w->mode != NULL) if (w->mode != NULL)
w->mode->draw(w, b, py, ny); w->mode->draw(w, b, py, ny);
else else
screen_draw(&w->screen, b, py, ny, 0); screen_draw(&w->screen, b, py, ny, 0, 0);
} }
void void