mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Horizontal history/scrolling.
This commit is contained in:
		
							
								
								
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -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 $ | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								screen.c
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -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); | ||||||
|   | |||||||
| @@ -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); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								window.c
									
									
									
									
									
								
							| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott