mirror of
https://github.com/tmux/tmux.git
synced 2026-06-20 09:25:12 +00:00
Extend client mode so the preview can be changed to a view with a
summary of the client terminal and its features, intended to make troubleshooting easier. "choose-client -i" or the "i" key in the mode.
This commit is contained in:
@@ -47,8 +47,8 @@ const struct cmd_entry cmd_choose_client_entry = {
|
|||||||
.name = "choose-client",
|
.name = "choose-client",
|
||||||
.alias = NULL,
|
.alias = NULL,
|
||||||
|
|
||||||
.args = { "F:f:hK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
|
.args = { "F:f:hiK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
|
||||||
.usage = "[-hkNrZ] [-F format] [-f filter] [-K key-format] "
|
.usage = "[-hikNrZ] [-F format] [-f filter] [-K key-format] "
|
||||||
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
|
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
|
|||||||
14
mode-tree.c
14
mode-tree.c
@@ -49,6 +49,7 @@ struct mode_tree_data {
|
|||||||
const struct menu_item *menu;
|
const struct menu_item *menu;
|
||||||
|
|
||||||
struct sort_criteria sort_crit;
|
struct sort_criteria sort_crit;
|
||||||
|
const char *view_name;
|
||||||
|
|
||||||
mode_tree_build_cb buildcb;
|
mode_tree_build_cb buildcb;
|
||||||
mode_tree_draw_cb drawcb;
|
mode_tree_draw_cb drawcb;
|
||||||
@@ -700,6 +701,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
|
|||||||
return (mti);
|
return (mti);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mode_tree_view_name(struct mode_tree_data *mtd, const char *name)
|
||||||
|
{
|
||||||
|
mtd->view_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mode_tree_draw_as_parent(struct mode_tree_item *mti)
|
mode_tree_draw_as_parent(struct mode_tree_item *mti)
|
||||||
{
|
{
|
||||||
@@ -884,9 +891,12 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
|||||||
screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, NULL, NULL);
|
screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, NULL, NULL);
|
||||||
|
|
||||||
if (mtd->sort_crit.order_seq != NULL) {
|
if (mtd->sort_crit.order_seq != NULL) {
|
||||||
xasprintf(&text, " %s (sort: %s%s)", mti->name,
|
xasprintf(&text, " %s (sort: %s%s)%s%s%s", mti->name,
|
||||||
sort_order_to_string(mtd->sort_crit.order),
|
sort_order_to_string(mtd->sort_crit.order),
|
||||||
mtd->sort_crit.reversed ? ", reversed" : "");
|
mtd->sort_crit.reversed ? ", reversed" : "",
|
||||||
|
mtd->view_name == NULL ? "" : " (view: ",
|
||||||
|
mtd->view_name == NULL ? "" : mtd->view_name,
|
||||||
|
mtd->view_name == NULL ? "" : ")");
|
||||||
} else
|
} else
|
||||||
xasprintf(&text, " %s", mti->name);
|
xasprintf(&text, " %s", mti->name);
|
||||||
if (w - 2 >= strlen(text)) {
|
if (w - 2 >= strlen(text)) {
|
||||||
|
|||||||
5
tmux.1
5
tmux.1
@@ -2864,7 +2864,7 @@ The
|
|||||||
command works only if at least one client is attached.
|
command works only if at least one client is attached.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic choose\-tree
|
.Ic choose\-tree
|
||||||
.Op Fl GhkNrswyZ
|
.Op Fl GhikNrswyZ
|
||||||
.Op Fl F Ar format
|
.Op Fl F Ar format
|
||||||
.Op Fl f Ar filter
|
.Op Fl f Ar filter
|
||||||
.Op Fl K Ar key\-format
|
.Op Fl K Ar key\-format
|
||||||
@@ -2916,6 +2916,7 @@ The following keys may be used in tree mode:
|
|||||||
.It Li "O" Ta "Change sort order"
|
.It Li "O" Ta "Change sort order"
|
||||||
.It Li "r" Ta "Reverse sort order"
|
.It Li "r" Ta "Reverse sort order"
|
||||||
.It Li "v" Ta "Toggle preview"
|
.It Li "v" Ta "Toggle preview"
|
||||||
|
.It Li "i" Ta "Change view (preview and client information)"
|
||||||
.It Li "F1 or C\-h" Ta "Display help"
|
.It Li "F1 or C\-h" Ta "Display help"
|
||||||
.It Li "q" Ta "Exit mode"
|
.It Li "q" Ta "Exit mode"
|
||||||
.El
|
.El
|
||||||
@@ -2955,6 +2956,8 @@ first.
|
|||||||
.Pp
|
.Pp
|
||||||
.Fl N
|
.Fl N
|
||||||
starts without the preview or if given twice with the larger preview.
|
starts without the preview or if given twice with the larger preview.
|
||||||
|
.Fl i
|
||||||
|
starts showing client information instead of the preview.
|
||||||
.Fl h
|
.Fl h
|
||||||
hides the pane containing the mode.
|
hides the pane containing the mode.
|
||||||
.Fl k
|
.Fl k
|
||||||
|
|||||||
3
tmux.h
3
tmux.h
@@ -3565,6 +3565,7 @@ void mode_tree_resize(struct mode_tree_data *, u_int, u_int);
|
|||||||
struct mode_tree_item *mode_tree_add(struct mode_tree_data *,
|
struct mode_tree_item *mode_tree_add(struct mode_tree_data *,
|
||||||
struct mode_tree_item *, void *, uint64_t, const char *,
|
struct mode_tree_item *, void *, uint64_t, const char *,
|
||||||
const char *, int);
|
const char *, int);
|
||||||
|
void mode_tree_view_name(struct mode_tree_data *, const char *);
|
||||||
void mode_tree_draw_as_parent(struct mode_tree_item *);
|
void mode_tree_draw_as_parent(struct mode_tree_item *);
|
||||||
void mode_tree_no_tag(struct mode_tree_item *);
|
void mode_tree_no_tag(struct mode_tree_item *);
|
||||||
void mode_tree_align(struct mode_tree_item *, int);
|
void mode_tree_align(struct mode_tree_item *, int);
|
||||||
@@ -3606,7 +3607,7 @@ int window_copy_get_current_offset(struct window_pane *, u_int *,
|
|||||||
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
|
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
|
||||||
void window_copy_set_line_numbers(struct window_pane *, int);
|
void window_copy_set_line_numbers(struct window_pane *, int);
|
||||||
|
|
||||||
/* window-option.c */
|
/* window-customize.c */
|
||||||
extern const struct window_mode window_customize_mode;
|
extern const struct window_mode window_customize_mode;
|
||||||
|
|
||||||
/* names.c */
|
/* names.c */
|
||||||
|
|||||||
134
window-client.c
134
window-client.c
@@ -47,6 +47,93 @@ static void window_client_key(struct window_mode_entry *,
|
|||||||
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
|
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
|
||||||
"}"
|
"}"
|
||||||
|
|
||||||
|
#define WINDOW_CLIENT_FEATURE(f) \
|
||||||
|
"#{?#{I/f:" #f "}," \
|
||||||
|
"#[fg=green],#[dim]}#{p/15:#{l:" #f "}}" \
|
||||||
|
"#[default]"
|
||||||
|
static const char *window_client_info_lines[] = {
|
||||||
|
"Client Name #[acs]x#[default] "
|
||||||
|
"#{client_name} "
|
||||||
|
"#[dim](PID #{client_pid})#[default]",
|
||||||
|
"Session #[acs]x#[default] "
|
||||||
|
"#{session_name}",
|
||||||
|
"Attach Time #[acs]x#[default] "
|
||||||
|
"#{t:client_created} "
|
||||||
|
"#[dim](#{t/r:client_created})#[default]",
|
||||||
|
"Activity Time #[acs]x#[default] "
|
||||||
|
"#{t:client_created} "
|
||||||
|
"#[dim](#{t/r:client_created})#[default]",
|
||||||
|
"Terminal Type #[acs]x#[default] "
|
||||||
|
"#{?client_termtype,#{client_termtype},Unknown}",
|
||||||
|
"TERM #[acs]x#[default] "
|
||||||
|
"#{client_termname}",
|
||||||
|
"Size #[acs]x#[default] "
|
||||||
|
"#{client_width}x#{client_height} "
|
||||||
|
"#[dim](cell #{client_cell_width}x#{client_cell_height})#[default]",
|
||||||
|
"Bytes Written #[acs]x#[default] "
|
||||||
|
"#{client_written} "
|
||||||
|
"#[dim](#{client_discarded} discarded)#[default]",
|
||||||
|
|
||||||
|
"Features #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(256) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(RGB) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(bpaste) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(ccolour),
|
||||||
|
" #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(clipboard) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(cstyle) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(extkeys) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(focus),
|
||||||
|
" #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(hyperlinks) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(ignorefkeys) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(margins) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(mouse),
|
||||||
|
" #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(osc7) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(overline) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(progressbar) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(rectfill),
|
||||||
|
" #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(sixel) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(strikethrough) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(sync) " "
|
||||||
|
WINDOW_CLIENT_FEATURE(title),
|
||||||
|
" #[acs]x#[default] "
|
||||||
|
WINDOW_CLIENT_FEATURE(usstyle),
|
||||||
|
"#[acs]qqqqqqqqqqqqqqn#{R:q,#{window_width}}#[default]",
|
||||||
|
|
||||||
|
"prefix #[acs]x#[default] "
|
||||||
|
"#{prefix}",
|
||||||
|
|
||||||
|
"mouse #[acs]x#[default] "
|
||||||
|
"#{?mouse,#{?#{I/c:kmous},,#[fg=red]}on,#[dim]off} "
|
||||||
|
"#{?#{I/c:kmous},,#[align=right]unavailable: [kmous] missing}",
|
||||||
|
|
||||||
|
"set-clipboard #[acs]x#[default] "
|
||||||
|
"#{?#{!=:#{set-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{set-clipboard},#[dim]off} "
|
||||||
|
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
|
||||||
|
|
||||||
|
"get-clipboard #[acs]x#[default] "
|
||||||
|
"#{?#{!=:#{get-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{get-clipboard},#[dim]off} "
|
||||||
|
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
|
||||||
|
|
||||||
|
"focus-events #[acs]x#[default] "
|
||||||
|
"#{?focus-events,#{?#{I/f:focus},,#[fg=red]}on,#[dim]off} "
|
||||||
|
"#{?#{I/f:focus},,#[align=right]unavailable: [Enfcs] or [Dcfcs] missing}",
|
||||||
|
|
||||||
|
"extended-keys #[acs]x#[default] "
|
||||||
|
"#{?#{!=:#{extended-keys},off},#{?#{I/f:extkeys},,#[fg=red]}#{extended-keys},#[dim]off} "
|
||||||
|
"#{?#{I/f:extkeys},,#[align=right]unavailable: [Eneks] or [Dseks] missing}",
|
||||||
|
|
||||||
|
"set-titles #[acs]x#[default] "
|
||||||
|
"#{?set-titles,on,#[dim]off}",
|
||||||
|
|
||||||
|
"escape-time #[acs]x#[default] "
|
||||||
|
"#{escape-time} ms",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct menu_item window_client_menu_items[] = {
|
static const struct menu_item window_client_menu_items[] = {
|
||||||
{ "Detach", 'd', NULL },
|
{ "Detach", 'd', NULL },
|
||||||
{ "Detach Tagged", 'D', NULL },
|
{ "Detach Tagged", 'D', NULL },
|
||||||
@@ -82,7 +169,9 @@ struct window_client_modedata {
|
|||||||
char *format;
|
char *format;
|
||||||
char *key_format;
|
char *key_format;
|
||||||
char *command;
|
char *command;
|
||||||
|
|
||||||
int hide_preview_this_pane;
|
int hide_preview_this_pane;
|
||||||
|
int preview_is_info;
|
||||||
|
|
||||||
struct window_client_itemdata **item_list;
|
struct window_client_itemdata **item_list;
|
||||||
u_int item_size;
|
u_int item_size;
|
||||||
@@ -162,6 +251,32 @@ window_client_build(void *modedata, struct sort_criteria *sort_crit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_client_draw_info(__unused void *modedata, void *itemdata,
|
||||||
|
struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
||||||
|
{
|
||||||
|
struct window_client_itemdata *item = itemdata;
|
||||||
|
struct client *c = item->c;
|
||||||
|
struct screen *s = ctx->s;
|
||||||
|
u_int cx = s->cx, cy = s->cy, i;
|
||||||
|
struct format_tree *ft;
|
||||||
|
char *expanded;
|
||||||
|
|
||||||
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
screen_write_cursormove(ctx, cx, cy, 0);
|
||||||
|
for (i = 0; i < nitems(window_client_info_lines); i++) {
|
||||||
|
if (i == sy)
|
||||||
|
break;
|
||||||
|
expanded = format_expand(ft, window_client_info_lines[i]);
|
||||||
|
screen_write_cursormove(ctx, cx, cy + i, 0);
|
||||||
|
format_draw(ctx, &grid_default_cell, sx, expanded, NULL, 0);
|
||||||
|
free(expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
format_free(ft);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_client_draw(void *modedata, void *itemdata,
|
window_client_draw(void *modedata, void *itemdata,
|
||||||
struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
||||||
@@ -175,6 +290,10 @@ window_client_draw(void *modedata, void *itemdata,
|
|||||||
|
|
||||||
if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
||||||
return;
|
return;
|
||||||
|
if (data->preview_is_info) {
|
||||||
|
window_client_draw_info(modedata, itemdata, ctx, sx, sy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
wp = c->session->curw->window->active;
|
wp = c->session->curw->window->active;
|
||||||
if (data->hide_preview_this_pane && wp == data->wp) {
|
if (data->hide_preview_this_pane && wp == data->wp) {
|
||||||
if (!TAILQ_EMPTY(&c->session->curw->window->last_panes))
|
if (!TAILQ_EMPTY(&c->session->curw->window->last_panes))
|
||||||
@@ -250,6 +369,7 @@ window_client_sort(struct sort_criteria *sort_crit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char* window_client_help_lines[] = {
|
static const char* window_client_help_lines[] = {
|
||||||
|
"\r\033[1m i \033[0m\016x\017 \033[0mToggle info view\n",
|
||||||
"\r\033[1m Enter \033[0m\016x\017 \033[0mChoose selected %1\n",
|
"\r\033[1m Enter \033[0m\016x\017 \033[0mChoose selected %1\n",
|
||||||
"\r\033[1m d \033[0m\016x\017 \033[0mDetach selected %1\n",
|
"\r\033[1m d \033[0m\016x\017 \033[0mDetach selected %1\n",
|
||||||
"\r\033[1m D \033[0m\016x\017 \033[0mDetach tagged %1s\n",
|
"\r\033[1m D \033[0m\016x\017 \033[0mDetach tagged %1s\n",
|
||||||
@@ -280,6 +400,7 @@ window_client_init(struct window_mode_entry *wme,
|
|||||||
wme->data = data = xcalloc(1, sizeof *data);
|
wme->data = data = xcalloc(1, sizeof *data);
|
||||||
data->wp = wp;
|
data->wp = wp;
|
||||||
data->hide_preview_this_pane = args != NULL && args_has(args, 'h');
|
data->hide_preview_this_pane = args != NULL && args_has(args, 'h');
|
||||||
|
data->preview_is_info = args != NULL && args_has(args, 'i');
|
||||||
|
|
||||||
if (args == NULL || !args_has(args, 'F'))
|
if (args == NULL || !args_has(args, 'F'))
|
||||||
data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
|
data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
|
||||||
@@ -300,6 +421,11 @@ window_client_init(struct window_mode_entry *wme,
|
|||||||
window_client_help, data, window_client_menu_items, &s);
|
window_client_help, data, window_client_menu_items, &s);
|
||||||
mode_tree_zoom(data->data, args);
|
mode_tree_zoom(data->data, args);
|
||||||
|
|
||||||
|
if (data->preview_is_info)
|
||||||
|
mode_tree_view_name(data->data, "info");
|
||||||
|
else
|
||||||
|
mode_tree_view_name(data->data, "preview");
|
||||||
|
|
||||||
mode_tree_build(data->data);
|
mode_tree_build(data->data);
|
||||||
mode_tree_draw(data->data);
|
mode_tree_draw(data->data);
|
||||||
|
|
||||||
@@ -389,6 +515,14 @@ window_client_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
mode_tree_each_tagged(mtd, window_client_do_detach, c, key, 0);
|
mode_tree_each_tagged(mtd, window_client_do_detach, c, key, 0);
|
||||||
mode_tree_build(mtd);
|
mode_tree_build(mtd);
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
data->preview_is_info = !data->preview_is_info;
|
||||||
|
if (data->preview_is_info)
|
||||||
|
mode_tree_view_name(mtd, "info");
|
||||||
|
else
|
||||||
|
mode_tree_view_name(mtd, "preview");
|
||||||
|
mode_tree_build(mtd);
|
||||||
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
item = mode_tree_get_current(mtd);
|
item = mode_tree_get_current(mtd);
|
||||||
mode_tree_run_command(c, NULL, data->command, item->c->ttyname);
|
mode_tree_run_command(c, NULL, data->command, item->c->ttyname);
|
||||||
|
|||||||
Reference in New Issue
Block a user