mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Add a number of new formats to inspect what sessions and clients a
window is present or active in. From Tyler Culp in GitHub issue 2034.
This commit is contained in:
		
							
								
								
									
										213
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										213
									
								
								format.c
									
									
									
									
									
								
							@@ -456,6 +456,35 @@ format_cb_pid(__unused struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
	xasprintf(&fe->value, "%ld", (long)getpid());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for session_attached_list. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_session_attached_list(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s = ft->s;
 | 
			
		||||
	struct client	*loop;
 | 
			
		||||
	struct evbuffer	*buffer;
 | 
			
		||||
	int		 size;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(loop, &clients, entry) {
 | 
			
		||||
		if (loop->session == s) {
 | 
			
		||||
			if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
				evbuffer_add(buffer, ",", 1);
 | 
			
		||||
			evbuffer_add_printf(buffer, "%s", loop->name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for session_alerts. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
@@ -528,6 +557,128 @@ format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
		fe->value = xstrdup("0");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_linked_sessions_list. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_linked_sessions_list(struct format_tree *ft,
 | 
			
		||||
    struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ft->wl->window;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	struct evbuffer	*buffer;
 | 
			
		||||
	int		 size;
 | 
			
		||||
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
			evbuffer_add(buffer, ",", 1);
 | 
			
		||||
		evbuffer_add_printf(buffer, "%s", wl->session->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_active_sessions. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_active_sessions(struct format_tree *ft,
 | 
			
		||||
    struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ft->wl->window;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	u_int		 n = 0;
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->session->curw == wl)
 | 
			
		||||
			n++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xasprintf(&fe->value, "%u", n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_active_sessions_list. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_active_sessions_list(struct format_tree *ft,
 | 
			
		||||
    struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ft->wl->window;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
	struct evbuffer	*buffer;
 | 
			
		||||
	int		 size;
 | 
			
		||||
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
 | 
			
		||||
		if (wl->session->curw == wl) {
 | 
			
		||||
			if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
				evbuffer_add(buffer, ",", 1);
 | 
			
		||||
			evbuffer_add_printf(buffer, "%s", wl->session->name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_active_clients. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_active_clients(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ft->wl->window;
 | 
			
		||||
	struct client	*loop;
 | 
			
		||||
	struct session	*client_session;
 | 
			
		||||
	u_int		 n = 0;
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(loop, &clients, entry) {
 | 
			
		||||
		client_session = loop->session;
 | 
			
		||||
		if (client_session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (w == client_session->curw->window)
 | 
			
		||||
			n++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xasprintf(&fe->value, "%u", n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_active_clients_list. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_active_clients_list(struct format_tree *ft,
 | 
			
		||||
    struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ft->wl->window;
 | 
			
		||||
	struct client	*loop;
 | 
			
		||||
	struct session	*client_session;
 | 
			
		||||
	struct evbuffer	*buffer;
 | 
			
		||||
	int		 size;
 | 
			
		||||
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(loop, &clients, entry) {
 | 
			
		||||
		client_session = loop->session;
 | 
			
		||||
		if (client_session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (w == client_session->curw->window) {
 | 
			
		||||
			if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
				evbuffer_add(buffer, ",", 1);
 | 
			
		||||
			evbuffer_add_printf(buffer, "%s", loop->name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for window_layout. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_window_layout(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
@@ -662,11 +813,52 @@ format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(loop, &sg->sessions, gentry) {
 | 
			
		||||
		if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
			evbuffer_add(buffer, ",", 1);
 | 
			
		||||
		evbuffer_add_printf(buffer, "%s", loop->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Callback for session_group_attached_list. */
 | 
			
		||||
static void
 | 
			
		||||
format_cb_session_group_attached_list(struct format_tree *ft,
 | 
			
		||||
    struct format_entry *fe)
 | 
			
		||||
{
 | 
			
		||||
	struct session		*s = ft->s, *client_session, *session_loop;
 | 
			
		||||
	struct session_group	*sg;
 | 
			
		||||
	struct client		*loop;
 | 
			
		||||
	struct evbuffer		*buffer;
 | 
			
		||||
	int			 size;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	sg = session_group_contains(s);
 | 
			
		||||
	if (sg == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	buffer = evbuffer_new();
 | 
			
		||||
	if (buffer == NULL)
 | 
			
		||||
		fatalx("out of memory");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(loop, &clients, entry) {
 | 
			
		||||
		client_session = loop->session;
 | 
			
		||||
		if (client_session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		TAILQ_FOREACH(session_loop, &sg->sessions, gentry) {
 | 
			
		||||
			if (session_loop == client_session){
 | 
			
		||||
				if (EVBUFFER_LENGTH(buffer) > 0)
 | 
			
		||||
					evbuffer_add(buffer, ",", 1);
 | 
			
		||||
				evbuffer_add_printf(buffer, "%s", loop->name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
 | 
			
		||||
		xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
 | 
			
		||||
	evbuffer_free(buffer);
 | 
			
		||||
@@ -2125,8 +2317,14 @@ format_defaults_session(struct format_tree *ft, struct session *s)
 | 
			
		||||
		format_add(ft, "session_group", "%s", sg->name);
 | 
			
		||||
		format_add(ft, "session_group_size", "%u",
 | 
			
		||||
		    session_group_count (sg));
 | 
			
		||||
		format_add(ft, "session_group_attached", "%u",
 | 
			
		||||
		    session_group_attached_count (sg));
 | 
			
		||||
		format_add(ft, "session_group_many_attached", "%u",
 | 
			
		||||
		    session_group_attached_count (sg) > 1);
 | 
			
		||||
		format_add_cb(ft, "session_group_list",
 | 
			
		||||
		    format_cb_session_group_list);
 | 
			
		||||
		format_add_cb(ft, "session_group_attached_list",
 | 
			
		||||
		    format_cb_session_group_attached_list);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	format_add_tv(ft, "session_created", &s->creation_time);
 | 
			
		||||
@@ -2135,6 +2333,8 @@ format_defaults_session(struct format_tree *ft, struct session *s)
 | 
			
		||||
 | 
			
		||||
	format_add(ft, "session_attached", "%u", s->attached);
 | 
			
		||||
	format_add(ft, "session_many_attached", "%d", s->attached > 1);
 | 
			
		||||
	format_add_cb(ft, "session_attached_list",
 | 
			
		||||
	    format_cb_session_attached_list);
 | 
			
		||||
 | 
			
		||||
	format_add_cb(ft, "session_alerts", format_cb_session_alerts);
 | 
			
		||||
	format_add_cb(ft, "session_stack", format_cb_session_stack);
 | 
			
		||||
@@ -2249,6 +2449,14 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
 | 
			
		||||
	format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
 | 
			
		||||
	format_add(ft, "window_flags", "%s", window_printable_flags(wl));
 | 
			
		||||
	format_add(ft, "window_active", "%d", wl == s->curw);
 | 
			
		||||
	format_add_cb(ft, "window_active_sessions",
 | 
			
		||||
	    format_cb_window_active_sessions);
 | 
			
		||||
	format_add_cb(ft, "window_active_sessions_list",
 | 
			
		||||
	    format_cb_window_active_sessions_list);
 | 
			
		||||
	format_add_cb(ft, "window_active_clients",
 | 
			
		||||
	    format_cb_window_active_clients);
 | 
			
		||||
	format_add_cb(ft, "window_active_clients_list",
 | 
			
		||||
	    format_cb_window_active_clients_list);
 | 
			
		||||
 | 
			
		||||
	format_add(ft, "window_start_flag", "%d",
 | 
			
		||||
	    !!(wl == RB_MIN(winlinks, &s->windows)));
 | 
			
		||||
@@ -2269,6 +2477,11 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
 | 
			
		||||
	format_add(ft, "window_last_flag", "%d",
 | 
			
		||||
	    !!(wl == TAILQ_FIRST(&s->lastw)));
 | 
			
		||||
	format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
 | 
			
		||||
 | 
			
		||||
	format_add_cb(ft, "window_linked_sessions_list",
 | 
			
		||||
	    format_cb_window_linked_sessions_list);
 | 
			
		||||
	format_add(ft, "window_linked_sessions", "%u",
 | 
			
		||||
	    wl->window->references);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set default format keys for a window pane. */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								session.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								session.c
									
									
									
									
									
								
							@@ -569,7 +569,20 @@ session_group_count(struct session_group *sg)
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	TAILQ_FOREACH(s, &sg->sessions, gentry)
 | 
			
		||||
	    n++;
 | 
			
		||||
		n++;
 | 
			
		||||
	return (n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Count number of clients attached to sessions in session group. */
 | 
			
		||||
u_int
 | 
			
		||||
session_group_attached_count(struct session_group *sg)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	u_int		 n;
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	TAILQ_FOREACH(s, &sg->sessions, gentry)
 | 
			
		||||
		n += s->attached;
 | 
			
		||||
	return (n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tmux.1
									
									
									
									
									
								
							@@ -4310,10 +4310,14 @@ The following variables are available, where appropriate:
 | 
			
		||||
.It Li "session_activity" Ta "" Ta "Time of session last activity"
 | 
			
		||||
.It Li "session_alerts" Ta "" Ta "List of window indexes with alerts"
 | 
			
		||||
.It Li "session_attached" Ta "" Ta "Number of clients session is attached to"
 | 
			
		||||
.It Li "session_attached_list" Ta "" Ta "List of clients session is attached to"
 | 
			
		||||
.It Li "session_created" Ta "" Ta "Time session created"
 | 
			
		||||
.It Li "session_format" Ta "" Ta "1 if format is for a session"
 | 
			
		||||
.It Li "session_group" Ta "" Ta "Name of session group"
 | 
			
		||||
.It Li "session_group_attached" Ta "" Ta "Number of clients sessions in group are attached to"
 | 
			
		||||
.It Li "session_group_attached_list" Ta "" Ta "List of clients sessions in group are attached to"
 | 
			
		||||
.It Li "session_group_list" Ta "" Ta "List of sessions in group"
 | 
			
		||||
.It Li "session_group_many_attached" Ta "" Ta "1 if multiple clients attached to sessions in group"
 | 
			
		||||
.It Li "session_group_size" Ta "" Ta "Size of session group"
 | 
			
		||||
.It Li "session_grouped" Ta "" Ta "1 if session in a group"
 | 
			
		||||
.It Li "session_id" Ta "" Ta "Unique session ID"
 | 
			
		||||
@@ -4325,6 +4329,10 @@ The following variables are available, where appropriate:
 | 
			
		||||
.It Li "socket_path" Ta "" Ta "Server socket path"
 | 
			
		||||
.It Li "start_time" Ta "" Ta "Server start time"
 | 
			
		||||
.It Li "window_active" Ta "" Ta "1 if window active"
 | 
			
		||||
.It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window"
 | 
			
		||||
.It Li "window_active_clients_list" Ta "" Ta "List of clients viewing this window"
 | 
			
		||||
.It Li "window_active_sessions" Ta "" Ta "Number of sessions on which this window is active"
 | 
			
		||||
.It Li "window_active_sessions_list" Ta "" Ta "List of sessions on which this window is active"
 | 
			
		||||
.It Li "window_activity" Ta "" Ta "Time of window last activity"
 | 
			
		||||
.It Li "window_activity_flag" Ta "" Ta "1 if window has activity"
 | 
			
		||||
.It Li "window_bell_flag" Ta "" Ta "1 if window has bell"
 | 
			
		||||
@@ -4340,6 +4348,8 @@ The following variables are available, where appropriate:
 | 
			
		||||
.It Li "window_last_flag" Ta "" Ta "1 if window is the last used"
 | 
			
		||||
.It Li "window_layout" Ta "" Ta "Window layout description, ignoring zoomed window panes"
 | 
			
		||||
.It Li "window_linked" Ta "" Ta "1 if window is linked across sessions"
 | 
			
		||||
.It Li "window_linked_sessions" Ta "" Ta "Number of sessions this window is linked to"
 | 
			
		||||
.It Li "window_linked_sessions_list" Ta "" Ta "List of sessions this window is linked to"
 | 
			
		||||
.It Li "window_marked_flag" Ta "" Ta "1 if window contains the marked pane"
 | 
			
		||||
.It Li "window_name" Ta "#W" Ta "Name of window"
 | 
			
		||||
.It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2689,6 +2689,7 @@ void		 session_group_add(struct session_group *, struct session *);
 | 
			
		||||
void		 session_group_synchronize_to(struct session *);
 | 
			
		||||
void		 session_group_synchronize_from(struct session *);
 | 
			
		||||
u_int		 session_group_count(struct session_group *);
 | 
			
		||||
u_int		 session_group_attached_count(struct session_group *);
 | 
			
		||||
void		 session_renumber_windows(struct session *);
 | 
			
		||||
 | 
			
		||||
/* utf8.c */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user