mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		@@ -335,7 +335,9 @@ key_bindings_init(void)
 | 
			
		||||
		"bind -Tcopy-mode M-> send -X history-bottom",
 | 
			
		||||
		"bind -Tcopy-mode M-R send -X top-line",
 | 
			
		||||
		"bind -Tcopy-mode M-b send -X previous-word",
 | 
			
		||||
		"bind -Tcopy-mode C-M-b send -X previous-matching-bracket",
 | 
			
		||||
		"bind -Tcopy-mode M-f send -X next-word-end",
 | 
			
		||||
		"bind -Tcopy-mode C-M-f send -X next-matching-bracket",
 | 
			
		||||
		"bind -Tcopy-mode M-m send -X back-to-indentation",
 | 
			
		||||
		"bind -Tcopy-mode M-r send -X middle-line",
 | 
			
		||||
		"bind -Tcopy-mode M-v send -X page-up",
 | 
			
		||||
@@ -408,6 +410,7 @@ key_bindings_init(void)
 | 
			
		||||
		"bind -Tcopy-mode-vi w send -X next-word",
 | 
			
		||||
		"bind -Tcopy-mode-vi { send -X previous-paragraph",
 | 
			
		||||
		"bind -Tcopy-mode-vi } send -X next-paragraph",
 | 
			
		||||
		"bind -Tcopy-mode-vi % send -X next-matching-bracket",
 | 
			
		||||
		"bind -Tcopy-mode-vi MouseDown1Pane select-pane",
 | 
			
		||||
		"bind -Tcopy-mode-vi MouseDrag1Pane select-pane\\; send -X begin-selection",
 | 
			
		||||
		"bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-selection-and-cancel",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										223
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										223
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -223,7 +223,7 @@ struct window_copy_mode_data {
 | 
			
		||||
 | 
			
		||||
	int		 searchtype;
 | 
			
		||||
	char		*searchstr;
 | 
			
		||||
	bitstr_t        *searchmark;
 | 
			
		||||
	bitstr_t	*searchmark;
 | 
			
		||||
	u_int		 searchcount;
 | 
			
		||||
	int		 searchthis;
 | 
			
		||||
	int		 searchx;
 | 
			
		||||
@@ -994,6 +994,218 @@ window_copy_cmd_middle_line(struct window_copy_cmd_state *cs)
 | 
			
		||||
	return (WINDOW_COPY_CMD_REDRAW);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum window_copy_cmd_action
 | 
			
		||||
window_copy_cmd_previous_matching_bracket(struct window_copy_cmd_state *cs)
 | 
			
		||||
{
 | 
			
		||||
	struct window_mode_entry	*wme = cs->wme;
 | 
			
		||||
	u_int				 np = wme->prefix;
 | 
			
		||||
	struct window_copy_mode_data	*data = wme->data;
 | 
			
		||||
	struct screen			*s = data->backing;
 | 
			
		||||
	char				 open[] = "{[(", close[] = "}])";
 | 
			
		||||
	char				 tried, found, start, *cp;
 | 
			
		||||
	u_int				 px, py, xx, yy, n;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	int				 failed;
 | 
			
		||||
 | 
			
		||||
	for (; np != 0; np--) {
 | 
			
		||||
		/* Get cursor position and line length. */
 | 
			
		||||
		px = data->cx;
 | 
			
		||||
		py = screen_hsize(s) + data->cy - data->oy;
 | 
			
		||||
		xx = window_copy_find_length(wme, py);
 | 
			
		||||
		yy = screen_hsize(s) + screen_size_y(s) - 1;
 | 
			
		||||
		if (xx == 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Get the current character. If not on a bracket, try the
 | 
			
		||||
		 * previous. If still not, then behave like previous-word.
 | 
			
		||||
		 */
 | 
			
		||||
		tried = 0;
 | 
			
		||||
	retry:
 | 
			
		||||
		grid_get_cell(s->grid, px, py, &gc);
 | 
			
		||||
		if (gc.data.size != 1 || (gc.flags & GRID_FLAG_PADDING))
 | 
			
		||||
			cp = NULL;
 | 
			
		||||
		else {
 | 
			
		||||
			found = *gc.data.data;
 | 
			
		||||
			cp = strchr(close, found);
 | 
			
		||||
		}
 | 
			
		||||
		if (cp == NULL) {
 | 
			
		||||
			if (data->modekeys == MODEKEY_EMACS) {
 | 
			
		||||
				if (!tried && px > 0) {
 | 
			
		||||
					px--;
 | 
			
		||||
					tried = 1;
 | 
			
		||||
					goto retry;
 | 
			
		||||
				}
 | 
			
		||||
				window_copy_cursor_previous_word(wme, "}]) ");
 | 
			
		||||
				px = data->cx;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		start = open[cp - close];
 | 
			
		||||
 | 
			
		||||
		/* Walk backward until the matching bracket is reached. */
 | 
			
		||||
		n = 1;
 | 
			
		||||
		failed = 0;
 | 
			
		||||
		do {
 | 
			
		||||
			if (px == 0) {
 | 
			
		||||
				if (py == 0) {
 | 
			
		||||
					failed = 1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				do {
 | 
			
		||||
					py--;
 | 
			
		||||
					xx = window_copy_find_length(wme, py);
 | 
			
		||||
				} while (xx == 0 && py > 0);
 | 
			
		||||
				if (xx == 0 && py == 0) {
 | 
			
		||||
					failed = 1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				px = xx - 1;
 | 
			
		||||
			} else
 | 
			
		||||
				px--;
 | 
			
		||||
 | 
			
		||||
			grid_get_cell(s->grid, px, py, &gc);
 | 
			
		||||
			if (gc.data.size == 1 &&
 | 
			
		||||
			    (~gc.flags & GRID_FLAG_PADDING)) {
 | 
			
		||||
				if (*gc.data.data == found)
 | 
			
		||||
					n++;
 | 
			
		||||
				else if (*gc.data.data == start)
 | 
			
		||||
					n--;
 | 
			
		||||
			}
 | 
			
		||||
		} while (n != 0);
 | 
			
		||||
 | 
			
		||||
		/* Move the cursor to the found location if any. */
 | 
			
		||||
		if (!failed)
 | 
			
		||||
			window_copy_scroll_to(wme, px, py);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (WINDOW_COPY_CMD_NOTHING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum window_copy_cmd_action
 | 
			
		||||
window_copy_cmd_next_matching_bracket(struct window_copy_cmd_state *cs)
 | 
			
		||||
{
 | 
			
		||||
	struct window_mode_entry	*wme = cs->wme;
 | 
			
		||||
	u_int				 np = wme->prefix;
 | 
			
		||||
	struct window_copy_mode_data	*data = wme->data;
 | 
			
		||||
	struct screen			*s = data->backing;
 | 
			
		||||
	char				 open[] = "{[(", close[] = "}])";
 | 
			
		||||
	char				 tried, found, end, *cp;
 | 
			
		||||
	u_int				 px, py, xx, yy, sx, sy, n;
 | 
			
		||||
	struct grid_cell		 gc;
 | 
			
		||||
	int				 failed;
 | 
			
		||||
	struct grid_line		*gl;
 | 
			
		||||
 | 
			
		||||
	for (; np != 0; np--) {
 | 
			
		||||
		/* Get cursor position and line length. */
 | 
			
		||||
		px = data->cx;
 | 
			
		||||
		py = screen_hsize(s) + data->cy - data->oy;
 | 
			
		||||
		xx = window_copy_find_length(wme, py);
 | 
			
		||||
		yy = screen_hsize(s) + screen_size_y(s) - 1;
 | 
			
		||||
		if (xx == 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Get the current character. If not on a bracket, try the
 | 
			
		||||
		 * next. If still not, then behave like next-word.
 | 
			
		||||
		 */
 | 
			
		||||
		tried = 0;
 | 
			
		||||
	retry:
 | 
			
		||||
		grid_get_cell(s->grid, px, py, &gc);
 | 
			
		||||
		if (gc.data.size != 1 || (gc.flags & GRID_FLAG_PADDING))
 | 
			
		||||
			cp = NULL;
 | 
			
		||||
		else {
 | 
			
		||||
			found = *gc.data.data;
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * In vi mode, attempt to move to previous bracket if a
 | 
			
		||||
			 * closing bracket is found first. If this fails,
 | 
			
		||||
			 * return to the original cursor position.
 | 
			
		||||
			 */
 | 
			
		||||
			cp = strchr(close, found);
 | 
			
		||||
			if (cp != NULL && data->modekeys == MODEKEY_VI) {
 | 
			
		||||
				sx = data->cx;
 | 
			
		||||
				sy = screen_hsize(s) + data->cy - data->oy;
 | 
			
		||||
 | 
			
		||||
				window_copy_scroll_to(wme, px, py);
 | 
			
		||||
				window_copy_cmd_previous_matching_bracket(cs);
 | 
			
		||||
 | 
			
		||||
				px = data->cx;
 | 
			
		||||
				py = screen_hsize(s) + data->cy - data->oy;
 | 
			
		||||
				grid_get_cell(s->grid, px, py, &gc);
 | 
			
		||||
				if (gc.data.size != 1 ||
 | 
			
		||||
				    (gc.flags & GRID_FLAG_PADDING) ||
 | 
			
		||||
				    strchr(close, *gc.data.data) == NULL)
 | 
			
		||||
					window_copy_scroll_to(wme, sx, sy);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cp = strchr(open, found);
 | 
			
		||||
		}
 | 
			
		||||
		if (cp == NULL) {
 | 
			
		||||
			if (data->modekeys == MODEKEY_EMACS) {
 | 
			
		||||
				if (!tried && px <= xx) {
 | 
			
		||||
					px++;
 | 
			
		||||
					tried = 1;
 | 
			
		||||
					goto retry;
 | 
			
		||||
				}
 | 
			
		||||
				window_copy_cursor_next_word_end(wme, "{[( ");
 | 
			
		||||
				px = data->cx;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			/* For vi, continue searching for bracket until EOL. */
 | 
			
		||||
			if (px > xx) {
 | 
			
		||||
				if (py == yy)
 | 
			
		||||
					continue;
 | 
			
		||||
				gl = grid_get_line(s->grid, py);
 | 
			
		||||
				if (~gl->flags & GRID_LINE_WRAPPED)
 | 
			
		||||
					continue;
 | 
			
		||||
				if (gl->cellsize > s->grid->sx)
 | 
			
		||||
					continue;
 | 
			
		||||
				px = 0;
 | 
			
		||||
				py++;
 | 
			
		||||
				xx = window_copy_find_length(wme, py);
 | 
			
		||||
			} else
 | 
			
		||||
				px++;
 | 
			
		||||
			goto retry;
 | 
			
		||||
		}
 | 
			
		||||
		end = close[cp - open];
 | 
			
		||||
 | 
			
		||||
		/* Walk forward until the matching bracket is reached. */
 | 
			
		||||
		n = 1;
 | 
			
		||||
		failed = 0;
 | 
			
		||||
		do {
 | 
			
		||||
			if (px > xx) {
 | 
			
		||||
				if (py == yy) {
 | 
			
		||||
					failed = 1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				px = 0;
 | 
			
		||||
				py++;
 | 
			
		||||
				xx = window_copy_find_length(wme, py);
 | 
			
		||||
			} else
 | 
			
		||||
				px++;
 | 
			
		||||
 | 
			
		||||
			grid_get_cell(s->grid, px, py, &gc);
 | 
			
		||||
			if (gc.data.size == 1 &&
 | 
			
		||||
			    (~gc.flags & GRID_FLAG_PADDING)) {
 | 
			
		||||
				if (*gc.data.data == found)
 | 
			
		||||
					n++;
 | 
			
		||||
				else if (*gc.data.data == end)
 | 
			
		||||
					n--;
 | 
			
		||||
			}
 | 
			
		||||
		} while (n != 0);
 | 
			
		||||
 | 
			
		||||
		/* Move the cursor to the found location if any. */
 | 
			
		||||
		if (!failed)
 | 
			
		||||
			window_copy_scroll_to(wme, px, py);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (WINDOW_COPY_CMD_NOTHING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum window_copy_cmd_action
 | 
			
		||||
window_copy_cmd_next_paragraph(struct window_copy_cmd_state *cs)
 | 
			
		||||
{
 | 
			
		||||
@@ -1613,6 +1825,8 @@ static const struct {
 | 
			
		||||
	  window_copy_cmd_jump_to_forward },
 | 
			
		||||
	{ "middle-line", 0, 0,
 | 
			
		||||
	  window_copy_cmd_middle_line },
 | 
			
		||||
	{ "next-matching-bracket", 0, 0,
 | 
			
		||||
	  window_copy_cmd_next_matching_bracket },
 | 
			
		||||
	{ "next-paragraph", 0, 0,
 | 
			
		||||
	  window_copy_cmd_next_paragraph },
 | 
			
		||||
	{ "next-space", 0, 0,
 | 
			
		||||
@@ -1631,6 +1845,8 @@ static const struct {
 | 
			
		||||
	  window_copy_cmd_page_down_and_cancel },
 | 
			
		||||
	{ "page-up", 0, 0,
 | 
			
		||||
	  window_copy_cmd_page_up },
 | 
			
		||||
	{ "previous-matching-bracket", 0, 0,
 | 
			
		||||
	  window_copy_cmd_previous_matching_bracket },
 | 
			
		||||
	{ "previous-paragraph", 0, 0,
 | 
			
		||||
	  window_copy_cmd_previous_paragraph },
 | 
			
		||||
	{ "previous-space", 0, 0,
 | 
			
		||||
@@ -3147,6 +3363,11 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
 | 
			
		||||
 | 
			
		||||
			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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user