mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Now that copy mode copies the pane content rather than keeping a
reference to it, it isn't necessary that the pane in copy mode is the same as the one copying from. Add a -s flag to copy-mode to specify a different pane for the source content. This means it is possible to view two places in a pane's history at the same time in different panes, or copy from a pane's history into an editor or shell in the same pane. From Anindya Mukherjee.
This commit is contained in:
		
							
								
								
									
										2
									
								
								cfg.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cfg.c
									
									
									
									
									
								
							| @@ -284,7 +284,7 @@ cfg_show_causes(struct session *s) | ||||
|  | ||||
| 	wme = TAILQ_FIRST(&wp->modes); | ||||
| 	if (wme == NULL || wme->mode != &window_view_mode) | ||||
| 		window_pane_set_mode(wp, &window_view_mode, NULL, NULL); | ||||
| 		window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL); | ||||
| 	for (i = 0; i < cfg_ncauses; i++) { | ||||
| 		window_copy_add(wp, "%s", cfg_causes[i]); | ||||
| 		free(cfg_causes[i]); | ||||
|   | ||||
| @@ -86,6 +86,6 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	} else | ||||
| 		mode = &window_tree_mode; | ||||
|  | ||||
| 	window_pane_set_mode(wp, mode, &item->target, args); | ||||
| 	window_pane_set_mode(wp, NULL, mode, &item->target, args); | ||||
| 	return (CMD_RETURN_NORMAL); | ||||
| } | ||||
|   | ||||
| @@ -30,9 +30,10 @@ const struct cmd_entry cmd_copy_mode_entry = { | ||||
| 	.name = "copy-mode", | ||||
| 	.alias = NULL, | ||||
|  | ||||
| 	.args = { "eHMt:uq", 0, 0 }, | ||||
| 	.usage = "[-eHMuq] " CMD_TARGET_PANE_USAGE, | ||||
| 	.args = { "eHMs:t:uq", 0, 0 }, | ||||
| 	.usage = "[-eHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE, | ||||
|  | ||||
| 	.source =  { 's', CMD_FIND_PANE, 0 }, | ||||
| 	.target = { 't', CMD_FIND_PANE, 0 }, | ||||
|  | ||||
| 	.flags = CMD_AFTERHOOK, | ||||
| @@ -59,7 +60,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	struct cmdq_shared	*shared = item->shared; | ||||
| 	struct client		*c = item->client; | ||||
| 	struct session		*s; | ||||
| 	struct window_pane	*wp = item->target.wp; | ||||
| 	struct window_pane	*wp = item->target.wp, *swp; | ||||
|  | ||||
| 	if (args_has(args, 'q')) { | ||||
| 		window_pane_reset_mode_all(wp); | ||||
| @@ -74,11 +75,15 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	} | ||||
|  | ||||
| 	if (self->entry == &cmd_clock_mode_entry) { | ||||
| 		window_pane_set_mode(wp, &window_clock_mode, NULL, NULL); | ||||
| 		window_pane_set_mode(wp, NULL, &window_clock_mode, NULL, NULL); | ||||
| 		return (CMD_RETURN_NORMAL); | ||||
| 	} | ||||
|  | ||||
| 	if (!window_pane_set_mode(wp, &window_copy_mode, NULL, args)) { | ||||
| 	if (args_has(args, 's')) | ||||
| 		swp = item->source.wp; | ||||
| 	else | ||||
| 		swp = wp; | ||||
| 	if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) { | ||||
| 		if (args_has(args, 'M')) | ||||
| 			window_copy_start_drag(c, &shared->mouse); | ||||
| 	} | ||||
|   | ||||
| @@ -116,7 +116,8 @@ cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 		args_set(new_args, 'Z', NULL); | ||||
| 	args_set(new_args, 'f', filter); | ||||
|  | ||||
| 	window_pane_set_mode(wp, &window_tree_mode, &item->target, new_args); | ||||
| 	window_pane_set_mode(wp, NULL, &window_tree_mode, &item->target, | ||||
| 	    new_args); | ||||
|  | ||||
| 	args_free(new_args); | ||||
| 	free(filter); | ||||
|   | ||||
| @@ -511,8 +511,10 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...) | ||||
| 	} else { | ||||
| 		wp = c->session->curw->window->active; | ||||
| 		wme = TAILQ_FIRST(&wp->modes); | ||||
| 		if (wme == NULL || wme->mode != &window_view_mode) | ||||
| 			window_pane_set_mode(wp, &window_view_mode, NULL, NULL); | ||||
| 		if (wme == NULL || wme->mode != &window_view_mode) { | ||||
| 			window_pane_set_mode(wp, NULL, &window_view_mode, NULL, | ||||
| 			    NULL); | ||||
| 		} | ||||
| 		window_copy_add(wp, "%s", msg); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -82,7 +82,7 @@ cmd_run_shell_print(struct job *job, const char *msg) | ||||
|  | ||||
| 	wme = TAILQ_FIRST(&wp->modes); | ||||
| 	if (wme == NULL || wme->mode != &window_view_mode) | ||||
| 		window_pane_set_mode(wp, &window_view_mode, NULL, NULL); | ||||
| 		window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL); | ||||
| 	window_copy_add(wp, "%s", msg); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1608,6 +1608,7 @@ command is: | ||||
| .Bl -tag -width Ds | ||||
| .It Xo Ic copy-mode | ||||
| .Op Fl eHMqu | ||||
| .Op Fl s Ar src-pane | ||||
| .Op Fl t Ar target-pane | ||||
| .Xc | ||||
| Enter copy mode. | ||||
| @@ -1621,6 +1622,11 @@ begins a mouse drag (only valid if bound to a mouse key binding, see | ||||
| hides the position indicator in the top right. | ||||
| .Fl q | ||||
| cancels copy mode and any other modes. | ||||
| .Fl s | ||||
| copies from | ||||
| .Ar src-pane | ||||
| instead of | ||||
| .Ar target-pane. | ||||
| .Pp | ||||
| .Fl e | ||||
| specifies that scrolling to the bottom of the history (to the visible screen) | ||||
|   | ||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -848,6 +848,7 @@ struct window_mode { | ||||
| /* Active window mode. */ | ||||
| struct window_mode_entry { | ||||
| 	struct window_pane		*wp; | ||||
| 	struct window_pane		*swp; | ||||
|  | ||||
| 	const struct window_mode	*mode; | ||||
| 	void				*data; | ||||
| @@ -2537,8 +2538,8 @@ void		 window_pane_unset_palette(struct window_pane *, u_int); | ||||
| void		 window_pane_reset_palette(struct window_pane *); | ||||
| int		 window_pane_get_palette(struct window_pane *, int); | ||||
| int		 window_pane_set_mode(struct window_pane *, | ||||
| 		     const struct window_mode *, struct cmd_find_state *, | ||||
| 		     struct args *); | ||||
| 		     struct window_pane *, const struct window_mode *, | ||||
| 		     struct cmd_find_state *, struct args *); | ||||
| void		 window_pane_reset_mode(struct window_pane *); | ||||
| void		 window_pane_reset_mode_all(struct window_pane *); | ||||
| int		 window_pane_key(struct window_pane *, struct client *, | ||||
|   | ||||
| @@ -130,7 +130,7 @@ static void	window_copy_rectangle_toggle(struct window_mode_entry *); | ||||
| static void	window_copy_move_mouse(struct mouse_event *); | ||||
| static void	window_copy_drag_update(struct client *, struct mouse_event *); | ||||
| static void	window_copy_drag_release(struct client *, struct mouse_event *); | ||||
| static struct screen* window_copy_clone_screen(struct screen *src); | ||||
| static struct screen* window_copy_clone_screen(struct screen *, struct screen*); | ||||
|  | ||||
| const struct window_mode window_copy_mode = { | ||||
| 	.name = "copy-mode", | ||||
| @@ -299,21 +299,29 @@ window_copy_scroll_timer(__unused int fd, __unused short events, void *arg) | ||||
| } | ||||
|  | ||||
| static struct screen * | ||||
| window_copy_clone_screen(struct screen *src) | ||||
| window_copy_clone_screen(struct screen *src, struct screen *hint) | ||||
| { | ||||
| 	struct screen			*dst; | ||||
| 	struct screen_write_ctx		 ctx; | ||||
| 	u_int				 dy, sy; | ||||
|  | ||||
| 	dst = xcalloc(1, sizeof *dst); | ||||
| 	screen_init(dst, screen_size_x(src), | ||||
| 	    screen_hsize(src) + screen_size_y(src), src->grid->hlimit); | ||||
| 	grid_duplicate_lines(dst->grid, 0, src->grid, 0, | ||||
| 	    screen_hsize(src) + screen_size_y(src)); | ||||
| 	dst->grid->sy = screen_size_y(src); | ||||
| 	dst->grid->hsize = screen_hsize(src); | ||||
|  | ||||
| 	sy = screen_hsize(src) + screen_size_y(src); | ||||
| 	if (screen_size_y(hint) > sy) | ||||
| 		dy = screen_size_y(hint); | ||||
| 	else | ||||
| 		dy = sy; | ||||
| 	screen_init(dst, screen_size_x(src), dy, src->grid->hlimit); | ||||
|  | ||||
| 	grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy); | ||||
| 	if (screen_size_y(hint) < sy) { | ||||
| 		dst->grid->sy = screen_size_y(hint); | ||||
| 		dst->grid->hsize = sy - screen_size_y(hint); | ||||
| 	} | ||||
|  | ||||
| 	screen_write_start(&ctx, NULL, dst); | ||||
| 	screen_write_cursormove(&ctx, src->cx, src->cy, 0); | ||||
| 	screen_write_cursormove(&ctx, 0, dst->grid->sy - 1, 0); | ||||
| 	screen_write_stop(&ctx); | ||||
|  | ||||
| 	return (dst); | ||||
| @@ -361,14 +369,14 @@ static struct screen * | ||||
| window_copy_init(struct window_mode_entry *wme, | ||||
|     __unused struct cmd_find_state *fs, struct args *args) | ||||
| { | ||||
| 	struct window_pane		*wp = wme->wp; | ||||
| 	struct window_pane		*wp = wme->swp; | ||||
| 	struct window_copy_mode_data	*data; | ||||
| 	struct screen_write_ctx		 ctx; | ||||
| 	u_int				 i; | ||||
|  | ||||
| 	data = window_copy_common_init(wme); | ||||
|  | ||||
| 	data->backing = window_copy_clone_screen(&wp->base); | ||||
| 	data->backing = window_copy_clone_screen(&wp->base, &data->screen); | ||||
| 	data->cx = data->backing->cx; | ||||
| 	data->cy = data->backing->cy; | ||||
|  | ||||
| @@ -2001,7 +2009,7 @@ static enum window_copy_cmd_action | ||||
| window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs) | ||||
| { | ||||
| 	struct window_mode_entry	*wme = cs->wme; | ||||
| 	struct window_pane		*wp = wme->wp; | ||||
| 	struct window_pane		*wp = wme->swp; | ||||
| 	struct window_copy_mode_data	*data = wme->data; | ||||
|  | ||||
| 	if (data->viewmode) | ||||
| @@ -2009,7 +2017,7 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs) | ||||
|  | ||||
| 	screen_free(data->backing); | ||||
| 	free(data->backing); | ||||
| 	data->backing = window_copy_clone_screen(&wp->base); | ||||
| 	data->backing = window_copy_clone_screen(&wp->base, &data->screen); | ||||
|  | ||||
| 	return (WINDOW_COPY_CMD_REDRAW); | ||||
| } | ||||
| @@ -2964,6 +2972,7 @@ window_copy_write_line(struct window_mode_entry *wme, | ||||
| 	struct grid_cell		 gc; | ||||
| 	char				 hdr[512]; | ||||
| 	size_t				 size = 0; | ||||
| 	u_int				 hsize = screen_hsize(data->backing); | ||||
|  | ||||
| 	style_apply(&gc, oo, "mode-style"); | ||||
| 	gc.flags |= GRID_FLAG_NOPALETTE; | ||||
| @@ -2972,23 +2981,20 @@ window_copy_write_line(struct window_mode_entry *wme, | ||||
| 		if (data->searchmark == NULL) { | ||||
| 			if (data->timeout) { | ||||
| 				size = xsnprintf(hdr, sizeof hdr, | ||||
| 			    		"(timed out) [%u/%u]", data->oy, | ||||
| 					screen_hsize(data->backing)); | ||||
| 				    "(timed out) [%u/%u]", data->oy, hsize); | ||||
| 			} else { | ||||
| 				size = xsnprintf(hdr, sizeof hdr, | ||||
| 					"[%u/%u]", data->oy, | ||||
| 					screen_hsize(data->backing)); | ||||
| 				    "[%u/%u]", data->oy, hsize); | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (data->searchthis == -1) { | ||||
| 				size = xsnprintf(hdr, sizeof hdr, | ||||
| 				    "(%u results) [%d/%u]", data->searchcount, | ||||
| 				    data->oy, screen_hsize(data->backing)); | ||||
| 				    data->oy, hsize); | ||||
| 			} else { | ||||
| 				size = xsnprintf(hdr, sizeof hdr, | ||||
| 				    "(%u/%u results) [%d/%u]", data->searchthis, | ||||
| 				    data->searchcount, data->oy, | ||||
| 				    screen_hsize(data->backing)); | ||||
| 				    data->searchcount, data->oy, hsize); | ||||
| 			} | ||||
| 		} | ||||
| 		if (size > screen_size_x(s)) | ||||
| @@ -3000,8 +3006,7 @@ window_copy_write_line(struct window_mode_entry *wme, | ||||
|  | ||||
| 	if (size < screen_size_x(s)) { | ||||
| 		screen_write_cursormove(ctx, 0, py, 0); | ||||
| 		screen_write_copy(ctx, data->backing, 0, | ||||
| 		    (screen_hsize(data->backing) - data->oy) + py, | ||||
| 		screen_write_copy(ctx, data->backing, 0, hsize - data->oy + py, | ||||
| 		    screen_size_x(s) - size, 1, data->searchmark, &gc); | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								window.c
									
									
									
									
									
								
							| @@ -1067,8 +1067,9 @@ window_pane_get_palette(struct window_pane *wp, int c) | ||||
| } | ||||
|  | ||||
| int | ||||
| window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode, | ||||
|     struct cmd_find_state *fs, struct args *args) | ||||
| window_pane_set_mode(struct window_pane *wp, struct window_pane *swp, | ||||
|     const struct window_mode *mode, struct cmd_find_state *fs, | ||||
|     struct args *args) | ||||
| { | ||||
| 	struct window_mode_entry	*wme; | ||||
|  | ||||
| @@ -1085,6 +1086,7 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode, | ||||
| 	} else { | ||||
| 		wme = xcalloc(1, sizeof *wme); | ||||
| 		wme->wp = wp; | ||||
| 		wme->swp = swp; | ||||
| 		wme->mode = mode; | ||||
| 		wme->prefix = 1; | ||||
| 		TAILQ_INSERT_HEAD(&wp->modes, wme, entry); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm