mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add V for select line with vi(1) keys. From Juho Pohjala.
This commit is contained in:
		@@ -289,6 +289,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
 | 
			
		||||
	{ 'M',			    0, MODEKEYCOPY_MIDDLELINE },
 | 
			
		||||
	{ 'N',			    0, MODEKEYCOPY_SEARCHREVERSE },
 | 
			
		||||
	{ 'T',			    0, MODEKEYCOPY_JUMPTOBACK },
 | 
			
		||||
	{ 'V',			    0, MODEKEYCOPY_SELECTLINE },
 | 
			
		||||
	{ 'W',			    0, MODEKEYCOPY_NEXTSPACE },
 | 
			
		||||
	{ '\002' /* C-b */,	    0, MODEKEYCOPY_PREVIOUSPAGE },
 | 
			
		||||
	{ '\003' /* C-c */,	    0, MODEKEYCOPY_CANCEL },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								screen.c
									
									
									
									
									
								
							@@ -269,6 +269,7 @@ screen_clear_selection(struct screen *s)
 | 
			
		||||
	struct screen_sel	*sel = &s->sel;
 | 
			
		||||
 | 
			
		||||
	sel->flag = 0;
 | 
			
		||||
	sel->lineflag = LINE_SEL_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check if cell in selection. */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.1
									
									
									
									
									
								
							@@ -912,6 +912,7 @@ The following keys are supported as appropriate for the mode:
 | 
			
		||||
.It Li "Rectangle toggle" Ta "v" Ta "R"
 | 
			
		||||
.It Li "Scroll down" Ta "C-Down or C-e" Ta "C-Down"
 | 
			
		||||
.It Li "Scroll up" Ta "C-Up or C-y" Ta "C-Up"
 | 
			
		||||
.It Li "Select line" Ta "" Ta "V"
 | 
			
		||||
.It Li "Search again" Ta "n" Ta "n"
 | 
			
		||||
.It Li "Search again in reverse" Ta "N" Ta "N"
 | 
			
		||||
.It Li "Search backward" Ta "?" Ta "C-r"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							@@ -712,6 +712,12 @@ LIST_HEAD(joblist, job);
 | 
			
		||||
struct screen_sel {
 | 
			
		||||
	int		 flag;
 | 
			
		||||
	int		 rectflag;
 | 
			
		||||
	enum {
 | 
			
		||||
		LINE_SEL_NONE,
 | 
			
		||||
		LINE_SEL_LEFT_RIGHT,
 | 
			
		||||
		LINE_SEL_RIGHT_LEFT,
 | 
			
		||||
	} lineflag;
 | 
			
		||||
 | 
			
		||||
	int		 modekeys;
 | 
			
		||||
 | 
			
		||||
	u_int		 sx;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -30,23 +30,23 @@ void	window_copy_resize(struct window_pane *, u_int, u_int);
 | 
			
		||||
void	window_copy_key(struct window_pane *, struct session *, int);
 | 
			
		||||
int	window_copy_key_input(struct window_pane *, int);
 | 
			
		||||
int	window_copy_key_numeric_prefix(struct window_pane *, int);
 | 
			
		||||
void	window_copy_mouse(
 | 
			
		||||
	    struct window_pane *, struct session *, struct mouse_event *);
 | 
			
		||||
void	window_copy_mouse(struct window_pane *, struct session *,
 | 
			
		||||
	    struct mouse_event *);
 | 
			
		||||
 | 
			
		||||
void	window_copy_redraw_lines(struct window_pane *, u_int, u_int);
 | 
			
		||||
void	window_copy_redraw_screen(struct window_pane *);
 | 
			
		||||
void	window_copy_write_line(
 | 
			
		||||
	    struct window_pane *, struct screen_write_ctx *, u_int);
 | 
			
		||||
void	window_copy_write_lines(
 | 
			
		||||
	    struct window_pane *, struct screen_write_ctx *, u_int, u_int);
 | 
			
		||||
void	window_copy_write_line(struct window_pane *, struct screen_write_ctx *,
 | 
			
		||||
	    u_int);
 | 
			
		||||
void	window_copy_write_lines(struct window_pane *,
 | 
			
		||||
	    struct screen_write_ctx *, u_int, u_int);
 | 
			
		||||
 | 
			
		||||
void	window_copy_scroll_to(struct window_pane *, u_int, u_int);
 | 
			
		||||
int	window_copy_search_compare(
 | 
			
		||||
	    struct grid *, u_int, u_int, struct grid *, u_int, int);
 | 
			
		||||
int	window_copy_search_lr(
 | 
			
		||||
	    struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
 | 
			
		||||
int	window_copy_search_rl(
 | 
			
		||||
	    struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
 | 
			
		||||
int	window_copy_search_compare(struct grid *, u_int, u_int, struct grid *,
 | 
			
		||||
	    u_int, int);
 | 
			
		||||
int	window_copy_search_lr(struct grid *, struct grid *, u_int *, u_int,
 | 
			
		||||
	    u_int, u_int, int);
 | 
			
		||||
int	window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
 | 
			
		||||
	    u_int, u_int, int);
 | 
			
		||||
void	window_copy_search_up(struct window_pane *, const char *);
 | 
			
		||||
void	window_copy_search_down(struct window_pane *, const char *);
 | 
			
		||||
void	window_copy_goto_line(struct window_pane *, const char *);
 | 
			
		||||
@@ -374,7 +374,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 | 
			
		||||
	u_int				 n;
 | 
			
		||||
	int				 np, keys;
 | 
			
		||||
	enum mode_key_cmd		 cmd;
 | 
			
		||||
	const char			*arg;
 | 
			
		||||
	const char			*arg, *ss;
 | 
			
		||||
 | 
			
		||||
	np = data->numprefix;
 | 
			
		||||
	if (np <= 0)
 | 
			
		||||
@@ -528,11 +528,15 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 | 
			
		||||
		window_copy_redraw_screen(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_STARTSELECTION:
 | 
			
		||||
		s->sel.lineflag = LINE_SEL_NONE;
 | 
			
		||||
		window_copy_start_selection(wp);
 | 
			
		||||
		window_copy_redraw_screen(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_COPYLINE:
 | 
			
		||||
	case MODEKEYCOPY_SELECTLINE:
 | 
			
		||||
		s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
 | 
			
		||||
		data->rectflag = 0;
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case MODEKEYCOPY_COPYLINE:
 | 
			
		||||
		window_copy_cursor_start_of_line(wp);
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case MODEKEYCOPY_COPYENDOFLINE:
 | 
			
		||||
@@ -683,29 +687,23 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 | 
			
		||||
		case WINDOW_COPY_NUMERICPREFIX:
 | 
			
		||||
			break;
 | 
			
		||||
		case WINDOW_COPY_SEARCHUP:
 | 
			
		||||
			ss = data->searchstr;
 | 
			
		||||
			if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
 | 
			
		||||
				for (; np != 0; np--) {
 | 
			
		||||
					window_copy_search_up(
 | 
			
		||||
					    wp, data->searchstr);
 | 
			
		||||
				}
 | 
			
		||||
				for (; np != 0; np--)
 | 
			
		||||
					window_copy_search_up(wp, ss);
 | 
			
		||||
			} else {
 | 
			
		||||
				for (; np != 0; np--) {
 | 
			
		||||
					window_copy_search_down(
 | 
			
		||||
					    wp, data->searchstr);
 | 
			
		||||
				}
 | 
			
		||||
				for (; np != 0; np--)
 | 
			
		||||
					window_copy_search_down(wp, ss);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case WINDOW_COPY_SEARCHDOWN:
 | 
			
		||||
			ss = data->searchstr;
 | 
			
		||||
			if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
 | 
			
		||||
				for (; np != 0; np--) {
 | 
			
		||||
					window_copy_search_down(
 | 
			
		||||
					    wp, data->searchstr);
 | 
			
		||||
				}
 | 
			
		||||
				for (; np != 0; np--)
 | 
			
		||||
					window_copy_search_down(wp, ss);
 | 
			
		||||
			} else {
 | 
			
		||||
				for (; np != 0; np--) {
 | 
			
		||||
					window_copy_search_up(
 | 
			
		||||
					    wp, data->searchstr);
 | 
			
		||||
				}
 | 
			
		||||
				for (; np != 0; np--)
 | 
			
		||||
					window_copy_search_up(wp, ss);
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
@@ -730,6 +728,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_RECTANGLETOGGLE:
 | 
			
		||||
		s->sel.lineflag = LINE_SEL_NONE;
 | 
			
		||||
		window_copy_rectangle_toggle(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
@@ -871,8 +870,8 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_mouse(
 | 
			
		||||
    struct window_pane *wp, struct session *sess, struct mouse_event *m)
 | 
			
		||||
window_copy_mouse(struct window_pane *wp, struct session *sess,
 | 
			
		||||
    struct mouse_event *m)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
@@ -895,7 +894,8 @@ window_copy_mouse(
 | 
			
		||||
				 * We reached the bottom, leave copy mode, but
 | 
			
		||||
				 * only if no selection is in progress.
 | 
			
		||||
				 */
 | 
			
		||||
				if (data->oy == 0 && !s->sel.flag)
 | 
			
		||||
				if (data->oy == 0 && !s->sel.flag &&
 | 
			
		||||
				    s->sel.lineflag == LINE_SEL_NONE)
 | 
			
		||||
					goto reset_mode;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -964,8 +964,8 @@ window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
window_copy_search_compare(
 | 
			
		||||
    struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis)
 | 
			
		||||
window_copy_search_compare(struct grid *gd, u_int px, u_int py,
 | 
			
		||||
    struct grid *sgd, u_int spx, int cis)
 | 
			
		||||
{
 | 
			
		||||
	const struct grid_cell	*gc, *sgc;
 | 
			
		||||
	struct utf8_data	 ud, sud;
 | 
			
		||||
@@ -1186,8 +1186,8 @@ window_copy_goto_line(struct window_pane *wp, const char *linestr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_write_line(
 | 
			
		||||
    struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
 | 
			
		||||
window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx,
 | 
			
		||||
    u_int py)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
@@ -1237,8 +1237,8 @@ window_copy_write_line(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_write_lines(
 | 
			
		||||
    struct window_pane *wp, struct screen_write_ctx *ctx, u_int py, u_int ny)
 | 
			
		||||
window_copy_write_lines(struct window_pane *wp, struct screen_write_ctx *ctx,
 | 
			
		||||
    u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	u_int	yy;
 | 
			
		||||
 | 
			
		||||
@@ -1311,7 +1311,7 @@ window_copy_update_selection(struct window_pane *wp, int may_redraw)
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	u_int				 sx, sy, ty, cy;
 | 
			
		||||
 | 
			
		||||
	if (!s->sel.flag)
 | 
			
		||||
	if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	/* Set colours. */
 | 
			
		||||
@@ -1365,7 +1365,7 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
 | 
			
		||||
	u_int				 firstsx, lastex, restex, restsx;
 | 
			
		||||
	int				 keys;
 | 
			
		||||
 | 
			
		||||
	if (!s->sel.flag)
 | 
			
		||||
	if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 | 
			
		||||
	buf = xmalloc(1);
 | 
			
		||||
@@ -1665,12 +1665,14 @@ window_copy_cursor_start_of_line(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
	struct grid			*gd = back_s->grid;
 | 
			
		||||
	u_int				 py;
 | 
			
		||||
 | 
			
		||||
	if (data->cx == 0) {
 | 
			
		||||
	if (data->cx == 0 && s->sel.lineflag == LINE_SEL_NONE) {
 | 
			
		||||
		py = screen_hsize(back_s) + data->cy - data->oy;
 | 
			
		||||
		while (py > 0 && gd->linedata[py-1].flags & GRID_LINE_WRAPPED) {
 | 
			
		||||
		while (py > 0 &&
 | 
			
		||||
		    gd->linedata[py-1].flags & GRID_LINE_WRAPPED) {
 | 
			
		||||
			window_copy_cursor_up(wp, 0);
 | 
			
		||||
			py = screen_hsize(back_s) + data->cy - data->oy;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1710,13 +1712,14 @@ window_copy_cursor_end_of_line(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*back_s = data->backing;
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
	struct grid			*gd = back_s->grid;
 | 
			
		||||
	u_int				 px, py;
 | 
			
		||||
 | 
			
		||||
	py = screen_hsize(back_s) + data->cy - data->oy;
 | 
			
		||||
	px = window_copy_find_length(wp, py);
 | 
			
		||||
 | 
			
		||||
	if (data->cx == px) {
 | 
			
		||||
	if (data->cx == px && s->sel.lineflag == LINE_SEL_NONE) {
 | 
			
		||||
		if (data->screen.sel.flag && data->rectflag)
 | 
			
		||||
			px = screen_size_x(back_s);
 | 
			
		||||
		if (gd->linedata[py].flags & GRID_LINE_WRAPPED) {
 | 
			
		||||
@@ -1742,9 +1745,14 @@ window_copy_other_end(struct window_pane *wp)
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
	u_int				 selx, sely, cx, cy, yy;
 | 
			
		||||
 | 
			
		||||
	if (!s->sel.flag)
 | 
			
		||||
	if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT)
 | 
			
		||||
		s->sel.lineflag = LINE_SEL_RIGHT_LEFT;
 | 
			
		||||
	else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
 | 
			
		||||
		s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
 | 
			
		||||
 | 
			
		||||
	selx = data->selx;
 | 
			
		||||
	sely = data->sely;
 | 
			
		||||
	cx = data->cx;
 | 
			
		||||
@@ -1820,6 +1828,9 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only)
 | 
			
		||||
		data->lastsx = ox;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
 | 
			
		||||
		window_copy_other_end(wp);
 | 
			
		||||
 | 
			
		||||
	data->cx = data->lastcx;
 | 
			
		||||
	if (scroll_only || data->cy == 0) {
 | 
			
		||||
		window_copy_scroll_down(wp, 1);
 | 
			
		||||
@@ -1846,6 +1857,11 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only)
 | 
			
		||||
		    data->cx > px)
 | 
			
		||||
			window_copy_cursor_end_of_line(wp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT)
 | 
			
		||||
		window_copy_cursor_end_of_line(wp);
 | 
			
		||||
	else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
 | 
			
		||||
		window_copy_cursor_start_of_line(wp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1862,6 +1878,9 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only)
 | 
			
		||||
		data->lastsx = ox;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely)
 | 
			
		||||
		window_copy_other_end(wp);
 | 
			
		||||
 | 
			
		||||
	data->cx = data->lastcx;
 | 
			
		||||
	if (scroll_only || data->cy == screen_size_y(s) - 1) {
 | 
			
		||||
		window_copy_scroll_up(wp, 1);
 | 
			
		||||
@@ -1880,6 +1899,11 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only)
 | 
			
		||||
		    data->cx > px)
 | 
			
		||||
			window_copy_cursor_end_of_line(wp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT)
 | 
			
		||||
		window_copy_cursor_end_of_line(wp);
 | 
			
		||||
	else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
 | 
			
		||||
		window_copy_cursor_start_of_line(wp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user