Add -F to choose-tree, choose-client, choose-buffer to specify the

format of each line, as well as adding a couple of formats needed for
the default display.
This commit is contained in:
nicm 2017-08-09 11:43:45 +00:00
parent 31b06571aa
commit 5dd5543fe4
7 changed files with 101 additions and 50 deletions

View File

@ -30,8 +30,9 @@ const struct cmd_entry cmd_choose_tree_entry = {
.name = "choose-tree", .name = "choose-tree",
.alias = NULL, .alias = NULL,
.args = { "f:O:st:w", 0, 1 }, .args = { "F:f:O:st:w", 0, 1 },
.usage = "[-sw] [-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .usage = "[-sw] [-F format] [-f filter] [-O sort-order] "
CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -43,8 +44,9 @@ const struct cmd_entry cmd_choose_client_entry = {
.name = "choose-client", .name = "choose-client",
.alias = NULL, .alias = NULL,
.args = { "f:O:t:", 0, 1 }, .args = { "F:f:O:t:", 0, 1 },
.usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .usage = "[-F format] [-f filter] [-O sort-order] "
CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -56,8 +58,9 @@ const struct cmd_entry cmd_choose_buffer_entry = {
.name = "choose-buffer", .name = "choose-buffer",
.alias = NULL, .alias = NULL,
.args = { "f:O:t:", 0, 1 }, .args = { "F:f:O:t:", 0, 1 },
.usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .usage = "[-F format] [-f filter] [-O sort-order] "
CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },

View File

@ -1216,6 +1216,10 @@ void
format_defaults(struct format_tree *ft, struct client *c, struct session *s, format_defaults(struct format_tree *ft, struct client *c, struct session *s,
struct winlink *wl, struct window_pane *wp) struct winlink *wl, struct window_pane *wp)
{ {
format_add(ft, "session_format", "%d", s != NULL);
format_add(ft, "window_format", "%d", wl != NULL);
format_add(ft, "pane_format", "%d", wp != NULL);
if (s == NULL && c != NULL) if (s == NULL && c != NULL)
s = c->session; s = c->session;
if (wl == NULL && s != NULL) if (wl == NULL && s != NULL)
@ -1463,12 +1467,17 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
void void
format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb) format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
{ {
size_t bufsize; struct timeval tv;
char *s; size_t size;
char *s;
paste_buffer_data(pb, &bufsize); timerclear(&tv);
format_add(ft, "buffer_size", "%zu", bufsize); tv.tv_sec = paste_buffer_created(pb);
paste_buffer_data(pb, &size);
format_add(ft, "buffer_size", "%zu", size);
format_add(ft, "buffer_name", "%s", paste_buffer_name(pb)); format_add(ft, "buffer_name", "%s", paste_buffer_name(pb));
format_add_tv(ft, "buffer_created", &tv);
s = paste_make_sample(pb); s = paste_make_sample(pb);
format_add(ft, "buffer_sample", "%s", s); format_add(ft, "buffer_sample", "%s", s);

View File

@ -411,7 +411,7 @@ screen_write_hline(struct screen_write_ctx *ctx, u_int nx, int left, int right)
/* Draw a horizontal line on screen. */ /* Draw a horizontal line on screen. */
void void
screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom) screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
struct grid_cell gc; struct grid_cell gc;

26
tmux.1
View File

@ -1354,6 +1354,7 @@ the end of the visible pane.
The default is to capture only the visible contents of the pane. The default is to capture only the visible contents of the pane.
.It Xo .It Xo
.Ic choose-client .Ic choose-client
.Op Fl F Ar format
.Op Fl f Ar filter .Op Fl f Ar filter
.Op Fl O Ar sort-order .Op Fl O Ar sort-order
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
@ -1401,10 +1402,13 @@ or
.Ql activity . .Ql activity .
.Fl f .Fl f
specifies an initial filter. specifies an initial filter.
.Fl F
specifies the format for each item in the list.
This command works only if at least one client is attached. This command works only if at least one client is attached.
.It Xo .It Xo
.Ic choose-tree .Ic choose-tree
.Op Fl sw .Op Fl sw
.Op Fl F Ar format
.Op Fl f Ar filter .Op Fl f Ar filter
.Op Fl O Ar sort-order .Op Fl O Ar sort-order
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
@ -1452,6 +1456,8 @@ or
.Ql time . .Ql time .
.Fl f .Fl f
specifies an initial filter. specifies an initial filter.
.Fl F
specifies the format for each item in the tree.
This command works only if at least one client is attached. This command works only if at least one client is attached.
.It Xo .It Xo
.Ic display-panes .Ic display-panes
@ -3561,11 +3567,12 @@ The following variables are available, where appropriate:
.It Li "alternate_on" Ta "" Ta "If pane is in alternate screen" .It Li "alternate_on" Ta "" Ta "If pane is in alternate screen"
.It Li "alternate_saved_x" Ta "" Ta "Saved cursor X in alternate screen" .It Li "alternate_saved_x" Ta "" Ta "Saved cursor X in alternate screen"
.It Li "alternate_saved_y" Ta "" Ta "Saved cursor Y in alternate screen" .It Li "alternate_saved_y" Ta "" Ta "Saved cursor Y in alternate screen"
.It Li "buffer_created" Ta "" Ta "Time buffer created"
.It Li "buffer_name" Ta "" Ta "Name of buffer" .It Li "buffer_name" Ta "" Ta "Name of buffer"
.It Li "buffer_sample" Ta "" Ta "Sample of start of buffer" .It Li "buffer_sample" Ta "" Ta "Sample of start of buffer"
.It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes" .It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
.It Li "client_activity" Ta "" Ta "Integer time client last had activity" .It Li "client_activity" Ta "" Ta "Time client last had activity"
.It Li "client_created" Ta "" Ta "Integer time client created" .It Li "client_created" Ta "" Ta "Time client created"
.It Li "client_control_mode" Ta "" Ta "1 if client is in control mode" .It Li "client_control_mode" Ta "" Ta "1 if client is in control mode"
.It Li "client_discarded" Ta "" Ta "Bytes discarded when client behind" .It Li "client_discarded" Ta "" Ta "Bytes discarded when client behind"
.It Li "client_height" Ta "" Ta "Height of client" .It Li "client_height" Ta "" Ta "Height of client"
@ -3617,6 +3624,7 @@ The following variables are available, where appropriate:
.It Li "pane_current_command" Ta "" Ta "Current command if available" .It Li "pane_current_command" Ta "" Ta "Current command if available"
.It Li "pane_dead" Ta "" Ta "1 if pane is dead" .It Li "pane_dead" Ta "" Ta "1 if pane is dead"
.It Li "pane_dead_status" Ta "" Ta "Exit status of process in dead pane" .It Li "pane_dead_status" Ta "" Ta "Exit status of process in dead pane"
.It Li "pane_format" Ta "" Ta "1 if format is for a pane (not assuming the current)"
.It Li "pane_height" Ta "" Ta "Height of pane" .It Li "pane_height" Ta "" Ta "Height of pane"
.It Li "pane_id" Ta "#D" Ta "Unique pane ID" .It Li "pane_id" Ta "#D" Ta "Unique pane ID"
.It Li "pane_in_mode" Ta "" Ta "If pane is in a mode" .It Li "pane_in_mode" Ta "" Ta "If pane is in a mode"
@ -3642,9 +3650,10 @@ The following variables are available, where appropriate:
.It Li "selection_present" Ta "" Ta "1 if selection started in copy mode" .It Li "selection_present" Ta "" Ta "1 if selection started in copy mode"
.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_activity" Ta "" Ta "Integer time of session last activity" .It Li "session_activity" Ta "" Ta "Time of session last activity"
.It Li "session_created" Ta "" Ta "Integer time session created" .It Li "session_created" Ta "" Ta "Time session created"
.It Li "session_last_attached" Ta "" Ta "Integer time session last attached" .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" Ta "" Ta "Name 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_height" Ta "" Ta "Height of session" .It Li "session_height" Ta "" Ta "Height of session"
@ -3656,12 +3665,12 @@ The following variables are available, where appropriate:
.It Li "session_windows" Ta "" Ta "Number of windows in session" .It Li "session_windows" Ta "" Ta "Number of windows in session"
.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_activity" Ta "" Ta "Integer 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_active" Ta "" Ta "1 if window active" .It Li "window_active" Ta "" Ta "1 if window active"
.It Li "window_bell_flag" Ta "" Ta "1 if window has bell" .It Li "window_bell_flag" Ta "" Ta "1 if window has bell"
.It Li "window_find_matches" Ta "" Ta "Matched data from the find-window"
.It Li "window_flags" Ta "#F" Ta "Window flags" .It Li "window_flags" Ta "#F" Ta "Window flags"
.It Li "window_format" Ta "" Ta "1 if format is for a window (not assuming the current)"
.It Li "window_height" Ta "" Ta "Height of window" .It Li "window_height" Ta "" Ta "Height of window"
.It Li "window_id" Ta "" Ta "Unique window ID" .It Li "window_id" Ta "" Ta "Unique window ID"
.It Li "window_index" Ta "#I" Ta "Index of window" .It Li "window_index" Ta "#I" Ta "Index of window"
@ -4024,6 +4033,7 @@ The buffer commands are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo .It Xo
.Ic choose-buffer .Ic choose-buffer
.Op Fl F Ar format
.Op Fl f Ar filter .Op Fl f Ar filter
.Op Fl O Ar sort-order .Op Fl O Ar sort-order
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
@ -4066,6 +4076,8 @@ or
.Ql size . .Ql size .
.Fl f .Fl f
specifies an initial filter. specifies an initial filter.
.Fl F
specifies the format for each item in the list.
This command works only if at least one client is attached. This command works only if at least one client is attached.
.It Ic clear-history Op Fl t Ar target-pane .It Ic clear-history Op Fl t Ar target-pane
.D1 (alias: Ic clearhist ) .D1 (alias: Ic clearhist )

View File

@ -36,6 +36,9 @@ static void window_buffer_key(struct window_pane *,
#define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -b '%%'" #define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -b '%%'"
#define WINDOW_BUFFER_DEFAULT_FORMAT \
"#{buffer_size} bytes (#{t:buffer_created})"
const struct window_mode window_buffer_mode = { const struct window_mode window_buffer_mode = {
.name = "buffer-mode", .name = "buffer-mode",
@ -58,7 +61,6 @@ static const char *window_buffer_sort_list[] = {
struct window_buffer_itemdata { struct window_buffer_itemdata {
const char *name; const char *name;
time_t created;
u_int order; u_int order;
size_t size; size_t size;
}; };
@ -66,6 +68,7 @@ struct window_buffer_itemdata {
struct window_buffer_modedata { struct window_buffer_modedata {
struct mode_tree_data *data; struct mode_tree_data *data;
char *command; char *command;
char *format;
struct window_buffer_itemdata **item_list; struct window_buffer_itemdata **item_list;
u_int item_size; u_int item_size;
@ -132,7 +135,7 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
struct window_buffer_itemdata *item; struct window_buffer_itemdata *item;
u_int i; u_int i;
struct paste_buffer *pb; struct paste_buffer *pb;
char *tim, *text, *cp; char *text, *cp;
struct format_tree *ft; struct format_tree *ft;
for (i = 0; i < data->item_size; i++) for (i = 0; i < data->item_size; i++)
@ -145,7 +148,6 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
while ((pb = paste_walk(pb)) != NULL) { while ((pb = paste_walk(pb)) != NULL) {
item = window_buffer_add_item(data); item = window_buffer_add_item(data);
item->name = xstrdup(paste_buffer_name(pb)); item->name = xstrdup(paste_buffer_name(pb));
item->created = paste_buffer_created(pb);
paste_buffer_data(pb, &item->size); paste_buffer_data(pb, &item->size);
item->order = paste_buffer_order(pb); item->order = paste_buffer_order(pb);
} }
@ -168,12 +170,13 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
for (i = 0; i < data->item_size; i++) { for (i = 0; i < data->item_size; i++) {
item = data->item_list[i]; item = data->item_list[i];
pb = paste_get_name(item->name);
if (pb == NULL)
continue;
ft = format_create(NULL, NULL, FORMAT_NONE, 0);
format_defaults_paste_buffer(ft, pb);
if (filter != NULL) { if (filter != NULL) {
pb = paste_get_name(item->name);
if (pb == NULL)
continue;
ft = format_create(NULL, NULL, FORMAT_NONE, 0);
format_defaults_paste_buffer(ft, pb);
cp = format_expand(ft, filter); cp = format_expand(ft, filter);
if (!format_true(cp)) { if (!format_true(cp)) {
free(cp); free(cp);
@ -181,16 +184,14 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
continue; continue;
} }
free(cp); free(cp);
format_free(ft);
} }
tim = ctime(&item->created); text = format_expand(ft, data->format);
*strchr(tim, '\n') = '\0';
xasprintf(&text, "%zu bytes (%s)", item->size, tim);
mode_tree_add(data->data, NULL, item, item->order, item->name, mode_tree_add(data->data, NULL, item, item->order, item->name,
text, -1); text, -1);
free(text); free(text);
format_free(ft);
} }
} }
@ -269,6 +270,10 @@ window_buffer_init(struct window_pane *wp, __unused struct cmd_find_state *fs,
wp->modedata = data = xcalloc(1, sizeof *data); wp->modedata = data = xcalloc(1, sizeof *data);
if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_BUFFER_DEFAULT_FORMAT);
else
data->format = xstrdup(args_get(args, 'F'));
if (args == NULL || args->argc == 0) if (args == NULL || args->argc == 0)
data->command = xstrdup(WINDOW_BUFFER_DEFAULT_COMMAND); data->command = xstrdup(WINDOW_BUFFER_DEFAULT_COMMAND);
else else
@ -299,7 +304,9 @@ window_buffer_free(struct window_pane *wp)
window_buffer_free_item(data->item_list[i]); window_buffer_free_item(data->item_list[i]);
free(data->item_list); free(data->item_list);
free(data->format);
free(data->command); free(data->command);
free(data); free(data);
} }

View File

@ -36,6 +36,10 @@ static void window_client_key(struct window_pane *,
#define WINDOW_CLIENT_DEFAULT_COMMAND "detach-client -t '%%'" #define WINDOW_CLIENT_DEFAULT_COMMAND "detach-client -t '%%'"
#define WINDOW_CLIENT_DEFAULT_FORMAT \
"session #{session_name} " \
"(#{client_width}x#{client_height}, #{t:client_activity})"
const struct window_mode window_client_mode = { const struct window_mode window_client_mode = {
.name = "client-mode", .name = "client-mode",
@ -64,6 +68,7 @@ struct window_client_itemdata {
struct window_client_modedata { struct window_client_modedata {
struct mode_tree_data *data; struct mode_tree_data *data;
char *format;
char *command; char *command;
struct window_client_itemdata **item_list; struct window_client_itemdata **item_list;
@ -148,7 +153,7 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
struct window_client_itemdata *item; struct window_client_itemdata *item;
u_int i; u_int i;
struct client *c; struct client *c;
char *tim, *text, *cp; char *text, *cp;
for (i = 0; i < data->item_size; i++) for (i = 0; i < data->item_size; i++)
window_client_free_item(data->item_list[i]); window_client_free_item(data->item_list[i]);
@ -198,11 +203,7 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
free(cp); free(cp);
} }
tim = ctime(&c->activity_time.tv_sec); text = format_single(NULL, data->format, c, NULL, NULL, NULL);
*strchr(tim, '\n') = '\0';
xasprintf(&text, "session %s (%ux%u, %s)", c->session->name,
c->tty.sx, c->tty.sy, tim);
mode_tree_add(data->data, NULL, item, (uint64_t)c, c->name, mode_tree_add(data->data, NULL, item, (uint64_t)c, c->name,
text, -1); text, -1);
free(text); free(text);
@ -251,6 +252,10 @@ window_client_init(struct window_pane *wp, __unused struct cmd_find_state *fs,
wp->modedata = data = xcalloc(1, sizeof *data); wp->modedata = data = xcalloc(1, sizeof *data);
if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
else
data->format = xstrdup(args_get(args, 'F'));
if (args == NULL || args->argc == 0) if (args == NULL || args->argc == 0)
data->command = xstrdup(WINDOW_CLIENT_DEFAULT_COMMAND); data->command = xstrdup(WINDOW_CLIENT_DEFAULT_COMMAND);
else else
@ -281,7 +286,9 @@ window_client_free(struct window_pane *wp)
window_client_free_item(data->item_list[i]); window_client_free_item(data->item_list[i]);
free(data->item_list); free(data->item_list);
free(data->format);
free(data->command); free(data->command);
free(data); free(data);
} }

View File

@ -33,6 +33,22 @@ static void window_tree_key(struct window_pane *,
#define WINDOW_TREE_DEFAULT_COMMAND "switch-client -t '%%'" #define WINDOW_TREE_DEFAULT_COMMAND "switch-client -t '%%'"
#define WINDOW_TREE_DEFAULT_FORMAT \
"#{?pane_format," \
"#{pane_current_command} \"#{pane_title}\"" \
"," \
"#{?window_format," \
"#{window_name}#{window_flags} " \
"(#{window_panes} panes)" \
"#{?#{==:#{window_panes},1}, \"#{pane_title}\",}" \
"," \
"#{session_windows} windows" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
"#{?session_attached, (attached),}" \
"}" \
"}"
const struct window_mode window_tree_mode = { const struct window_mode window_tree_mode = {
.name = "tree-mode", .name = "tree-mode",
@ -73,6 +89,7 @@ struct window_tree_modedata {
int references; int references;
struct mode_tree_data *data; struct mode_tree_data *data;
char *format;
char *command; char *command;
struct window_tree_itemdata **item_list; struct window_tree_itemdata **item_list;
@ -215,9 +232,7 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
item->winlink = wl->idx; item->winlink = wl->idx;
item->pane = wp->id; item->pane = wp->id;
text = format_single(NULL, text = format_single(NULL, data->format, NULL, s, wl, wp);
"#{pane_current_command} \"#{pane_title}\"",
NULL, s, wl, wp);
xasprintf(&name, "%u", idx); xasprintf(&name, "%u", idx);
mode_tree_add(data->data, parent, item, (uint64_t)wp, name, text, -1); mode_tree_add(data->data, parent, item, (uint64_t)wp, name, text, -1);
@ -243,10 +258,7 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
item->winlink = wl->idx; item->winlink = wl->idx;
item->pane = -1; item->pane = -1;
text = format_single(NULL, text = format_single(NULL, data->format, NULL, s, wl, NULL);
"#{window_name}#{window_flags} (#{window_panes} panes)"
"#{?#{==:#{window_panes},1}, \"#{pane_title}\",}",
NULL, s, wl, NULL);
xasprintf(&name, "%u", wl->idx); xasprintf(&name, "%u", wl->idx);
if (data->type == WINDOW_TREE_SESSION || if (data->type == WINDOW_TREE_SESSION ||
@ -319,12 +331,7 @@ window_tree_build_session(struct session *s, void* modedata,
item->winlink = -1; item->winlink = -1;
item->pane = -1; item->pane = -1;
text = format_single(NULL, text = format_single(NULL, data->format, NULL, s, NULL, NULL);
"#{session_windows} windows"
"#{?session_grouped, (group ,}"
"#{session_group}#{?session_grouped,),}"
"#{?session_attached, (attached),}",
NULL, s, NULL, NULL);
if (data->type == WINDOW_TREE_SESSION) if (data->type == WINDOW_TREE_SESSION)
expanded = 0; expanded = 0;
@ -755,6 +762,10 @@ window_tree_init(struct window_pane *wp, struct cmd_find_state *fs,
data->wp = wp; data->wp = wp;
data->references = 1; data->references = 1;
if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT);
else
data->format = xstrdup(args_get(args, 'F'));
if (args == NULL || args->argc == 0) if (args == NULL || args->argc == 0)
data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND); data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND);
else else
@ -786,7 +797,9 @@ window_tree_destroy(struct window_tree_modedata *data)
window_tree_free_item(data->item_list[i]); window_tree_free_item(data->item_list[i]);
free(data->item_list); free(data->item_list);
free(data->format);
free(data->command); free(data->command);
free(data); free(data);
} }