mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Change mouse selection so that after selecting a word, dragging selects
only words and similar for lines. From Anindya Mukherjee.
This commit is contained in:
		
							
								
								
									
										260
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										260
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -119,8 +119,12 @@ static void	window_copy_cursor_jump_to(struct window_mode_entry *);
 | 
				
			|||||||
static void	window_copy_cursor_jump_to_back(struct window_mode_entry *);
 | 
					static void	window_copy_cursor_jump_to_back(struct window_mode_entry *);
 | 
				
			||||||
static void	window_copy_cursor_next_word(struct window_mode_entry *,
 | 
					static void	window_copy_cursor_next_word(struct window_mode_entry *,
 | 
				
			||||||
		    const char *);
 | 
							    const char *);
 | 
				
			||||||
 | 
					static void	window_copy_cursor_next_word_end_pos(struct window_mode_entry *,
 | 
				
			||||||
 | 
							    const char *, u_int *, u_int *);
 | 
				
			||||||
static void	window_copy_cursor_next_word_end(struct window_mode_entry *,
 | 
					static void	window_copy_cursor_next_word_end(struct window_mode_entry *,
 | 
				
			||||||
		    const char *);
 | 
							    const char *);
 | 
				
			||||||
 | 
					static void	window_copy_cursor_previous_word_pos(struct window_mode_entry *,
 | 
				
			||||||
 | 
							    const char *, int, u_int *, u_int *);
 | 
				
			||||||
static void	window_copy_cursor_previous_word(struct window_mode_entry *,
 | 
					static void	window_copy_cursor_previous_word(struct window_mode_entry *,
 | 
				
			||||||
		    const char *, int);
 | 
							    const char *, int);
 | 
				
			||||||
static void	window_copy_scroll_up(struct window_mode_entry *, u_int);
 | 
					static void	window_copy_scroll_up(struct window_mode_entry *, u_int);
 | 
				
			||||||
@@ -227,6 +231,22 @@ struct window_copy_mode_data {
 | 
				
			|||||||
	int		 rectflag;	/* in rectangle copy mode? */
 | 
						int		 rectflag;	/* in rectangle copy mode? */
 | 
				
			||||||
	int		 scroll_exit;	/* exit on scroll to end? */
 | 
						int		 scroll_exit;	/* exit on scroll to end? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum {
 | 
				
			||||||
 | 
							SEL_CHAR,		/* select one char at a time */
 | 
				
			||||||
 | 
							SEL_WORD,		/* select one word at a time */
 | 
				
			||||||
 | 
							SEL_LINE,		/* select one line at a time */
 | 
				
			||||||
 | 
						} selflag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char	*ws;		/* word separators */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int		 dx;		/* drag start position */
 | 
				
			||||||
 | 
						u_int		 dy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u_int		 selrx;		/* selection reset positions */
 | 
				
			||||||
 | 
						u_int		 selry;
 | 
				
			||||||
 | 
						u_int		 endselrx;
 | 
				
			||||||
 | 
						u_int		 endselry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u_int		 cx;
 | 
						u_int		 cx;
 | 
				
			||||||
	u_int		 cy;
 | 
						u_int		 cy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -695,6 +715,9 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs)
 | 
				
			|||||||
	struct client			*c = cs->c;
 | 
						struct client			*c = cs->c;
 | 
				
			||||||
	struct mouse_event		*m = cs->m;
 | 
						struct mouse_event		*m = cs->m;
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
 | 
						struct options			*oo = cs->s->options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data->ws = options_get_string(oo, "word-separators");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (m != NULL) {
 | 
						if (m != NULL) {
 | 
				
			||||||
		window_copy_start_drag(c, m);
 | 
							window_copy_start_drag(c, m);
 | 
				
			||||||
@@ -1507,12 +1530,19 @@ window_copy_cmd_select_line(struct window_copy_cmd_state *cs)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	data->lineflag = LINE_SEL_LEFT_RIGHT;
 | 
						data->lineflag = LINE_SEL_LEFT_RIGHT;
 | 
				
			||||||
	data->rectflag = 0;
 | 
						data->rectflag = 0;
 | 
				
			||||||
 | 
						data->selflag = SEL_LINE;
 | 
				
			||||||
 | 
						data->dx = data->cx;
 | 
				
			||||||
 | 
						data->dy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	window_copy_cursor_start_of_line(wme);
 | 
						window_copy_cursor_start_of_line(wme);
 | 
				
			||||||
 | 
						data->selrx = data->cx;
 | 
				
			||||||
 | 
						data->selry = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
	window_copy_start_selection(wme);
 | 
						window_copy_start_selection(wme);
 | 
				
			||||||
	for (; np > 1; np--)
 | 
						for (; np > 1; np--)
 | 
				
			||||||
		window_copy_cursor_down(wme, 0);
 | 
							window_copy_cursor_down(wme, 0);
 | 
				
			||||||
	window_copy_cursor_end_of_line(wme);
 | 
						window_copy_cursor_end_of_line(wme);
 | 
				
			||||||
 | 
						data->endselrx = data->cx;
 | 
				
			||||||
 | 
						data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (WINDOW_COPY_CMD_REDRAW);
 | 
						return (WINDOW_COPY_CMD_REDRAW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1524,26 +1554,33 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
 | 
				
			|||||||
	struct session			*s = cs->s;
 | 
						struct session			*s = cs->s;
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
	const char			*ws;
 | 
						const char			*ws;
 | 
				
			||||||
	u_int				 px, py, xx;
 | 
						u_int				 px, py;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->lineflag = LINE_SEL_LEFT_RIGHT;
 | 
						data->lineflag = LINE_SEL_LEFT_RIGHT;
 | 
				
			||||||
	data->rectflag = 0;
 | 
						data->rectflag = 0;
 | 
				
			||||||
 | 
						data->selflag = SEL_WORD;
 | 
				
			||||||
 | 
						data->dx = data->cx;
 | 
				
			||||||
 | 
						data->dy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	px = data->cx;
 | 
						px = data->cx;
 | 
				
			||||||
	py = screen_hsize(data->backing) + data->cy - data->oy;
 | 
						py = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
	xx = window_copy_find_length(wme, py);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ws = options_get_string(s->options, "word-separators");
 | 
						ws = options_get_string(s->options, "word-separators");
 | 
				
			||||||
	window_copy_cursor_previous_word(wme, ws, 0);
 | 
						window_copy_cursor_previous_word(wme, ws, 0);
 | 
				
			||||||
 | 
						data->selrx = data->cx;
 | 
				
			||||||
 | 
						data->selry = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
	window_copy_start_selection(wme);
 | 
						window_copy_start_selection(wme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (px >= xx || !window_copy_in_set(wme, px + 1, py, ws))
 | 
						if (px >= window_copy_find_length(wme, py) ||
 | 
				
			||||||
 | 
						    !window_copy_in_set(wme, px + 1, py, ws))
 | 
				
			||||||
		window_copy_cursor_next_word_end(wme, ws);
 | 
							window_copy_cursor_next_word_end(wme, ws);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		window_copy_update_cursor(wme, px, data->cy);
 | 
							window_copy_update_cursor(wme, px, data->cy);
 | 
				
			||||||
		if (window_copy_update_selection(wme, 1))
 | 
							if (window_copy_update_selection(wme, 1))
 | 
				
			||||||
			window_copy_redraw_lines(wme, data->cy, 1);
 | 
								window_copy_redraw_lines(wme, data->cy, 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						data->endselrx = data->cx;
 | 
				
			||||||
 | 
						data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (WINDOW_COPY_CMD_REDRAW);
 | 
						return (WINDOW_COPY_CMD_REDRAW);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2788,6 +2825,7 @@ static void
 | 
				
			|||||||
window_copy_redraw_selection(struct window_mode_entry *wme, u_int old_y)
 | 
					window_copy_redraw_selection(struct window_mode_entry *wme, u_int old_y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
 | 
						struct grid			*gd = data->backing->grid;
 | 
				
			||||||
	u_int				 new_y, start, end;
 | 
						u_int				 new_y, start, end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	new_y = data->cy;
 | 
						new_y = data->cy;
 | 
				
			||||||
@@ -2798,6 +2836,16 @@ window_copy_redraw_selection(struct window_mode_entry *wme, u_int old_y)
 | 
				
			|||||||
		start = new_y;
 | 
							start = new_y;
 | 
				
			||||||
		end = old_y;
 | 
							end = old_y;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * In word selection mode the first word on the line below the cursor
 | 
				
			||||||
 | 
						 * might be selected, so add this line to the redraw area.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (data->selflag == SEL_WORD) {
 | 
				
			||||||
 | 
							/* Last grid line in data coordinates. */
 | 
				
			||||||
 | 
							if (end < gd->sy + data->oy - 1)
 | 
				
			||||||
 | 
								end++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	window_copy_redraw_lines(wme, start, end - start + 1);
 | 
						window_copy_redraw_lines(wme, start, end - start + 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2825,22 +2873,82 @@ window_copy_redraw_screen(struct window_mode_entry *wme)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
window_copy_synchronize_cursor(struct window_mode_entry *wme)
 | 
					window_copy_synchronize_cursor_end(struct window_mode_entry *wme)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
	u_int				 xx, yy;
 | 
						u_int				 xx, yy;
 | 
				
			||||||
 | 
						int				 begin = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xx = data->cx;
 | 
					 | 
				
			||||||
	yy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
						yy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
						switch (data->selflag) {
 | 
				
			||||||
 | 
						case SEL_WORD:
 | 
				
			||||||
 | 
							xx = data->cx;
 | 
				
			||||||
 | 
							if (data->ws == NULL)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (data->dy > yy || (data->dy == yy && data->dx > xx)) {
 | 
				
			||||||
 | 
								/* Right to left selection. */
 | 
				
			||||||
 | 
								window_copy_cursor_previous_word_pos(wme, data->ws, 0,
 | 
				
			||||||
 | 
								    &xx, &yy);
 | 
				
			||||||
 | 
								begin = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Reset the end. */
 | 
				
			||||||
 | 
								data->endselx = data->endselrx;
 | 
				
			||||||
 | 
								data->endsely = data->endselry;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Left to right selection. */
 | 
				
			||||||
 | 
								if (xx >= window_copy_find_length(wme, yy) ||
 | 
				
			||||||
 | 
								    !window_copy_in_set(wme, xx + 1, yy, data->ws))
 | 
				
			||||||
 | 
									window_copy_cursor_next_word_end_pos(wme,
 | 
				
			||||||
 | 
									    data->ws, &xx, &yy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Reset the start. */
 | 
				
			||||||
 | 
								data->selx = data->selrx;
 | 
				
			||||||
 | 
								data->sely = data->selry;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SEL_LINE:
 | 
				
			||||||
 | 
							if (data->dy > yy) {
 | 
				
			||||||
 | 
								/* Right to left selection. */
 | 
				
			||||||
 | 
								xx = 0;
 | 
				
			||||||
 | 
								begin = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Reset the end. */
 | 
				
			||||||
 | 
								data->endselx = data->endselrx;
 | 
				
			||||||
 | 
								data->endsely = data->endselry;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Left to right selection. */
 | 
				
			||||||
 | 
								xx = window_copy_find_length(wme, yy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Reset the start. */
 | 
				
			||||||
 | 
								data->selx = data->selrx;
 | 
				
			||||||
 | 
								data->sely = data->selry;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SEL_CHAR:
 | 
				
			||||||
 | 
							xx = data->cx;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (begin) {
 | 
				
			||||||
 | 
							data->selx = xx;
 | 
				
			||||||
 | 
							data->sely = yy;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							data->endselx = xx;
 | 
				
			||||||
 | 
							data->endsely = yy;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_copy_synchronize_cursor(struct window_mode_entry *wme)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (data->cursordrag) {
 | 
						switch (data->cursordrag) {
 | 
				
			||||||
	case CURSORDRAG_ENDSEL:
 | 
						case CURSORDRAG_ENDSEL:
 | 
				
			||||||
		data->endselx = xx;
 | 
							window_copy_synchronize_cursor_end(wme);
 | 
				
			||||||
		data->endsely = yy;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case CURSORDRAG_SEL:
 | 
						case CURSORDRAG_SEL:
 | 
				
			||||||
		data->selx = xx;
 | 
							data->selx = data->cx;
 | 
				
			||||||
		data->sely = yy;
 | 
							data->sely = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case CURSORDRAG_NONE:
 | 
						case CURSORDRAG_NONE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
@@ -3709,6 +3817,55 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
 | 
				
			|||||||
		window_copy_redraw_lines(wme, data->cy, 1);
 | 
							window_copy_redraw_lines(wme, data->cy, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
 | 
				
			||||||
 | 
					    const char *separators, u_int *ppx, u_int *ppy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane		*wp = wme->wp;
 | 
				
			||||||
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
 | 
						struct options			*oo = wp->window->options;
 | 
				
			||||||
 | 
						struct screen			*back_s = data->backing;
 | 
				
			||||||
 | 
						u_int				 px, py, xx, yy;
 | 
				
			||||||
 | 
						int				 keys, expected = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = data->cx;
 | 
				
			||||||
 | 
						py = screen_hsize(back_s) + data->cy - data->oy;
 | 
				
			||||||
 | 
						xx = window_copy_find_length(wme, py);
 | 
				
			||||||
 | 
						yy = screen_hsize(back_s) + screen_size_y(back_s) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keys = options_get_number(oo, "mode-keys");
 | 
				
			||||||
 | 
						if (keys == MODEKEY_VI && !window_copy_in_set(wme, px, py, separators))
 | 
				
			||||||
 | 
							px++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * First skip past any word characters, then any non-word characters.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * expected is initially set to 1 for the former and then 0 for the
 | 
				
			||||||
 | 
						 * latter.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							while (px > xx ||
 | 
				
			||||||
 | 
							    window_copy_in_set(wme, px, py, separators) == expected) {
 | 
				
			||||||
 | 
								/* Move down if we're past the end of the line. */
 | 
				
			||||||
 | 
								if (px > xx) {
 | 
				
			||||||
 | 
									if (py == yy)
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									py++;
 | 
				
			||||||
 | 
									px = 0;
 | 
				
			||||||
 | 
									xx = window_copy_find_length(wme, py);
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
									px++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							expected = !expected;
 | 
				
			||||||
 | 
						} while (expected == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (keys == MODEKEY_VI && px != 0)
 | 
				
			||||||
 | 
							px--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*ppx = px;
 | 
				
			||||||
 | 
						*ppy = py;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
window_copy_cursor_next_word_end(struct window_mode_entry *wme,
 | 
					window_copy_cursor_next_word_end(struct window_mode_entry *wme,
 | 
				
			||||||
    const char *separators)
 | 
					    const char *separators)
 | 
				
			||||||
@@ -3761,6 +3918,54 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
 | 
				
			|||||||
		window_copy_redraw_lines(wme, data->cy, 1);
 | 
							window_copy_redraw_lines(wme, data->cy, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Compute the previous place where a word begins. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_copy_cursor_previous_word_pos(struct window_mode_entry *wme,
 | 
				
			||||||
 | 
					    const char *separators, int already, u_int *ppx, u_int *ppy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
 | 
						u_int				 px, py;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = data->cx;
 | 
				
			||||||
 | 
						py = screen_hsize(data->backing) + data->cy - data->oy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Move back to the previous word character. */
 | 
				
			||||||
 | 
						if (already || window_copy_in_set(wme, px, py, separators)) {
 | 
				
			||||||
 | 
							for (;;) {
 | 
				
			||||||
 | 
								if (px > 0) {
 | 
				
			||||||
 | 
									px--;
 | 
				
			||||||
 | 
									if (!window_copy_in_set(wme, px, py,
 | 
				
			||||||
 | 
									    separators))
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									if (data->cy == 0 &&
 | 
				
			||||||
 | 
									    (screen_hsize(data->backing) == 0 ||
 | 
				
			||||||
 | 
									    data->oy >=
 | 
				
			||||||
 | 
									    screen_hsize(data->backing) - 1))
 | 
				
			||||||
 | 
										goto out;
 | 
				
			||||||
 | 
									py--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									py = screen_hsize(data->backing) + data->cy -
 | 
				
			||||||
 | 
									    data->oy;
 | 
				
			||||||
 | 
									px = window_copy_find_length(wme, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									/* Stop if separator at EOL. */
 | 
				
			||||||
 | 
									if (px > 0 && window_copy_in_set(wme, px - 1,
 | 
				
			||||||
 | 
									    py, separators))
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Move back to the beginning of this word. */
 | 
				
			||||||
 | 
						while (px > 0 && !window_copy_in_set(wme, px - 1, py, separators))
 | 
				
			||||||
 | 
							px--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						*ppx = px;
 | 
				
			||||||
 | 
						*ppy = py;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Move to the previous place where a word begins. */
 | 
					/* Move to the previous place where a word begins. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
window_copy_cursor_previous_word(struct window_mode_entry *wme,
 | 
					window_copy_cursor_previous_word(struct window_mode_entry *wme,
 | 
				
			||||||
@@ -3777,21 +3982,24 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
 | 
				
			|||||||
		for (;;) {
 | 
							for (;;) {
 | 
				
			||||||
			if (px > 0) {
 | 
								if (px > 0) {
 | 
				
			||||||
				px--;
 | 
									px--;
 | 
				
			||||||
				if (!window_copy_in_set(wme, px, py, separators))
 | 
									if (!window_copy_in_set(wme, px, py,
 | 
				
			||||||
 | 
									    separators))
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if (data->cy == 0 &&
 | 
									if (data->cy == 0 &&
 | 
				
			||||||
				    (screen_hsize(data->backing) == 0 ||
 | 
									    (screen_hsize(data->backing) == 0 ||
 | 
				
			||||||
				    data->oy >= screen_hsize(data->backing) - 1))
 | 
									    data->oy >=
 | 
				
			||||||
 | 
									    screen_hsize(data->backing) - 1))
 | 
				
			||||||
					goto out;
 | 
										goto out;
 | 
				
			||||||
				window_copy_cursor_up(wme, 0);
 | 
									window_copy_cursor_up(wme, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				py = screen_hsize(data->backing) + data->cy - data->oy;
 | 
									py = screen_hsize(data->backing) + data->cy -
 | 
				
			||||||
 | 
									    data->oy;
 | 
				
			||||||
				px = window_copy_find_length(wme, py);
 | 
									px = window_copy_find_length(wme, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* Stop if separator at EOL. */
 | 
									/* Stop if separator at EOL. */
 | 
				
			||||||
				if (px > 0 &&
 | 
									if (px > 0 && window_copy_in_set(wme, px - 1,
 | 
				
			||||||
				    window_copy_in_set(wme, px - 1, py, separators))
 | 
									    py, separators))
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -3913,6 +4121,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct window_pane		*wp;
 | 
						struct window_pane		*wp;
 | 
				
			||||||
	struct window_mode_entry	*wme;
 | 
						struct window_mode_entry	*wme;
 | 
				
			||||||
 | 
						struct window_copy_mode_data	*data;
 | 
				
			||||||
	u_int				 x, y;
 | 
						u_int				 x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (c == NULL)
 | 
						if (c == NULL)
 | 
				
			||||||
@@ -3933,10 +4142,27 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
 | 
				
			|||||||
	c->tty.mouse_drag_update = window_copy_drag_update;
 | 
						c->tty.mouse_drag_update = window_copy_drag_update;
 | 
				
			||||||
	c->tty.mouse_drag_release = window_copy_drag_release;
 | 
						c->tty.mouse_drag_release = window_copy_drag_release;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	window_copy_update_cursor(wme, x, y);
 | 
						data = wme->data;
 | 
				
			||||||
	window_copy_start_selection(wme);
 | 
						switch (data->selflag) {
 | 
				
			||||||
	window_copy_redraw_screen(wme);
 | 
							case SEL_WORD:
 | 
				
			||||||
 | 
								if (data->ws) {
 | 
				
			||||||
 | 
									window_copy_update_cursor(wme, x, y);
 | 
				
			||||||
 | 
									window_copy_cursor_previous_word_pos(wme,
 | 
				
			||||||
 | 
									    data->ws, 0, &x, &y);
 | 
				
			||||||
 | 
									y -= screen_hsize(data->backing) - data->oy;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								window_copy_update_cursor(wme, x, y);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SEL_LINE:
 | 
				
			||||||
 | 
								window_copy_update_cursor(wme, 0, y);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SEL_CHAR:
 | 
				
			||||||
 | 
								window_copy_update_cursor(wme, x, y);
 | 
				
			||||||
 | 
								window_copy_start_selection(wme);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_copy_redraw_screen(wme);
 | 
				
			||||||
	window_copy_drag_update(c, m);
 | 
						window_copy_drag_update(c, m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user