mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Sync OpenBSD patchset 953:
Add initial framework for more powerful formatting of command output and
use it for list-{panes,windows,sessions}. This allows more descriptive
replacements (such as #{session_name}) and conditionals.
Later this will be used for status_replace and list-keys and other
places.
			
			
This commit is contained in:
		
							
								
								
									
										106
									
								
								cmd-list-panes.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								cmd-list-panes.c
									
									
									
									
									
								
							@@ -28,15 +28,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int	cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
 | 
					int	cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void	cmd_list_panes_server(struct cmd_ctx *);
 | 
					void	cmd_list_panes_server(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
void	cmd_list_panes_session(struct session *, struct cmd_ctx *, int);
 | 
					void	cmd_list_panes_session(
 | 
				
			||||||
void	cmd_list_panes_window(
 | 
						    struct cmd *, struct session *, struct cmd_ctx *, int);
 | 
				
			||||||
 | 
					void	cmd_list_panes_window(struct cmd *,
 | 
				
			||||||
	    struct session *, struct winlink *, struct cmd_ctx *, int);
 | 
						    struct session *, struct winlink *, struct cmd_ctx *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_list_panes_entry = {
 | 
					const struct cmd_entry cmd_list_panes_entry = {
 | 
				
			||||||
	"list-panes", "lsp",
 | 
						"list-panes", "lsp",
 | 
				
			||||||
	"ast:", 0, 0,
 | 
						"asF:t:", 0, 0,
 | 
				
			||||||
	"[-as] [-t target]",
 | 
						"[-as] [-F format] [-t target]",
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
@@ -51,87 +52,92 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
	struct winlink	*wl;
 | 
						struct winlink	*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'a'))
 | 
						if (args_has(args, 'a'))
 | 
				
			||||||
		cmd_list_panes_server(ctx);
 | 
							cmd_list_panes_server(self, ctx);
 | 
				
			||||||
	else if (args_has(args, 's')) {
 | 
						else if (args_has(args, 's')) {
 | 
				
			||||||
		s = cmd_find_session(ctx, args_get(args, 't'), 0);
 | 
							s = cmd_find_session(ctx, args_get(args, 't'), 0);
 | 
				
			||||||
		if (s == NULL)
 | 
							if (s == NULL)
 | 
				
			||||||
			return (-1);
 | 
								return (-1);
 | 
				
			||||||
		cmd_list_panes_session(s, ctx, 1);
 | 
							cmd_list_panes_session(self, s, ctx, 1);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		wl = cmd_find_window(ctx, args_get(args, 't'), &s);
 | 
							wl = cmd_find_window(ctx, args_get(args, 't'), &s);
 | 
				
			||||||
		if (wl == NULL)
 | 
							if (wl == NULL)
 | 
				
			||||||
			return (-1);
 | 
								return (-1);
 | 
				
			||||||
		cmd_list_panes_window(s, wl, ctx, 0);
 | 
							cmd_list_panes_window(self, s, wl, ctx, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_list_panes_server(struct cmd_ctx *ctx)
 | 
					cmd_list_panes_server(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct session	*s;
 | 
						struct session	*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH(s, sessions, &sessions)
 | 
						RB_FOREACH(s, sessions, &sessions)
 | 
				
			||||||
		cmd_list_panes_session(s, ctx, 2);
 | 
							cmd_list_panes_session(self, s, ctx, 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_list_panes_session(struct session *s, struct cmd_ctx *ctx, int type)
 | 
					cmd_list_panes_session(
 | 
				
			||||||
 | 
					    struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct winlink	*wl;
 | 
						struct winlink	*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH(wl, winlinks, &s->windows)
 | 
						RB_FOREACH(wl, winlinks, &s->windows)
 | 
				
			||||||
		cmd_list_panes_window(s, wl, ctx, type);
 | 
							cmd_list_panes_window(self, s, wl, ctx, type);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_list_panes_window(
 | 
					cmd_list_panes_window(struct cmd *self,
 | 
				
			||||||
    struct session *s, struct winlink *wl, struct cmd_ctx *ctx, int type)
 | 
					    struct session *s, struct winlink *wl, struct cmd_ctx *ctx, int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct args		*args = self->args;
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	struct grid		*gd;
 | 
						u_int			 n;
 | 
				
			||||||
	struct grid_line	*gl;
 | 
						struct format_tree	*ft;
 | 
				
			||||||
	u_int			 i, n;
 | 
						const char		*template;
 | 
				
			||||||
	unsigned long long	 size;
 | 
						char			*line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template = args_get(args, 'F');
 | 
				
			||||||
 | 
						if (template == NULL) {
 | 
				
			||||||
 | 
							switch (type) {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								template = "#{line}: "
 | 
				
			||||||
 | 
								    "[#{pane_width}x#{pane_height}] [history "
 | 
				
			||||||
 | 
								    "#{history_size}/#{history_limit}, "
 | 
				
			||||||
 | 
								    "#{history_bytes} bytes] #{pane_id}"
 | 
				
			||||||
 | 
								    "#{?pane_active, (active),}#{?pane_dead, (dead),}";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								template = "#{window_index}.#{line}: "
 | 
				
			||||||
 | 
								    "[#{pane_width}x#{pane_height}] [history "
 | 
				
			||||||
 | 
								    "#{history_size}/#{history_limit}, "
 | 
				
			||||||
 | 
								    "#{history_bytes} bytes] #{pane_id}"
 | 
				
			||||||
 | 
								    "#{?pane_active, (active),}#{?pane_dead, (dead),}";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 2:
 | 
				
			||||||
 | 
								template = "#{session_name}:#{window_index}.#{line}: "
 | 
				
			||||||
 | 
								    "[#{pane_width}x#{pane_height}] [history "
 | 
				
			||||||
 | 
								    "#{history_size}/#{history_limit}, "
 | 
				
			||||||
 | 
								    "#{history_bytes} bytes] #{pane_id}"
 | 
				
			||||||
 | 
								    "#{?pane_active, (active),}#{?pane_dead, (dead),}";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n = 0;
 | 
						n = 0;
 | 
				
			||||||
	TAILQ_FOREACH(wp, &wl->window->panes, entry) {
 | 
						TAILQ_FOREACH(wp, &wl->window->panes, entry) {
 | 
				
			||||||
		gd = wp->base.grid;
 | 
							ft = format_create();
 | 
				
			||||||
 | 
							format_add(ft, "line", "%u", n);
 | 
				
			||||||
 | 
							format_session(ft, s);
 | 
				
			||||||
 | 
							format_winlink(ft, s, wl);
 | 
				
			||||||
 | 
							format_window_pane(ft, wp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size = 0;
 | 
							line = format_expand(ft, template);
 | 
				
			||||||
		for (i = 0; i < gd->hsize; i++) {
 | 
							ctx->print(ctx, "%s", line);
 | 
				
			||||||
			gl = &gd->linedata[i];
 | 
							xfree(line);
 | 
				
			||||||
			size += gl->cellsize * sizeof *gl->celldata;
 | 
					 | 
				
			||||||
			size += gl->utf8size * sizeof *gl->utf8data;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		size += gd->hsize * sizeof *gd->linedata;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (type) {
 | 
							format_free(ft);
 | 
				
			||||||
		case 0:
 | 
					 | 
				
			||||||
			ctx->print(ctx,
 | 
					 | 
				
			||||||
			    "%u: [%ux%u] [history %u/%u, %llu bytes] %%%u%s%s",
 | 
					 | 
				
			||||||
			    n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
 | 
					 | 
				
			||||||
			    wp->id, wp == wp->window->active ? " (active)" : "",
 | 
					 | 
				
			||||||
			    wp->fd == -1 ? " (dead)" : "");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 1:
 | 
					 | 
				
			||||||
			ctx->print(ctx,
 | 
					 | 
				
			||||||
			    "%d.%u: [%ux%u] [history %u/%u, %llu bytes] "
 | 
					 | 
				
			||||||
			    "%%%u%s%s", wl->idx,
 | 
					 | 
				
			||||||
			    n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
 | 
					 | 
				
			||||||
			    wp->id, wp == wp->window->active ? " (active)" : "",
 | 
					 | 
				
			||||||
			    wp->fd == -1 ? " (dead)" : "");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 2:
 | 
					 | 
				
			||||||
			ctx->print(ctx,
 | 
					 | 
				
			||||||
			    "%s:%d.%u: [%ux%u] [history %u/%u, %llu bytes] "
 | 
					 | 
				
			||||||
			    "%%%u%s%s", s->name, wl->idx,
 | 
					 | 
				
			||||||
			    n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
 | 
					 | 
				
			||||||
			    wp->id, wp == wp->window->active ? " (active)" : "",
 | 
					 | 
				
			||||||
			    wp->fd == -1 ? " (dead)" : "");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		n++;
 | 
							n++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,40 +31,45 @@ int	cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_list_sessions_entry = {
 | 
					const struct cmd_entry cmd_list_sessions_entry = {
 | 
				
			||||||
	"list-sessions", "ls",
 | 
						"list-sessions", "ls",
 | 
				
			||||||
	"", 0, 0,
 | 
						"F:", 0, 0,
 | 
				
			||||||
	"",
 | 
						"[-F format]",
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
	cmd_list_sessions_exec
 | 
						cmd_list_sessions_exec
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ARGSUSED */
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
					cmd_list_sessions_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct args		*args = self->args;
 | 
				
			||||||
	struct session		*s;
 | 
						struct session		*s;
 | 
				
			||||||
	struct session_group	*sg;
 | 
						u_int		 	 n;
 | 
				
			||||||
	char			*tim, tmp[64];
 | 
						struct format_tree	*ft;
 | 
				
			||||||
	u_int			 idx;
 | 
						const char		*template;
 | 
				
			||||||
	time_t			 t;
 | 
						char			*line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template = args_get(args, 'F');
 | 
				
			||||||
 | 
						if (template == NULL) {
 | 
				
			||||||
 | 
							template = "#{session_name}: #{session_windows} windows "
 | 
				
			||||||
 | 
							    "(created #{session_created_string}) [#{session_width}x"
 | 
				
			||||||
 | 
							    "#{session_height}]#{?session_grouped, (group ,}"
 | 
				
			||||||
 | 
							    "#{session_group}#{?session_grouped,),}"
 | 
				
			||||||
 | 
							    "#{?session_attached, (attached),}";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
						RB_FOREACH(s, sessions, &sessions) {
 | 
				
			||||||
		sg = session_group_find(s);
 | 
							ft = format_create();
 | 
				
			||||||
		if (sg == NULL)
 | 
							format_add(ft, "line", "%u", n);
 | 
				
			||||||
			*tmp = '\0';
 | 
							format_session(ft, s);
 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			idx = session_group_index(sg);
 | 
					 | 
				
			||||||
			xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		t = s->creation_time.tv_sec;
 | 
							line = format_expand(ft, template);
 | 
				
			||||||
		tim = ctime(&t);
 | 
							ctx->print(ctx, "%s", line);
 | 
				
			||||||
		*strchr(tim, '\n') = '\0';
 | 
							xfree(line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s%s",
 | 
							format_free(ft);
 | 
				
			||||||
		    s->name, winlink_count(&s->windows), tim, s->sx, s->sy,
 | 
							n++;
 | 
				
			||||||
		    tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,13 +28,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int	cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
 | 
					int	cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void	cmd_list_windows_server(struct cmd_ctx *);
 | 
					void	cmd_list_windows_server(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
void	cmd_list_windows_session(struct session *, struct cmd_ctx *, int);
 | 
					void	cmd_list_windows_session(
 | 
				
			||||||
 | 
						    struct cmd *, struct session *, struct cmd_ctx *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_list_windows_entry = {
 | 
					const struct cmd_entry cmd_list_windows_entry = {
 | 
				
			||||||
	"list-windows", "lsw",
 | 
						"list-windows", "lsw",
 | 
				
			||||||
	"at:", 0, 0,
 | 
						"aF:t:", 0, 0,
 | 
				
			||||||
	"[-a] " CMD_TARGET_SESSION_USAGE,
 | 
						"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
@@ -48,45 +49,69 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
	struct session	*s;
 | 
						struct session	*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'a'))
 | 
						if (args_has(args, 'a'))
 | 
				
			||||||
		cmd_list_windows_server(ctx);
 | 
							cmd_list_windows_server(self, ctx);
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		s = cmd_find_session(ctx, args_get(args, 't'), 0);
 | 
							s = cmd_find_session(ctx, args_get(args, 't'), 0);
 | 
				
			||||||
		if (s == NULL)
 | 
							if (s == NULL)
 | 
				
			||||||
			return (-1);
 | 
								return (-1);
 | 
				
			||||||
		cmd_list_windows_session(s, ctx, 0);
 | 
							cmd_list_windows_session(self, s, ctx, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_list_windows_server(struct cmd_ctx *ctx)
 | 
					cmd_list_windows_server(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct session	*s;
 | 
						struct session	*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH(s, sessions, &sessions)
 | 
						RB_FOREACH(s, sessions, &sessions)
 | 
				
			||||||
		cmd_list_windows_session(s, ctx, 1);
 | 
							cmd_list_windows_session(self, s, ctx, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_list_windows_session(struct session *s, struct cmd_ctx *ctx, int type)
 | 
					cmd_list_windows_session(
 | 
				
			||||||
 | 
					    struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct winlink	*wl;
 | 
						struct args		*args = self->args;
 | 
				
			||||||
	char		*layout;
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						u_int			n;
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						const char		*template;
 | 
				
			||||||
 | 
						char			*line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH(wl, winlinks, &s->windows) {
 | 
						template = args_get(args, 'F');
 | 
				
			||||||
		layout = layout_dump(wl->window);
 | 
						if (template == NULL) {
 | 
				
			||||||
		if (type) {
 | 
							switch (type) {
 | 
				
			||||||
			ctx->print(ctx, "%s:%d: %s [%ux%u] [layout %s]%s",
 | 
							case 0:
 | 
				
			||||||
			    s->name, wl->idx, wl->window->name, wl->window->sx,
 | 
								template = "#{window_index}: "
 | 
				
			||||||
			    wl->window->sy, layout,
 | 
								    "#{window_name} "
 | 
				
			||||||
			    wl == s->curw ? " (active)" : "");
 | 
								    "[#{window_width}x#{window_height}] "
 | 
				
			||||||
		} else {
 | 
								    "[layout #{window_layout}]"
 | 
				
			||||||
			ctx->print(ctx, "%d: %s [%ux%u] [layout %s]%s",
 | 
								    "#{?window_active, (active),}";
 | 
				
			||||||
			    wl->idx, wl->window->name, wl->window->sx,
 | 
								break;
 | 
				
			||||||
			    wl->window->sy, layout,
 | 
							case 1:
 | 
				
			||||||
			    wl == s->curw ? " (active)" : "");
 | 
								template = "#{session_name):#{window_index}: "
 | 
				
			||||||
 | 
								    "#{window_name} "
 | 
				
			||||||
 | 
								    "[#{window_width}x#{window_height}] "
 | 
				
			||||||
 | 
								    "[layout #{window_layout}]"
 | 
				
			||||||
 | 
								    "#{?window_active, (active),}";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		xfree(layout);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
						RB_FOREACH(wl, winlinks, &s->windows) {
 | 
				
			||||||
 | 
							ft = format_create();
 | 
				
			||||||
 | 
							format_add(ft, "line", "%u", n);
 | 
				
			||||||
 | 
							format_session(ft, s);
 | 
				
			||||||
 | 
							format_winlink(ft, s, wl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							line = format_expand(ft, template);
 | 
				
			||||||
 | 
							ctx->print(ctx, "%s", line);
 | 
				
			||||||
 | 
							xfree(line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							format_free(ft);
 | 
				
			||||||
 | 
							n++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										346
									
								
								format.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								format.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,346 @@
 | 
				
			|||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <netdb.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Build a list of key-value pairs and use them to expand #{key} entries in a
 | 
				
			||||||
 | 
					 * string.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	format_replace(struct format_tree *,
 | 
				
			||||||
 | 
						    const char *, size_t, char **, size_t *, size_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Format key-value replacement entry. */
 | 
				
			||||||
 | 
					RB_GENERATE(format_tree, format_entry, entry, format_cmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Format tree comparison function. */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					format_cmp(struct format_entry *fe1, struct format_entry *fe2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (strcmp(fe1->key, fe2->key));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Single-character aliases. */
 | 
				
			||||||
 | 
					const char *format_aliases[26] = {
 | 
				
			||||||
 | 
						NULL,		/* A */
 | 
				
			||||||
 | 
						NULL,		/* B */
 | 
				
			||||||
 | 
						NULL,		/* C */
 | 
				
			||||||
 | 
						"pane_id",	/* D */
 | 
				
			||||||
 | 
						NULL,		/* E */
 | 
				
			||||||
 | 
						"window_flags",	/* F */
 | 
				
			||||||
 | 
						NULL,		/* G */
 | 
				
			||||||
 | 
						"host",		/* H */
 | 
				
			||||||
 | 
						"window_index",	/* I */
 | 
				
			||||||
 | 
						NULL,		/* J */
 | 
				
			||||||
 | 
						NULL,		/* K */
 | 
				
			||||||
 | 
						NULL,		/* L */
 | 
				
			||||||
 | 
						NULL,		/* M */
 | 
				
			||||||
 | 
						NULL,		/* N */
 | 
				
			||||||
 | 
						NULL,		/* O */
 | 
				
			||||||
 | 
						"pane_index",	/* P */
 | 
				
			||||||
 | 
						NULL,		/* Q */
 | 
				
			||||||
 | 
						NULL,		/* R */
 | 
				
			||||||
 | 
						"session_name",	/* S */
 | 
				
			||||||
 | 
						"pane_title",	/* T */
 | 
				
			||||||
 | 
						NULL,		/* U */
 | 
				
			||||||
 | 
						NULL,		/* V */
 | 
				
			||||||
 | 
						"window_name",	/* W */
 | 
				
			||||||
 | 
						NULL,		/* X */
 | 
				
			||||||
 | 
						NULL,		/* Y */
 | 
				
			||||||
 | 
						NULL 		/* Z */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Create a new tree. */
 | 
				
			||||||
 | 
					struct format_tree *
 | 
				
			||||||
 | 
					format_create(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct format_tree	*ft;
 | 
				
			||||||
 | 
						char			 host[MAXHOSTNAMELEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ft = xmalloc(sizeof *ft);
 | 
				
			||||||
 | 
						RB_INIT(ft);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gethostname(host, sizeof host) == 0)
 | 
				
			||||||
 | 
							format_add(ft, "host", "%s", host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (ft);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Free a tree. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					format_free(struct format_tree *ft)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct format_entry	*fe, *fe_next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fe_next = RB_MIN(format_tree, ft);
 | 
				
			||||||
 | 
						while (fe_next != NULL) {
 | 
				
			||||||
 | 
							fe = fe_next;
 | 
				
			||||||
 | 
							fe_next = RB_NEXT(format_tree, ft, fe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RB_REMOVE(format_tree, ft, fe);
 | 
				
			||||||
 | 
							xfree(fe->value);
 | 
				
			||||||
 | 
							xfree(fe->key);
 | 
				
			||||||
 | 
							xfree(fe);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree (ft);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add a key-value pair. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct format_entry	*fe;
 | 
				
			||||||
 | 
						va_list			 ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fe = xmalloc(sizeof *fe);
 | 
				
			||||||
 | 
						fe->key = xstrdup(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						xvasprintf(&fe->value, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RB_INSERT(format_tree, ft, fe);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Find a format entry. */
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					format_find(struct format_tree *ft, const char *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct format_entry	*fe, fe_find;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fe_find.key = (char *) key;
 | 
				
			||||||
 | 
						fe = RB_FIND(format_tree, ft, &fe_find);
 | 
				
			||||||
 | 
						if (fe == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return (fe->value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Replace a key/value pair in buffer. #{blah} is expanded directly,
 | 
				
			||||||
 | 
					 * #{?blah,a,b} is replace with a if blah exists and is nonzero else b.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					format_replace(struct format_tree *ft,
 | 
				
			||||||
 | 
					    const char *key, size_t keylen, char **buf, size_t *len, size_t *off)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char		*copy, *ptr;
 | 
				
			||||||
 | 
						const char	*value;
 | 
				
			||||||
 | 
						size_t		 valuelen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make a copy of the key. */
 | 
				
			||||||
 | 
						copy = xmalloc(keylen + 1);
 | 
				
			||||||
 | 
						memcpy(copy, key, keylen);
 | 
				
			||||||
 | 
						copy[keylen] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Is this a conditional? If so, check it exists and extract either the
 | 
				
			||||||
 | 
						 * first or second element. If not, look up the key directly.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (*copy == '?') {
 | 
				
			||||||
 | 
							ptr = strchr(copy, ',');
 | 
				
			||||||
 | 
							if (ptr == NULL)
 | 
				
			||||||
 | 
								goto fail;
 | 
				
			||||||
 | 
							*ptr = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							value = format_find(ft, copy + 1);
 | 
				
			||||||
 | 
							if (value != NULL && (value[0] != '0' || value[1] != '\0')) {
 | 
				
			||||||
 | 
								value = ptr + 1;
 | 
				
			||||||
 | 
								ptr = strchr(value, ',');
 | 
				
			||||||
 | 
								if (ptr == NULL)
 | 
				
			||||||
 | 
									goto fail;
 | 
				
			||||||
 | 
								*ptr = '\0';
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ptr = strchr(ptr + 1, ',');
 | 
				
			||||||
 | 
								if (ptr == NULL)
 | 
				
			||||||
 | 
									goto fail;
 | 
				
			||||||
 | 
								value = ptr + 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							value = format_find(ft, copy);
 | 
				
			||||||
 | 
							if (value == NULL)
 | 
				
			||||||
 | 
								value = "";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						valuelen = strlen(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Expand the buffer and copy in the value. */
 | 
				
			||||||
 | 
						while (*len - *off < valuelen + 1) {
 | 
				
			||||||
 | 
							*buf = xrealloc(*buf, 2, *len);
 | 
				
			||||||
 | 
							*len *= 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						memcpy(*buf + *off, value, valuelen);
 | 
				
			||||||
 | 
						*off += valuelen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(copy);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fail:
 | 
				
			||||||
 | 
						xfree(copy);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Expand keys in a template. */
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					format_expand(struct format_tree *ft, const char *fmt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char		*buf, *ptr;
 | 
				
			||||||
 | 
						const char	*s;
 | 
				
			||||||
 | 
						size_t		 off, len, n;
 | 
				
			||||||
 | 
						int     	 ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = 64;
 | 
				
			||||||
 | 
						buf = xmalloc(len);
 | 
				
			||||||
 | 
						off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (*fmt != '\0') {
 | 
				
			||||||
 | 
							if (*fmt != '#') {
 | 
				
			||||||
 | 
								while (len - off < 2) {
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 2, len);
 | 
				
			||||||
 | 
									len *= 2;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buf[off++] = *fmt++;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ch = (u_char) *fmt++;
 | 
				
			||||||
 | 
							switch (ch) {
 | 
				
			||||||
 | 
							case '{':
 | 
				
			||||||
 | 
								ptr = strchr(fmt, '}');
 | 
				
			||||||
 | 
								if (ptr == NULL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								n = ptr - fmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (format_replace(ft, fmt, n, &buf, &len, &off) != 0)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								fmt += n + 1;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								if (ch >= 'A' && ch <= 'Z') {
 | 
				
			||||||
 | 
									s = format_aliases[ch - 'A'];
 | 
				
			||||||
 | 
									if (s != NULL) {
 | 
				
			||||||
 | 
										n = strlen(s);
 | 
				
			||||||
 | 
										if (format_replace (
 | 
				
			||||||
 | 
										    ft, s, n, &buf, &len, &off) != 0)
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while (len - off < 2) {
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 2, len);
 | 
				
			||||||
 | 
									len *= 2;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buf[off++] = ch;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						buf[off] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set default format keys for a session. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					format_session(struct format_tree *ft, struct session *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session_group	*sg;
 | 
				
			||||||
 | 
						char			*tim;
 | 
				
			||||||
 | 
						time_t			 t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_add(ft, "session_name", "%s", s->name);
 | 
				
			||||||
 | 
						format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
 | 
				
			||||||
 | 
						format_add(ft, "session_width", "%u", s->sx);
 | 
				
			||||||
 | 
						format_add(ft, "session_height", "%u", s->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sg = session_group_find(s);
 | 
				
			||||||
 | 
						format_add(ft, "session_grouped", "%d", sg != NULL);
 | 
				
			||||||
 | 
						if (sg != NULL)
 | 
				
			||||||
 | 
							format_add(ft, "session_group", "%u", session_group_index(sg));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t = s->creation_time.tv_sec;
 | 
				
			||||||
 | 
						format_add(ft, "session_created", "%ld", (long) t);
 | 
				
			||||||
 | 
						tim = ctime(&t);
 | 
				
			||||||
 | 
						*strchr(tim, '\n') = '\0';
 | 
				
			||||||
 | 
						format_add(ft, "session_created_string", "%s", tim);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s->flags & SESSION_UNATTACHED)
 | 
				
			||||||
 | 
							format_add(ft, "session_attached", "%d", 0);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							format_add(ft, "session_attached", "%d", 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set default format keys for a winlink. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window	*w = wl->window;
 | 
				
			||||||
 | 
						char		*layout, *flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout = layout_dump(w);
 | 
				
			||||||
 | 
						flags = window_printable_flags(s, wl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_add(ft, "window_index", "%d", wl->idx);
 | 
				
			||||||
 | 
						format_add(ft, "window_name", "%s", w->name);
 | 
				
			||||||
 | 
						format_add(ft, "window_width", "%u", w->sx);
 | 
				
			||||||
 | 
						format_add(ft, "window_height", "%u", w->sy);
 | 
				
			||||||
 | 
						format_add(ft, "window_flags", "%s", flags);
 | 
				
			||||||
 | 
						format_add(ft, "window_layout", "%s", layout);
 | 
				
			||||||
 | 
						format_add(ft, "window_active", "%d", wl == s->curw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(flags);
 | 
				
			||||||
 | 
						xfree(layout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set default format keys for a window pane. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					format_window_pane(struct format_tree *ft, struct window_pane *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct grid		*gd = wp->base.grid;
 | 
				
			||||||
 | 
						struct grid_line	*gl;
 | 
				
			||||||
 | 
						unsigned long long	 size;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < gd->hsize; i++) {
 | 
				
			||||||
 | 
							gl = &gd->linedata[i];
 | 
				
			||||||
 | 
							size += gl->cellsize * sizeof *gl->celldata;
 | 
				
			||||||
 | 
							size += gl->utf8size * sizeof *gl->utf8data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size += gd->hsize * sizeof *gd->linedata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						format_add(ft, "pane_width", "%u", wp->sx);
 | 
				
			||||||
 | 
						format_add(ft, "pane_height", "%u", wp->sy);
 | 
				
			||||||
 | 
						format_add(ft, "pane_title", "%s", wp->base.title);
 | 
				
			||||||
 | 
						format_add(ft, "history_size", "%u", gd->hsize);
 | 
				
			||||||
 | 
						format_add(ft, "history_limit", "%u", gd->hlimit);
 | 
				
			||||||
 | 
						format_add(ft, "history_bytes", "%llu", size);
 | 
				
			||||||
 | 
						format_add(ft, "pane_id", "%%%u", wp->id);
 | 
				
			||||||
 | 
						format_add(ft, "pane_active", "%d", wp == wp->window->active);
 | 
				
			||||||
 | 
						format_add(ft, "pane_dead", "%d", wp->fd == -1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										79
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								tmux.1
									
									
									
									
									
								
							@@ -14,7 +14,7 @@
 | 
				
			|||||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
					.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
.\"
 | 
					.\"
 | 
				
			||||||
.Dd $Mdocdate: August 24 2011 $
 | 
					.Dd $Mdocdate: August 26 2011 $
 | 
				
			||||||
.Dt TMUX 1
 | 
					.Dt TMUX 1
 | 
				
			||||||
.Os
 | 
					.Os
 | 
				
			||||||
.Sh NAME
 | 
					.Sh NAME
 | 
				
			||||||
@@ -621,6 +621,7 @@ is specified, list only clients connected to that session.
 | 
				
			|||||||
List the syntax of all commands supported by
 | 
					List the syntax of all commands supported by
 | 
				
			||||||
.Nm .
 | 
					.Nm .
 | 
				
			||||||
.It Ic list-sessions
 | 
					.It Ic list-sessions
 | 
				
			||||||
 | 
					.Op Fl F Ar format
 | 
				
			||||||
.D1 (alias: Ic ls )
 | 
					.D1 (alias: Ic ls )
 | 
				
			||||||
List all sessions managed by the server.
 | 
					List all sessions managed by the server.
 | 
				
			||||||
.It Ic lock-client Op Fl t Ar target-client
 | 
					.It Ic lock-client Op Fl t Ar target-client
 | 
				
			||||||
@@ -630,6 +631,11 @@ Lock
 | 
				
			|||||||
see the
 | 
					see the
 | 
				
			||||||
.Ic lock-server
 | 
					.Ic lock-server
 | 
				
			||||||
command.
 | 
					command.
 | 
				
			||||||
 | 
					For the meaning of the
 | 
				
			||||||
 | 
					.Fl F
 | 
				
			||||||
 | 
					flag, see the
 | 
				
			||||||
 | 
					.Sx FORMATS
 | 
				
			||||||
 | 
					section.
 | 
				
			||||||
.It Ic lock-session Op Fl t Ar target-session
 | 
					.It Ic lock-session Op Fl t Ar target-session
 | 
				
			||||||
.D1 (alias: Ic locks )
 | 
					.D1 (alias: Ic locks )
 | 
				
			||||||
Lock all clients attached to
 | 
					Lock all clients attached to
 | 
				
			||||||
@@ -1151,6 +1157,7 @@ If
 | 
				
			|||||||
is given, the newly linked window is not selected.
 | 
					is given, the newly linked window is not selected.
 | 
				
			||||||
.It Xo Ic list-panes
 | 
					.It Xo Ic list-panes
 | 
				
			||||||
.Op Fl as
 | 
					.Op Fl as
 | 
				
			||||||
 | 
					.Op Fl F Ar format
 | 
				
			||||||
.Op Fl t Ar target
 | 
					.Op Fl t Ar target
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
.D1 (alias: Ic lsp )
 | 
					.D1 (alias: Ic lsp )
 | 
				
			||||||
@@ -1169,6 +1176,7 @@ If neither is given,
 | 
				
			|||||||
is a window (or the current window).
 | 
					is a window (or the current window).
 | 
				
			||||||
.It Xo Ic list-windows
 | 
					.It Xo Ic list-windows
 | 
				
			||||||
.Op Fl a
 | 
					.Op Fl a
 | 
				
			||||||
 | 
					.Op Fl F Ar format
 | 
				
			||||||
.Op Fl t Ar target-session
 | 
					.Op Fl t Ar target-session
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
.D1 (alias: Ic lsw )
 | 
					.D1 (alias: Ic lsw )
 | 
				
			||||||
@@ -1177,6 +1185,11 @@ If
 | 
				
			|||||||
is given, list all windows on the server.
 | 
					is given, list all windows on the server.
 | 
				
			||||||
Otherwise, list windows in the current session or in
 | 
					Otherwise, list windows in the current session or in
 | 
				
			||||||
.Ar target-session .
 | 
					.Ar target-session .
 | 
				
			||||||
 | 
					For the meaning of the
 | 
				
			||||||
 | 
					.Fl F
 | 
				
			||||||
 | 
					flag, see the
 | 
				
			||||||
 | 
					.Sx FORMATS
 | 
				
			||||||
 | 
					section.
 | 
				
			||||||
.It Xo Ic move-window
 | 
					.It Xo Ic move-window
 | 
				
			||||||
.Op Fl dk
 | 
					.Op Fl dk
 | 
				
			||||||
.Op Fl s Ar src-window
 | 
					.Op Fl s Ar src-window
 | 
				
			||||||
@@ -2539,6 +2552,70 @@ or the global window options if
 | 
				
			|||||||
.Fl g
 | 
					.Fl g
 | 
				
			||||||
is used.
 | 
					is used.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
 | 
					.Sh FORMATS
 | 
				
			||||||
 | 
					The
 | 
				
			||||||
 | 
					.Ic list-sessions ,
 | 
				
			||||||
 | 
					.Ic list-windows
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Ic list-panes
 | 
				
			||||||
 | 
					commands accept the
 | 
				
			||||||
 | 
					.Fl F
 | 
				
			||||||
 | 
					flag with a
 | 
				
			||||||
 | 
					.Ar format
 | 
				
			||||||
 | 
					argument.
 | 
				
			||||||
 | 
					This is a string which controls the output format of the command.
 | 
				
			||||||
 | 
					Special character sequences are replaced as documented under the
 | 
				
			||||||
 | 
					.Ic status-left
 | 
				
			||||||
 | 
					option and an additional long form is accepted.
 | 
				
			||||||
 | 
					Replacement variables are enclosed in
 | 
				
			||||||
 | 
					.Ql #{
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Ql } ,
 | 
				
			||||||
 | 
					for example
 | 
				
			||||||
 | 
					.Ql #{session_name}
 | 
				
			||||||
 | 
					is equivalent to
 | 
				
			||||||
 | 
					.Ql #S .
 | 
				
			||||||
 | 
					Conditionals are also accepted by prefixing with
 | 
				
			||||||
 | 
					.Ql ?
 | 
				
			||||||
 | 
					and separating two alternatives with a comma;
 | 
				
			||||||
 | 
					if the specified variable exists and is not zero, the first alternative
 | 
				
			||||||
 | 
					is chosen, otherwise the second is used. For example
 | 
				
			||||||
 | 
					.Ql #{?session_attached,attached,not attached}
 | 
				
			||||||
 | 
					will include the string
 | 
				
			||||||
 | 
					.Ql attached
 | 
				
			||||||
 | 
					if the session is attached and the string
 | 
				
			||||||
 | 
					.Ql not attached
 | 
				
			||||||
 | 
					if it is unattached.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					The following variables are available, where appropriate:
 | 
				
			||||||
 | 
					.Bl -column "session_created_string" "Replaced with" -offset indent
 | 
				
			||||||
 | 
					.It Sy "Variable name" Ta Sy "Replaced with"
 | 
				
			||||||
 | 
					.It Li "host" Ta "Hostname of local host"
 | 
				
			||||||
 | 
					.It Li "line" Ta "Line number in the list"
 | 
				
			||||||
 | 
					.It Li "pane_active" Ta "1 if active pane"
 | 
				
			||||||
 | 
					.It Li "pane_dead" Ta "1 if pane is dead"
 | 
				
			||||||
 | 
					.It Li "pane_height" Ta "Height of pane"
 | 
				
			||||||
 | 
					.It Li "pane_id" Ta "Unique pane id"
 | 
				
			||||||
 | 
					.It Li "pane_title" Ta "Title of pane"
 | 
				
			||||||
 | 
					.It Li "pane_width" Ta "Width of pane"
 | 
				
			||||||
 | 
					.It Li "session_attached" Ta "1 if session attached"
 | 
				
			||||||
 | 
					.It Li "session_created" Ta "Integer time session created"
 | 
				
			||||||
 | 
					.It Li "session_created_string" Ta "String time session created"
 | 
				
			||||||
 | 
					.It Li "session_group" Ta "Number of session group"
 | 
				
			||||||
 | 
					.It Li "session_grouped" Ta "1 if session in a group"
 | 
				
			||||||
 | 
					.It Li "session_height" Ta "Height of session"
 | 
				
			||||||
 | 
					.It Li "session_name" Ta "Name of session"
 | 
				
			||||||
 | 
					.It Li "session_width" Ta "Width of session"
 | 
				
			||||||
 | 
					.It Li "session_windows" Ta "Number of windows in session"
 | 
				
			||||||
 | 
					.It Li "window_active" Ta "1 if window active"
 | 
				
			||||||
 | 
					.It Li "window_flags" Ta "Window flags"
 | 
				
			||||||
 | 
					.It Li "window_height" Ta "Height of window"
 | 
				
			||||||
 | 
					.It Li "window_index" Ta "Index of window"
 | 
				
			||||||
 | 
					.It Li "window_layout" Ta "Window layout description"
 | 
				
			||||||
 | 
					.It Li "window_name" Ta "Name of window"
 | 
				
			||||||
 | 
					.It Li "window_width" Ta "Width of window"
 | 
				
			||||||
 | 
					.El
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
.Sh ENVIRONMENT
 | 
					.Sh ENVIRONMENT
 | 
				
			||||||
When the server is started,
 | 
					When the server is started,
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1299,6 +1299,15 @@ struct options_table_entry {
 | 
				
			|||||||
	long long		default_num;
 | 
						long long		default_num;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Tree of format entries. */
 | 
				
			||||||
 | 
					struct format_entry {
 | 
				
			||||||
 | 
						char		       *key;
 | 
				
			||||||
 | 
						char		       *value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RB_ENTRY(format_entry)	entry;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					RB_HEAD(format_tree, format_entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* List of configuration causes. */
 | 
					/* List of configuration causes. */
 | 
				
			||||||
ARRAY_DECL(causelist, char *);
 | 
					ARRAY_DECL(causelist, char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1341,6 +1350,20 @@ extern struct causelist cfg_causes;
 | 
				
			|||||||
void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
 | 
					void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
 | 
				
			||||||
int		 load_cfg(const char *, struct cmd_ctx *, struct causelist *);
 | 
					int		 load_cfg(const char *, struct cmd_ctx *, struct causelist *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* format.c */
 | 
				
			||||||
 | 
					int		 format_cmp(struct format_entry *, struct format_entry *);
 | 
				
			||||||
 | 
					RB_PROTOTYPE(format_tree, format_entry, entry, format_cmp);
 | 
				
			||||||
 | 
					struct format_tree *format_create(void);
 | 
				
			||||||
 | 
					void		 format_free(struct format_tree *);
 | 
				
			||||||
 | 
					void		 format_add(
 | 
				
			||||||
 | 
							     struct format_tree *, const char *, const char *, ...);
 | 
				
			||||||
 | 
					const char	*format_find(struct format_tree *, const char *);
 | 
				
			||||||
 | 
					char		*format_expand(struct format_tree *, const char *);
 | 
				
			||||||
 | 
					void		 format_session(struct format_tree *, struct session *);
 | 
				
			||||||
 | 
					void		 format_winlink(
 | 
				
			||||||
 | 
							     struct format_tree *, struct session *, struct winlink *);
 | 
				
			||||||
 | 
					void		 format_window_pane(struct format_tree *, struct window_pane *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* mode-key.c */
 | 
					/* mode-key.c */
 | 
				
			||||||
extern const struct mode_key_table mode_key_tables[];
 | 
					extern const struct mode_key_table mode_key_tables[];
 | 
				
			||||||
extern struct mode_key_tree mode_key_tree_vi_edit;
 | 
					extern struct mode_key_tree mode_key_tree_vi_edit;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user