mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Allow panes to be empty (no command), output can be piped to them with
split-window or display-message -I.
This commit is contained in:
		@@ -39,8 +39,8 @@ const struct cmd_entry cmd_display_message_entry = {
 | 
				
			|||||||
	.name = "display-message",
 | 
						.name = "display-message",
 | 
				
			||||||
	.alias = "display",
 | 
						.alias = "display",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "ac:pt:F:v", 0, 1 },
 | 
						.args = { "ac:Ipt:F:v", 0, 1 },
 | 
				
			||||||
	.usage = "[-apv] [-c target-client] [-F format] "
 | 
						.usage = "[-aIpv] [-c target-client] [-F format] "
 | 
				
			||||||
		 CMD_TARGET_PANE_USAGE " [message]",
 | 
							 CMD_TARGET_PANE_USAGE " [message]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
@@ -66,10 +66,19 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	struct winlink		*wl = item->target.wl;
 | 
						struct winlink		*wl = item->target.wl;
 | 
				
			||||||
	struct window_pane	*wp = item->target.wp;
 | 
						struct window_pane	*wp = item->target.wp;
 | 
				
			||||||
	const char		*template;
 | 
						const char		*template;
 | 
				
			||||||
	char			*msg;
 | 
						char			*msg, *cause;
 | 
				
			||||||
	struct format_tree	*ft;
 | 
						struct format_tree	*ft;
 | 
				
			||||||
	int			 flags;
 | 
						int			 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (args_has(args, 'I')) {
 | 
				
			||||||
 | 
							if (window_pane_start_input(wp, item, &cause) != 0) {
 | 
				
			||||||
 | 
								cmdq_error(item, "%s", cause);
 | 
				
			||||||
 | 
								free(cause);
 | 
				
			||||||
 | 
								return (CMD_RETURN_ERROR);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (CMD_RETURN_WAIT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'F') && args->argc != 0) {
 | 
						if (args_has(args, 'F') && args->argc != 0) {
 | 
				
			||||||
		cmdq_error(item, "only one of -F or argument must be given");
 | 
							cmdq_error(item, "only one of -F or argument must be given");
 | 
				
			||||||
		return (CMD_RETURN_ERROR);
 | 
							return (CMD_RETURN_ERROR);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,9 +40,10 @@ const struct cmd_entry cmd_split_window_entry = {
 | 
				
			|||||||
	.name = "split-window",
 | 
						.name = "split-window",
 | 
				
			||||||
	.alias = "splitw",
 | 
						.alias = "splitw",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "bc:de:fF:l:hp:Pt:v", 0, -1 },
 | 
						.args = { "bc:de:fF:hIl:p:Pt:v", 0, -1 },
 | 
				
			||||||
	.usage = "[-bdefhvP] [-c start-directory] [-e environment] [-F format] "
 | 
						.usage = "[-bdefhIPv] [-c start-directory] [-e environment] "
 | 
				
			||||||
		 "[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
 | 
							 "[-F format] [-p percentage|-l size] " CMD_TARGET_PANE_USAGE
 | 
				
			||||||
 | 
							 " [command]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +64,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	enum layout_type	 type;
 | 
						enum layout_type	 type;
 | 
				
			||||||
	struct layout_cell	*lc;
 | 
						struct layout_cell	*lc;
 | 
				
			||||||
	struct cmd_find_state	 fs;
 | 
						struct cmd_find_state	 fs;
 | 
				
			||||||
	int			 size, percentage, flags;
 | 
						int			 size, percentage, flags, input;
 | 
				
			||||||
	const char		*template, *add;
 | 
						const char		*template, *add;
 | 
				
			||||||
	char			*cause, *cp;
 | 
						char			*cause, *cp;
 | 
				
			||||||
	struct args_value	*value;
 | 
						struct args_value	*value;
 | 
				
			||||||
@@ -94,12 +95,15 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
		size = -1;
 | 
							size = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server_unzoom_window(wp->window);
 | 
						server_unzoom_window(wp->window);
 | 
				
			||||||
 | 
						input = (args_has(args, 'I') && args->argc == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flags = 0;
 | 
						flags = 0;
 | 
				
			||||||
	if (args_has(args, 'b'))
 | 
						if (args_has(args, 'b'))
 | 
				
			||||||
		flags |= SPAWN_BEFORE;
 | 
							flags |= SPAWN_BEFORE;
 | 
				
			||||||
	if (args_has(args, 'f'))
 | 
						if (args_has(args, 'f'))
 | 
				
			||||||
		flags |= SPAWN_FULLSIZE;
 | 
							flags |= SPAWN_FULLSIZE;
 | 
				
			||||||
 | 
						if (input || (args->argc == 1 && *args->argv[0] == '\0'))
 | 
				
			||||||
 | 
							flags |= SPAWN_EMPTY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lc = layout_split_pane(wp, type, size, flags);
 | 
						lc = layout_split_pane(wp, type, size, flags);
 | 
				
			||||||
	if (lc == NULL) {
 | 
						if (lc == NULL) {
 | 
				
			||||||
@@ -134,10 +138,18 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
		sc.flags |= SPAWN_DETACHED;
 | 
							sc.flags |= SPAWN_DETACHED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
 | 
						if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
 | 
				
			||||||
 | 
							layout_close_pane(new_wp);
 | 
				
			||||||
		cmdq_error(item, "create pane failed: %s", cause);
 | 
							cmdq_error(item, "create pane failed: %s", cause);
 | 
				
			||||||
		free(cause);
 | 
							free(cause);
 | 
				
			||||||
		return (CMD_RETURN_ERROR);
 | 
							return (CMD_RETURN_ERROR);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (input && window_pane_start_input(new_wp, item, &cause) != 0) {
 | 
				
			||||||
 | 
							layout_close_pane(new_wp);
 | 
				
			||||||
 | 
							window_remove_pane(wp->window, new_wp);
 | 
				
			||||||
 | 
							cmdq_error(item, "%s", cause);
 | 
				
			||||||
 | 
							free(cause);
 | 
				
			||||||
 | 
							return (CMD_RETURN_ERROR);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (!args_has(args, 'd'))
 | 
						if (!args_has(args, 'd'))
 | 
				
			||||||
		cmd_find_from_winlink_pane(current, wl, new_wp, 0);
 | 
							cmd_find_from_winlink_pane(current, wl, new_wp, 0);
 | 
				
			||||||
	server_redraw_window(wp->window);
 | 
						server_redraw_window(wp->window);
 | 
				
			||||||
@@ -155,5 +167,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	cmdq_insert_hook(s, item, &fs, "after-split-window");
 | 
						cmdq_insert_hook(s, item, &fs, "after-split-window");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	environ_free(sc.environ);
 | 
						environ_free(sc.environ);
 | 
				
			||||||
 | 
						if (input)
 | 
				
			||||||
 | 
							return (CMD_RETURN_WAIT);
 | 
				
			||||||
	return (CMD_RETURN_NORMAL);
 | 
						return (CMD_RETURN_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								format.c
									
									
									
									
									
								
							@@ -2031,7 +2031,10 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(status))
 | 
						if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(status))
 | 
				
			||||||
		format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
 | 
							format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
 | 
				
			||||||
 | 
						if (~wp->flags & PANE_EMPTY)
 | 
				
			||||||
		format_add(ft, "pane_dead", "%d", wp->fd == -1);
 | 
							format_add(ft, "pane_dead", "%d", wp->fd == -1);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							format_add(ft, "pane_dead", "0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	format_add(ft, "pane_left", "%u", wp->xoff);
 | 
						format_add(ft, "pane_left", "%u", wp->xoff);
 | 
				
			||||||
	format_add(ft, "pane_top", "%u", wp->yoff);
 | 
						format_add(ft, "pane_top", "%u", wp->yoff);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								input.c
									
									
									
									
									
								
							@@ -1185,6 +1185,8 @@ input_c0_dispatch(struct input_ctx *ictx)
 | 
				
			|||||||
	case '\013':	/* VT */
 | 
						case '\013':	/* VT */
 | 
				
			||||||
	case '\014':	/* FF */
 | 
						case '\014':	/* FF */
 | 
				
			||||||
		screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
 | 
							screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
 | 
				
			||||||
 | 
							if (s->mode & MODE_CRLF)
 | 
				
			||||||
 | 
								screen_write_carriagereturn(sctx);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '\015':	/* CR */
 | 
						case '\015':	/* CR */
 | 
				
			||||||
		screen_write_carriagereturn(sctx);
 | 
							screen_write_carriagereturn(sctx);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1671,8 +1671,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
 | 
				
			|||||||
			evbuffer_add(c->stdin_data, stdindata.data,
 | 
								evbuffer_add(c->stdin_data, stdindata.data,
 | 
				
			||||||
			    stdindata.size);
 | 
								    stdindata.size);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		c->stdin_callback(c, c->stdin_closed,
 | 
							c->stdin_callback(c, c->stdin_closed, c->stdin_callback_data);
 | 
				
			||||||
		    c->stdin_callback_data);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case MSG_RESIZE:
 | 
						case MSG_RESIZE:
 | 
				
			||||||
		if (datalen != 0)
 | 
							if (datalen != 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -439,7 +439,6 @@ server_check_unattached(void)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Set stdin callback. */
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
 | 
					server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
 | 
				
			||||||
    void *), void *cb_data, char **cause)
 | 
					    void *), void *cb_data, char **cause)
 | 
				
			||||||
@@ -453,7 +452,7 @@ server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
 | 
				
			|||||||
		return (-1);
 | 
							return (-1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (c->stdin_callback != NULL) {
 | 
						if (c->stdin_callback != NULL) {
 | 
				
			||||||
		*cause = xstrdup("stdin in use");
 | 
							*cause = xstrdup("stdin is in use");
 | 
				
			||||||
		return (-1);
 | 
							return (-1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								spawn.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								spawn.c
									
									
									
									
									
								
							@@ -332,6 +332,14 @@ spawn_pane(struct spawn_context *sc, char **cause)
 | 
				
			|||||||
	cmd_log_argv(new_wp->argc, new_wp->argv, __func__);
 | 
						cmd_log_argv(new_wp->argc, new_wp->argv, __func__);
 | 
				
			||||||
	environ_log(child, "%s: environment ", __func__);
 | 
						environ_log(child, "%s: environment ", __func__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If the command is empty, don't fork a child process. */
 | 
				
			||||||
 | 
						if (sc->flags & SPAWN_EMPTY) {
 | 
				
			||||||
 | 
							new_wp->flags |= PANE_EMPTY;
 | 
				
			||||||
 | 
							new_wp->base.mode &= ~MODE_CURSOR;
 | 
				
			||||||
 | 
							new_wp->base.mode |= MODE_CRLF;
 | 
				
			||||||
 | 
							goto complete;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Initialize the window size. */
 | 
						/* Initialize the window size. */
 | 
				
			||||||
	memset(&ws, 0, sizeof ws);
 | 
						memset(&ws, 0, sizeof ws);
 | 
				
			||||||
	ws.ws_col = screen_size_x(&new_wp->base);
 | 
						ws.ws_col = screen_size_x(&new_wp->base);
 | 
				
			||||||
@@ -355,25 +363,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* In the parent process, everything is done now. */
 | 
						/* In the parent process, everything is done now. */
 | 
				
			||||||
	if (new_wp->pid != 0) {
 | 
						if (new_wp->pid != 0)
 | 
				
			||||||
		new_wp->pipe_off = 0;
 | 
							goto complete;
 | 
				
			||||||
		new_wp->flags &= ~PANE_EXITED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sigprocmask(SIG_SETMASK, &oldset, NULL);
 | 
					 | 
				
			||||||
		window_pane_set_event(new_wp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (sc->flags & SPAWN_RESPAWN)
 | 
					 | 
				
			||||||
			return (new_wp);
 | 
					 | 
				
			||||||
		if ((~sc->flags & SPAWN_DETACHED) || w->active == NULL) {
 | 
					 | 
				
			||||||
			if (sc->flags & SPAWN_NONOTIFY)
 | 
					 | 
				
			||||||
				window_set_active_pane(w, new_wp, 0);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				window_set_active_pane(w, new_wp, 1);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (~sc->flags & SPAWN_NONOTIFY)
 | 
					 | 
				
			||||||
			notify_window("window-layout-changed", w);
 | 
					 | 
				
			||||||
		return (new_wp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Child process. Change to the working directory or home if that
 | 
						 * Child process. Change to the working directory or home if that
 | 
				
			||||||
@@ -433,4 +424,23 @@ spawn_pane(struct spawn_context *sc, char **cause)
 | 
				
			|||||||
		xasprintf(&argv0, "-%s", new_wp->shell);
 | 
							xasprintf(&argv0, "-%s", new_wp->shell);
 | 
				
			||||||
	execl(new_wp->shell, argv0, (char *)NULL);
 | 
						execl(new_wp->shell, argv0, (char *)NULL);
 | 
				
			||||||
	_exit(1);
 | 
						_exit(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					complete:
 | 
				
			||||||
 | 
						new_wp->pipe_off = 0;
 | 
				
			||||||
 | 
						new_wp->flags &= ~PANE_EXITED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigprocmask(SIG_SETMASK, &oldset, NULL);
 | 
				
			||||||
 | 
						window_pane_set_event(new_wp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sc->flags & SPAWN_RESPAWN)
 | 
				
			||||||
 | 
							return (new_wp);
 | 
				
			||||||
 | 
						if ((~sc->flags & SPAWN_DETACHED) || w->active == NULL) {
 | 
				
			||||||
 | 
							if (sc->flags & SPAWN_NONOTIFY)
 | 
				
			||||||
 | 
								window_set_active_pane(w, new_wp, 0);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								window_set_active_pane(w, new_wp, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (~sc->flags & SPAWN_NONOTIFY)
 | 
				
			||||||
 | 
							notify_window("window-layout-changed", w);
 | 
				
			||||||
 | 
						return (new_wp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								tmux.1
									
									
									
									
									
								
							@@ -2204,7 +2204,7 @@ is given and the selected window is already the current window,
 | 
				
			|||||||
the command behaves like
 | 
					the command behaves like
 | 
				
			||||||
.Ic last-window .
 | 
					.Ic last-window .
 | 
				
			||||||
.It Xo Ic split-window
 | 
					.It Xo Ic split-window
 | 
				
			||||||
.Op Fl bdfhvP
 | 
					.Op Fl bdfhIvP
 | 
				
			||||||
.Op Fl c Ar start-directory
 | 
					.Op Fl c Ar start-directory
 | 
				
			||||||
.Op Fl e Ar environment
 | 
					.Op Fl e Ar environment
 | 
				
			||||||
.Oo Fl l
 | 
					.Oo Fl l
 | 
				
			||||||
@@ -2240,6 +2240,24 @@ option creates a new pane spanning the full window height (with
 | 
				
			|||||||
or full window width (with
 | 
					or full window width (with
 | 
				
			||||||
.Fl v ) ,
 | 
					.Fl v ) ,
 | 
				
			||||||
instead of splitting the active pane.
 | 
					instead of splitting the active pane.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					An empty
 | 
				
			||||||
 | 
					.Ar shell-command
 | 
				
			||||||
 | 
					('') will create a pane with no command running in it.
 | 
				
			||||||
 | 
					Output can be sent to such a pane with the
 | 
				
			||||||
 | 
					.Ic display-message
 | 
				
			||||||
 | 
					command.
 | 
				
			||||||
 | 
					The
 | 
				
			||||||
 | 
					.Fl I
 | 
				
			||||||
 | 
					flag (if
 | 
				
			||||||
 | 
					.Ar shell-command
 | 
				
			||||||
 | 
					is not specified or empty)
 | 
				
			||||||
 | 
					will create an empty pane and forward any output from stdin to it.
 | 
				
			||||||
 | 
					For example:
 | 
				
			||||||
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
 | 
					$ make 2>&1|tmux splitw -dI &
 | 
				
			||||||
 | 
					.Ed
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
All other options have the same meaning as for the
 | 
					All other options have the same meaning as for the
 | 
				
			||||||
.Ic new-window
 | 
					.Ic new-window
 | 
				
			||||||
command.
 | 
					command.
 | 
				
			||||||
@@ -2822,7 +2840,7 @@ This option should be configured when
 | 
				
			|||||||
is used as a login shell.
 | 
					is used as a login shell.
 | 
				
			||||||
.It Ic default-size Ar XxY
 | 
					.It Ic default-size Ar XxY
 | 
				
			||||||
Set the default size of new windows when the
 | 
					Set the default size of new windows when the
 | 
				
			||||||
.Ar window-size
 | 
					.Ic window-size
 | 
				
			||||||
option is set to manual or when a session is created with
 | 
					option is set to manual or when a session is created with
 | 
				
			||||||
.Ic new-session
 | 
					.Ic new-session
 | 
				
			||||||
.Fl d .
 | 
					.Fl d .
 | 
				
			||||||
@@ -4428,7 +4446,7 @@ option.
 | 
				
			|||||||
This command works only from inside
 | 
					This command works only from inside
 | 
				
			||||||
.Nm .
 | 
					.Nm .
 | 
				
			||||||
.It Xo Ic display-message
 | 
					.It Xo Ic display-message
 | 
				
			||||||
.Op Fl apv
 | 
					.Op Fl aIpv
 | 
				
			||||||
.Op Fl c Ar target-client
 | 
					.Op Fl c Ar target-client
 | 
				
			||||||
.Op Fl t Ar target-pane
 | 
					.Op Fl t Ar target-pane
 | 
				
			||||||
.Op Ar message
 | 
					.Op Ar message
 | 
				
			||||||
@@ -4455,6 +4473,10 @@ is given, otherwise the active pane for the session attached to
 | 
				
			|||||||
prints verbose logging as the format is parsed and
 | 
					prints verbose logging as the format is parsed and
 | 
				
			||||||
.Fl a
 | 
					.Fl a
 | 
				
			||||||
lists the format variables and their values.
 | 
					lists the format variables and their values.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					.Fl I
 | 
				
			||||||
 | 
					forwards any input read from stdin to the empty pane given by
 | 
				
			||||||
 | 
					.Ar target-pane .
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh BUFFERS
 | 
					.Sh BUFFERS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							@@ -522,6 +522,7 @@ struct msg_stderr_data {
 | 
				
			|||||||
#define MODE_FOCUSON 0x800
 | 
					#define MODE_FOCUSON 0x800
 | 
				
			||||||
#define MODE_MOUSE_ALL 0x1000
 | 
					#define MODE_MOUSE_ALL 0x1000
 | 
				
			||||||
#define MODE_ORIGIN 0x2000
 | 
					#define MODE_ORIGIN 0x2000
 | 
				
			||||||
 | 
					#define MODE_CRLF 0x4000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ALL_MODES 0xffffff
 | 
					#define ALL_MODES 0xffffff
 | 
				
			||||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
 | 
					#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
 | 
				
			||||||
@@ -802,6 +803,7 @@ struct window_pane {
 | 
				
			|||||||
#define PANE_EXITED 0x100
 | 
					#define PANE_EXITED 0x100
 | 
				
			||||||
#define PANE_STATUSREADY 0x200
 | 
					#define PANE_STATUSREADY 0x200
 | 
				
			||||||
#define PANE_STATUSDRAWN 0x400
 | 
					#define PANE_STATUSDRAWN 0x400
 | 
				
			||||||
 | 
					#define PANE_EMPTY 0x800
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int		 argc;
 | 
						int		 argc;
 | 
				
			||||||
	char	       **argv;
 | 
						char	       **argv;
 | 
				
			||||||
@@ -1598,6 +1600,7 @@ struct spawn_context {
 | 
				
			|||||||
#define SPAWN_BEFORE 0x8
 | 
					#define SPAWN_BEFORE 0x8
 | 
				
			||||||
#define SPAWN_NONOTIFY 0x10
 | 
					#define SPAWN_NONOTIFY 0x10
 | 
				
			||||||
#define SPAWN_FULLSIZE 0x20
 | 
					#define SPAWN_FULLSIZE 0x20
 | 
				
			||||||
 | 
					#define SPAWN_EMPTY 0x40
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tmux.c */
 | 
					/* tmux.c */
 | 
				
			||||||
@@ -2317,6 +2320,8 @@ void		 window_add_ref(struct window *, const char *);
 | 
				
			|||||||
void		 window_remove_ref(struct window *, const char *);
 | 
					void		 window_remove_ref(struct window *, const char *);
 | 
				
			||||||
void		 winlink_clear_flags(struct winlink *);
 | 
					void		 winlink_clear_flags(struct winlink *);
 | 
				
			||||||
int		 winlink_shuffle_up(struct session *, struct winlink *);
 | 
					int		 winlink_shuffle_up(struct session *, struct winlink *);
 | 
				
			||||||
 | 
					int		 window_pane_start_input(struct window_pane *,
 | 
				
			||||||
 | 
							     struct cmdq_item *, char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* layout.c */
 | 
					/* layout.c */
 | 
				
			||||||
u_int		 layout_count_cells(struct layout_cell *);
 | 
					u_int		 layout_count_cells(struct layout_cell *);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								window.c
									
									
									
									
									
								
							@@ -72,6 +72,11 @@ const struct window_mode *all_window_modes[] = {
 | 
				
			|||||||
	NULL
 | 
						NULL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct window_pane_input_data {
 | 
				
			||||||
 | 
						struct cmdq_item	*item;
 | 
				
			||||||
 | 
						u_int			 wp;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct window_pane *window_pane_create(struct window *, u_int, u_int,
 | 
					static struct window_pane *window_pane_create(struct window *, u_int, u_int,
 | 
				
			||||||
		    u_int);
 | 
							    u_int);
 | 
				
			||||||
static void	window_pane_destroy(struct window_pane *);
 | 
					static void	window_pane_destroy(struct window_pane *);
 | 
				
			||||||
@@ -1466,3 +1471,45 @@ winlink_shuffle_up(struct session *s, struct winlink *wl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return (idx);
 | 
						return (idx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_pane_input_callback(struct client *c, int closed, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane_input_data	*cdata = data;
 | 
				
			||||||
 | 
						struct window_pane		*wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wp = window_pane_find_by_id(cdata->wp);
 | 
				
			||||||
 | 
						if (wp == NULL || closed || c->flags & CLIENT_DEAD) {
 | 
				
			||||||
 | 
							c->stdin_callback = NULL;
 | 
				
			||||||
 | 
							server_client_unref(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cdata->item->flags &= ~CMDQ_WAITING;
 | 
				
			||||||
 | 
							free(cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (evbuffer_add_buffer(wp->event->input, c->stdin_data) != 0)
 | 
				
			||||||
 | 
							evbuffer_drain(c->stdin_data, EVBUFFER_LENGTH(c->stdin_data));
 | 
				
			||||||
 | 
						input_parse(wp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					window_pane_start_input(struct window_pane *wp, struct cmdq_item *item,
 | 
				
			||||||
 | 
					    char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client			*c = item->client;
 | 
				
			||||||
 | 
						struct window_pane_input_data	*cdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (~wp->flags & PANE_EMPTY) {
 | 
				
			||||||
 | 
							*cause = xstrdup("pane is not empty");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						cdata->item = item;
 | 
				
			||||||
 | 
						cdata->wp = wp->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (server_set_stdin_callback(c, window_pane_input_callback, cdata,
 | 
				
			||||||
 | 
						    cause));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user