From 3887d95bcae1f31ec13c2a24ff29ad211a93a5f7 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Nov 2017 18:26:38 +0000 Subject: [PATCH 1/4] There is no point in reflowing panes which have not changed width. --- screen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/screen.c b/screen.c index 800dbe8f..c792c04a 100644 --- a/screen.c +++ b/screen.c @@ -197,7 +197,8 @@ screen_resize(struct screen *s, u_int sx, u_int sy, int reflow) * is simpler and more reliable so let's do that. */ screen_reset_tabs(s); - } + } else + reflow = 0; if (sy != screen_size_y(s)) screen_resize_y(s, sy); From c1f62f1fdebc3bd000b81bd93dcae6f1a539f345 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Nov 2017 18:27:35 +0000 Subject: [PATCH 2/4] Only show the first member of session groups in tree mode (-G flag disables). --- cmd-choose-tree.c | 4 ++-- format.c | 41 ++++++++++++++++++++++++++++++++++++++--- session.c | 6 +----- tmux.1 | 7 ++++++- tmux.h | 1 + window-tree.c | 15 +++++++++++++-- 6 files changed, 61 insertions(+), 13 deletions(-) diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index 65c3ae0a..815c2a03 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -30,8 +30,8 @@ const struct cmd_entry cmd_choose_tree_entry = { .name = "choose-tree", .alias = NULL, - .args = { "F:f:NO:st:w", 0, 1 }, - .usage = "[-Nsw] [-F format] [-f filter] [-O sort-order] " + .args = { "F:Gf:NO:st:w", 0, 1 }, + .usage = "[-GNsw] [-F format] [-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, diff --git a/format.c b/format.c index aa8396d7..8c5a0698 100644 --- a/format.c +++ b/format.c @@ -572,8 +572,38 @@ format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe) evbuffer_add(buffer, ",", 1); evbuffer_add_printf(buffer, "%u", i); } - size = EVBUFFER_LENGTH(buffer); - xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); + if ((size = EVBUFFER_LENGTH(buffer)) != 0) + xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); + evbuffer_free(buffer); +} + +/* Callback for session_group_others. */ +static void +format_cb_session_group_others(struct format_tree *ft, struct format_entry *fe) +{ + struct session *s = ft->s; + struct session_group *sg; + struct session *loop; + struct evbuffer *buffer; + int size; + + if (s == NULL) + return; + sg = session_group_contains(s); + if (sg == NULL) + return; + + buffer = evbuffer_new(); + TAILQ_FOREACH(loop, &sg->sessions, gentry) { + if (loop == s) + continue; + + 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); } @@ -1253,8 +1283,13 @@ format_defaults_session(struct format_tree *ft, struct session *s) sg = session_group_contains(s); format_add(ft, "session_grouped", "%d", sg != NULL); - if (sg != NULL) + if (sg != NULL) { format_add(ft, "session_group", "%s", sg->name); + format_add(ft, "session_group_size", "%u", + session_group_count (sg)); + format_add_cb(ft, "session_group_others", + format_cb_session_group_others); + } format_add_tv(ft, "session_created", &s->creation_time); format_add_tv(ft, "session_last_attached", &s->last_attached_time); diff --git a/session.c b/session.c index a675ae3d..11493181 100644 --- a/session.c +++ b/session.c @@ -39,10 +39,6 @@ static struct winlink *session_next_alert(struct winlink *); static struct winlink *session_previous_alert(struct winlink *); static void session_group_remove(struct session *); -static u_int session_group_count(struct session_group *); -static void session_group_synchronize1(struct session *, struct session *); - -static u_int session_group_count(struct session_group *); static void session_group_synchronize1(struct session *, struct session *); RB_GENERATE(sessions, session, entry, session_cmp); @@ -624,7 +620,7 @@ session_group_remove(struct session *s) } /* Count number of sessions in session group. */ -static u_int +u_int session_group_count(struct session_group *sg) { struct session *s; diff --git a/tmux.1 b/tmux.1 index 847e3e1b..b7b2a088 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1428,7 +1428,7 @@ starts without the preview. This command works only if at least one client is attached. .It Xo .Ic choose-tree -.Op Fl Nsw +.Op Fl GNsw .Op Fl F Ar format .Op Fl f Ar filter .Op Fl O Ar sort-order @@ -1484,6 +1484,9 @@ If a filter would lead to an empty list, it is ignored. specifies the format for each item in the tree. .Fl N starts without the preview. +.Fl G +includes all sessions in any session groups in the tree rather than only the +first. This command works only if at least one client is attached. .It Xo .Ic display-panes @@ -3710,6 +3713,8 @@ The following variables are available, where appropriate: .It Li "session_format" Ta "" Ta "1 if format is for a session (not assuming the current)" .It Li "session_last_attached" Ta "" Ta "Time session last attached" .It Li "session_group" Ta "" Ta "Name of session group" +.It Li "session_group_size" Ta "" Ta "Size of session group" +.It Li "session_group_others" Ta "" Ta "List of other sessions in group" .It Li "session_grouped" Ta "" Ta "1 if session in a group" .It Li "session_height" Ta "" Ta "Height of session" .It Li "session_id" Ta "" Ta "Unique session ID" diff --git a/tmux.h b/tmux.h index 720ff40e..974a0678 100644 --- a/tmux.h +++ b/tmux.h @@ -2335,6 +2335,7 @@ struct session_group *session_group_new(const char *); 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 *); void session_renumber_windows(struct session *); /* utf8.c */ diff --git a/window-tree.c b/window-tree.c index 164f0aad..8765628a 100644 --- a/window-tree.c +++ b/window-tree.c @@ -43,8 +43,12 @@ static void window_tree_key(struct window_pane *, "#{?#{==:#{window_panes},1}, \"#{pane_title}\",}" \ "," \ "#{session_windows} windows" \ - "#{?session_grouped, (group ,}" \ - "#{session_group}#{?session_grouped,),}" \ + "#{?session_grouped, " \ + "(group #{session_group}" \ + "#{?session_group_others," \ + " with #{session_group_others}," \ + "})," \ + "}" \ "#{?session_attached, (attached),}" \ "}" \ "}" @@ -91,6 +95,7 @@ struct window_tree_modedata { struct mode_tree_data *data; char *format; char *command; + int squash_groups; struct window_tree_itemdata **item_list; u_int item_size; @@ -394,6 +399,7 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag, { struct window_tree_modedata *data = modedata; struct session *s, **l; + struct session_group *sg; u_int n, i; for (i = 0; i < data->item_size; i++) @@ -405,6 +411,10 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag, l = NULL; n = 0; RB_FOREACH(s, sessions, &sessions) { + if (data->squash_groups && + (sg = session_group_contains(s)) != NULL && + s != TAILQ_FIRST(&sg->sessions)) + continue; l = xreallocarray(l, n + 1, sizeof *l); l[n++] = s; } @@ -805,6 +815,7 @@ window_tree_init(struct window_pane *wp, struct cmd_find_state *fs, data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND); else data->command = xstrdup(args->argv[0]); + data->squash_groups = !args_has(args, 'G'); data->data = mode_tree_start(wp, args, window_tree_build, window_tree_draw, window_tree_search, data, window_tree_sort_list, From 95850e1aca6697df784d02c24a0ca997f82f90f7 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Nov 2017 18:43:51 +0000 Subject: [PATCH 3/4] Tweak previous slightly so that current session is chosen if it is in the group rather than first. --- format.c | 5 ++++- window-tree.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/format.c b/format.c index 8c5a0698..e254eb22 100644 --- a/format.c +++ b/format.c @@ -795,8 +795,11 @@ format_find(struct format_tree *ft, const char *key, int modifiers) found = s; goto found; } - if (fe->value == NULL && fe->cb != NULL) + if (fe->value == NULL && fe->cb != NULL) { fe->cb(ft, fe); + if (fe->value == NULL) + fe->value = xstrdup(""); + } found = fe->value; goto found; } diff --git a/window-tree.c b/window-tree.c index 8765628a..563c64e0 100644 --- a/window-tree.c +++ b/window-tree.c @@ -399,9 +399,11 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag, { struct window_tree_modedata *data = modedata; struct session *s, **l; - struct session_group *sg; + struct session_group *sg, *current; u_int n, i; + current = session_group_contains(data->fs.s); + for (i = 0; i < data->item_size; i++) window_tree_free_item(data->item_list[i]); free(data->item_list); @@ -412,9 +414,11 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag, n = 0; RB_FOREACH(s, sessions, &sessions) { if (data->squash_groups && - (sg = session_group_contains(s)) != NULL && - s != TAILQ_FIRST(&sg->sessions)) - continue; + (sg = session_group_contains(s)) != NULL) { + if ((sg == current && s != data->fs.s) || + (sg != current && s != TAILQ_FIRST(&sg->sessions))) + continue; + } l = xreallocarray(l, n + 1, sizeof *l); l[n++] = s; } From 17655e5ba65e37787cd9920e1a89aedf6f623957 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 2 Nov 2017 18:52:05 +0000 Subject: [PATCH 4/4] Format for group list of "other sessions" is a bit weird, just list all the sessions in the group. --- format.c | 11 ++++------- tmux.1 | 2 +- window-tree.c | 6 ++---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/format.c b/format.c index e254eb22..1b967c93 100644 --- a/format.c +++ b/format.c @@ -577,9 +577,9 @@ format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe) evbuffer_free(buffer); } -/* Callback for session_group_others. */ +/* Callback for session_group_list. */ static void -format_cb_session_group_others(struct format_tree *ft, struct format_entry *fe) +format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe) { struct session *s = ft->s; struct session_group *sg; @@ -595,9 +595,6 @@ format_cb_session_group_others(struct format_tree *ft, struct format_entry *fe) buffer = evbuffer_new(); TAILQ_FOREACH(loop, &sg->sessions, gentry) { - if (loop == s) - continue; - if (EVBUFFER_LENGTH(buffer) > 0) evbuffer_add(buffer, ",", 1); evbuffer_add_printf(buffer, "%s", loop->name); @@ -1290,8 +1287,8 @@ 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_cb(ft, "session_group_others", - format_cb_session_group_others); + format_add_cb(ft, "session_group_list", + format_cb_session_group_list); } format_add_tv(ft, "session_created", &s->creation_time); diff --git a/tmux.1 b/tmux.1 index b7b2a088..a67a7274 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3714,7 +3714,7 @@ The following variables are available, where appropriate: .It Li "session_last_attached" Ta "" Ta "Time session last attached" .It Li "session_group" Ta "" Ta "Name of session group" .It Li "session_group_size" Ta "" Ta "Size of session group" -.It Li "session_group_others" Ta "" Ta "List of other sessions in group" +.It Li "session_group_list" Ta "" Ta "List of sessions in group" .It Li "session_grouped" Ta "" Ta "1 if session in a group" .It Li "session_height" Ta "" Ta "Height of session" .It Li "session_id" Ta "" Ta "Unique session ID" diff --git a/window-tree.c b/window-tree.c index 563c64e0..c83db557 100644 --- a/window-tree.c +++ b/window-tree.c @@ -44,10 +44,8 @@ static void window_tree_key(struct window_pane *, "," \ "#{session_windows} windows" \ "#{?session_grouped, " \ - "(group #{session_group}" \ - "#{?session_group_others," \ - " with #{session_group_others}," \ - "})," \ + "(group #{session_group}: " \ + "#{session_group_list})," \ "}" \ "#{?session_attached, (attached),}" \ "}" \