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 | ||||
|  | ||||
| * Full line width memory and horizontal scrolling in history. | ||||
| * 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 | ||||
|   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 | ||||
|   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> | ||||
| @@ -193,6 +193,8 @@ screen_display_scroll_region_up(struct screen *s) | ||||
| 			    s->grid_attr, sy + 1, sizeof *s->grid_attr); | ||||
| 			s->grid_colr = xrealloc( | ||||
| 			    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); | ||||
| 		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> | ||||
| @@ -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_attr = xmalloc(dy * (sizeof *s->grid_attr)); | ||||
| 	s->grid_colr = xmalloc(dy * (sizeof *s->grid_colr)); | ||||
| 	s->grid_size = xmalloc(dy * (sizeof *s->grid_size)); | ||||
| 	screen_make_lines(s, 0, dy); | ||||
| } | ||||
|  | ||||
| @@ -125,12 +126,17 @@ screen_resize(struct screen *s, u_int sx, u_int sy) | ||||
| 	 * X dimension. | ||||
| 	 */ | ||||
| 	if (sx != ox) { | ||||
| 		/* Resize all lines including history. */ | ||||
| 		/* XXX need per-line sizes! */ | ||||
| 		for (i = 0; i < s->hsize + oy; i++) { | ||||
| 			s->grid_data[i] = xrealloc(s->grid_data[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); | ||||
| 		/* Resize on-screen lines. */ | ||||
| 		for (i = s->hsize; i < s->hsize + oy; i++) { | ||||
| 			if (sx > s->grid_size[i]) { | ||||
| 				s->grid_data[i] =  | ||||
| 				    xrealloc(s->grid_data[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) { | ||||
| 				screen_fill_cells(s, ox, i, sx - ox, | ||||
| 				    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_attr = xrealloc(s->grid_attr, ny, sizeof *s->grid_attr); | ||||
| 	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; | ||||
|  | ||||
| 	/* Size increasing. */ | ||||
| @@ -202,14 +209,16 @@ screen_destroy(struct screen *s) | ||||
| 	xfree(s->grid_data); | ||||
| 	xfree(s->grid_attr); | ||||
| 	xfree(s->grid_colr); | ||||
| 	xfree(s->grid_size); | ||||
| } | ||||
|  | ||||
| /* Draw a set of lines on the screen. */ | ||||
| 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_int	 i, j, base; | ||||
| 	u_int	 i, j, nx, base; | ||||
|  | ||||
| 	/* XXX. This is naive and rough right now. */ | ||||
| 	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); | ||||
|  | ||||
| 	base = screen_y(s, 0); | ||||
| 	if (off > base) | ||||
| 	if (oy > base) | ||||
| 		base = 0; | ||||
| 	else | ||||
| 		base -= off; | ||||
| 		base -= oy; | ||||
|  | ||||
| 	for (j = py; j < py + ny; j++) { | ||||
| 		input_store_two(b, CODE_CURSORMOVE, j + 1, 1); | ||||
|  | ||||
| 		for (i = 0; i <= screen_last_x(s); i++) { | ||||
| 			if (s->grid_attr[base + j][i] != attr || | ||||
| 			    s->grid_colr[base + j][i] != colr) { | ||||
| 		nx = s->grid_size[base + j] - ox; | ||||
| 		if (nx > screen_size_x(s)) | ||||
| 			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, | ||||
| 				    s->grid_attr[base + j][i], | ||||
| 				    s->grid_colr[base + j][i]); | ||||
| 				attr = s->grid_attr[base + j][i]; | ||||
| 				colr = s->grid_colr[base + j][i]; | ||||
| 				    s->grid_attr[base + j][ox + i], | ||||
| 				    s->grid_colr[base + j][ox + i]); | ||||
| 				attr = s->grid_attr[base + j][ox + 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); | ||||
| @@ -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_attr[i] = xmalloc(s->dx); | ||||
| 		s->grid_colr[i] = xmalloc(s->dx); | ||||
| 		s->grid_size[i] = s->dx; | ||||
| 	} | ||||
| 	screen_fill_lines( | ||||
| 	    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_attr[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)); | ||||
| 	memmove( | ||||
| 	    &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. */ | ||||
|   | ||||
							
								
								
									
										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> | ||||
| @@ -354,6 +354,7 @@ struct screen { | ||||
| 	u_char	       **grid_data; | ||||
| 	u_char	       **grid_attr; | ||||
| 	u_char	       **grid_colr; | ||||
| 	u_int		*grid_size; | ||||
|  | ||||
|  	u_int		 dx;		/* display x 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_destroy(struct screen *); | ||||
| 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_free_lines(struct screen *, 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> | ||||
| @@ -33,7 +33,8 @@ const struct window_mode window_scroll_mode = { | ||||
| }; | ||||
|  | ||||
| struct window_scroll_mode_data { | ||||
| 	u_int	off; | ||||
| 	u_int	ox; | ||||
| 	u_int	oy; | ||||
| 	u_int	size; | ||||
| }; | ||||
|  | ||||
| @@ -43,7 +44,7 @@ window_scroll_init(struct window *w) | ||||
| 	struct window_scroll_mode_data	*data; | ||||
|  | ||||
| 	w->modedata = data = xmalloc(sizeof *data); | ||||
| 	data->off = 0; | ||||
| 	data->ox = data->oy = 0; | ||||
| 	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; | ||||
|  | ||||
| 	if (s->hsize != data->size) { | ||||
| 		data->off += s->hsize - data->size; | ||||
| 		data->ox += s->hsize - data->size; | ||||
| 		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); | ||||
|  | ||||
| 	if (py == 0 && ny > 0) { | ||||
| 		len = screen_size_x(s); | ||||
| 		if (len > (sizeof buf) - 1) | ||||
| 			len = (sizeof buf) - 1; | ||||
| 		len = xsnprintf(buf, len + 1, "{%u/%u}", | ||||
| 		    data->off, s->hsize); | ||||
| 		len = xsnprintf( | ||||
| 		    buf, len + 1, "[%u,%u/%u]", data->ox, data->oy, s->hsize); | ||||
|  | ||||
| 		input_store_two( | ||||
| 		    b, CODE_CURSORMOVE, 0, screen_size_x(s) - len + 1); | ||||
| @@ -86,9 +87,14 @@ void | ||||
| window_scroll_key(struct window *w, int key) | ||||
| { | ||||
| 	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) { | ||||
| 	case 'Q': | ||||
| 	case 'q': | ||||
| @@ -98,33 +104,43 @@ window_scroll_key(struct window *w, int key) | ||||
| 		recalculate_sizes(); | ||||
| 		server_redraw_window_all(w); | ||||
| 		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 KEYC_UP: | ||||
| 		if (data->off < data->size) | ||||
| 			data->off++; | ||||
| 		if (data->oy < data->size) | ||||
| 			data->oy++; | ||||
| 		break; | ||||
| 	case 'j': | ||||
| 	case 'J': | ||||
| 	case KEYC_DOWN: | ||||
| 		if (data->off > 0) | ||||
| 			data->off--; | ||||
| 		if (data->oy > 0) | ||||
| 			data->oy--; | ||||
| 		break; | ||||
| 	case '\025': | ||||
| 	case KEYC_PPAGE: | ||||
| 		if (data->off + sy > data->size) | ||||
| 			data->off = data->size; | ||||
| 		if (data->oy + sy > data->size) | ||||
| 			data->oy = data->size; | ||||
| 		else | ||||
| 			data->off += sy; | ||||
| 			data->oy += sy; | ||||
| 		break; | ||||
| 	case '\006': | ||||
| 	case KEYC_NPAGE: | ||||
| 		if (data->off < sy) | ||||
| 			data->off = 0; | ||||
| 		if (data->oy < sy) | ||||
| 			data->oy = 0; | ||||
| 		else | ||||
| 			data->off -= sy; | ||||
| 			data->oy -= sy; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (off != data->off) | ||||
| 	if (ox != data->ox || oy != data->oy) | ||||
| 		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> | ||||
| @@ -287,7 +287,7 @@ window_draw(struct window *w, struct buffer *b, u_int py, u_int ny) | ||||
| 	if (w->mode != NULL) | ||||
| 		w->mode->draw(w, b, py, ny); | ||||
| 	else | ||||
| 		screen_draw(&w->screen, b, py, ny, 0); | ||||
| 		screen_draw(&w->screen, b, py, ny, 0, 0); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott