mirror of
https://github.com/tmux/tmux.git
synced 2024-11-19 10:58:51 +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:
parent
07e37479c2
commit
817d199cbb
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());
|
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. */
|
/* Callback for session_alerts. */
|
||||||
static void
|
static void
|
||||||
format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
|
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");
|
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. */
|
/* Callback for window_layout. */
|
||||||
static void
|
static void
|
||||||
format_cb_window_layout(struct format_tree *ft, struct format_entry *fe)
|
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();
|
buffer = evbuffer_new();
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
fatalx("out of memory");
|
fatalx("out of memory");
|
||||||
|
|
||||||
TAILQ_FOREACH(loop, &sg->sessions, gentry) {
|
TAILQ_FOREACH(loop, &sg->sessions, gentry) {
|
||||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||||
evbuffer_add(buffer, ",", 1);
|
evbuffer_add(buffer, ",", 1);
|
||||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
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)
|
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||||
evbuffer_free(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", "%s", sg->name);
|
||||||
format_add(ft, "session_group_size", "%u",
|
format_add(ft, "session_group_size", "%u",
|
||||||
session_group_count (sg));
|
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_add_cb(ft, "session_group_list",
|
||||||
format_cb_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);
|
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_attached", "%u", s->attached);
|
||||||
format_add(ft, "session_many_attached", "%d", s->attached > 1);
|
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_alerts", format_cb_session_alerts);
|
||||||
format_add_cb(ft, "session_stack", format_cb_session_stack);
|
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_cb(ft, "window_stack_index", format_cb_window_stack_index);
|
||||||
format_add(ft, "window_flags", "%s", window_printable_flags(wl));
|
format_add(ft, "window_flags", "%s", window_printable_flags(wl));
|
||||||
format_add(ft, "window_active", "%d", wl == s->curw);
|
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",
|
format_add(ft, "window_start_flag", "%d",
|
||||||
!!(wl == RB_MIN(winlinks, &s->windows)));
|
!!(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",
|
format_add(ft, "window_last_flag", "%d",
|
||||||
!!(wl == TAILQ_FIRST(&s->lastw)));
|
!!(wl == TAILQ_FIRST(&s->lastw)));
|
||||||
format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
|
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. */
|
/* Set default format keys for a window pane. */
|
||||||
|
13
session.c
13
session.c
@ -573,6 +573,19 @@ session_group_count(struct session_group *sg)
|
|||||||
return (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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Synchronize a session to its session group. */
|
/* Synchronize a session to its session group. */
|
||||||
void
|
void
|
||||||
session_group_synchronize_to(struct session *s)
|
session_group_synchronize_to(struct session *s)
|
||||||
|
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_activity" Ta "" Ta "Time of session last activity"
|
||||||
.It Li "session_alerts" Ta "" Ta "List of window indexes with alerts"
|
.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" 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_created" Ta "" Ta "Time session created"
|
||||||
.It Li "session_format" Ta "" Ta "1 if format is for a session"
|
.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" 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_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_group_size" Ta "" Ta "Size of session group"
|
||||||
.It Li "session_grouped" Ta "" Ta "1 if session in a group"
|
.It Li "session_grouped" Ta "" Ta "1 if session in a group"
|
||||||
.It Li "session_id" Ta "" Ta "Unique session ID"
|
.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 "socket_path" Ta "" Ta "Server socket path"
|
||||||
.It Li "start_time" Ta "" Ta "Server start time"
|
.It Li "start_time" Ta "" Ta "Server start time"
|
||||||
.It Li "window_active" Ta "" Ta "1 if window active"
|
.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" Ta "" Ta "Time of window last activity"
|
||||||
.It Li "window_activity_flag" Ta "" Ta "1 if window has 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"
|
.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_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_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" 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_marked_flag" Ta "" Ta "1 if window contains the marked pane"
|
||||||
.It Li "window_name" Ta "#W" Ta "Name of window"
|
.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"
|
.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_to(struct session *);
|
||||||
void session_group_synchronize_from(struct session *);
|
void session_group_synchronize_from(struct session *);
|
||||||
u_int session_group_count(struct session_group *);
|
u_int session_group_count(struct session_group *);
|
||||||
|
u_int session_group_attached_count(struct session_group *);
|
||||||
void session_renumber_windows(struct session *);
|
void session_renumber_windows(struct session *);
|
||||||
|
|
||||||
/* utf8.c */
|
/* utf8.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user