mirror of
https://github.com/openbsd/src.git
synced 2026-06-18 07:13:36 +02: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:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-choose-tree.c,v 1.55 2026/06/08 21:01:33 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-choose-tree.c,v 1.56 2026/06/13 10:32:54 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
|
||||
@@ -47,8 +47,8 @@ const struct cmd_entry cmd_choose_client_entry = {
|
||||
.name = "choose-client",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "F:f:hK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
|
||||
.usage = "[-hkNrZ] [-F format] [-f filter] [-K key-format] "
|
||||
.args = { "F:f:hiK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
|
||||
.usage = "[-hikNrZ] [-F format] [-f filter] [-K key-format] "
|
||||
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mode-tree.c,v 1.83 2026/06/08 15:16:21 nicm Exp $ */
|
||||
/* $OpenBSD: mode-tree.c,v 1.84 2026/06/13 10:32:54 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -49,6 +49,7 @@ struct mode_tree_data {
|
||||
const struct menu_item *menu;
|
||||
|
||||
struct sort_criteria sort_crit;
|
||||
const char *view_name;
|
||||
|
||||
mode_tree_build_cb buildcb;
|
||||
mode_tree_draw_cb drawcb;
|
||||
@@ -700,6 +701,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
|
||||
return (mti);
|
||||
}
|
||||
|
||||
void
|
||||
mode_tree_view_name(struct mode_tree_data *mtd, const char *name)
|
||||
{
|
||||
mtd->view_name = name;
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
|
||||
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),
|
||||
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
|
||||
xasprintf(&text, " %s", mti->name);
|
||||
if (w - 2 >= strlen(text)) {
|
||||
|
||||
+5
-2
@@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.1082 2026/06/13 09:17:29 nicm Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.1083 2026/06/13 10:32:54 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@@ -2864,7 +2864,7 @@ The
|
||||
command works only if at least one client is attached.
|
||||
.It Xo
|
||||
.Ic choose\-tree
|
||||
.Op Fl GhkNrswyZ
|
||||
.Op Fl GhikNrswyZ
|
||||
.Op Fl F Ar format
|
||||
.Op Fl f Ar filter
|
||||
.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 "r" Ta "Reverse sort order"
|
||||
.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 "q" Ta "Exit mode"
|
||||
.El
|
||||
@@ -2955,6 +2956,8 @@ first.
|
||||
.Pp
|
||||
.Fl N
|
||||
starts without the preview or if given twice with the larger preview.
|
||||
.Fl i
|
||||
starts showing client information instead of the preview.
|
||||
.Fl h
|
||||
hides the pane containing the mode.
|
||||
.Fl k
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1347 2026/06/13 09:17:29 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1348 2026/06/13 10:32:54 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -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 *, void *, uint64_t, const char *,
|
||||
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_no_tag(struct mode_tree_item *);
|
||||
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);
|
||||
void window_copy_set_line_numbers(struct window_pane *, int);
|
||||
|
||||
/* window-option.c */
|
||||
/* window-customize.c */
|
||||
extern const struct window_mode window_customize_mode;
|
||||
|
||||
/* names.c */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: window-client.c,v 1.39 2026/06/08 21:01:33 nicm Exp $ */
|
||||
/* $OpenBSD: window-client.c,v 1.40 2026/06/13 10:32:54 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -47,6 +47,93 @@ static void window_client_key(struct window_mode_entry *,
|
||||
"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[] = {
|
||||
{ "Detach", 'd', NULL },
|
||||
{ "Detach Tagged", 'D', NULL },
|
||||
@@ -82,7 +169,9 @@ struct window_client_modedata {
|
||||
char *format;
|
||||
char *key_format;
|
||||
char *command;
|
||||
|
||||
int hide_preview_this_pane;
|
||||
int preview_is_info;
|
||||
|
||||
struct window_client_itemdata **item_list;
|
||||
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
|
||||
window_client_draw(void *modedata, void *itemdata,
|
||||
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))
|
||||
return;
|
||||
if (data->preview_is_info) {
|
||||
window_client_draw_info(modedata, itemdata, ctx, sx, sy);
|
||||
return;
|
||||
}
|
||||
wp = c->session->curw->window->active;
|
||||
if (data->hide_preview_this_pane && wp == data->wp) {
|
||||
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[] = {
|
||||
"\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 d \033[0m\016x\017 \033[0mDetach selected %1\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);
|
||||
data->wp = wp;
|
||||
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'))
|
||||
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);
|
||||
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_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_build(mtd);
|
||||
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':
|
||||
item = mode_tree_get_current(mtd);
|
||||
mode_tree_run_command(c, NULL, data->command, item->c->ttyname);
|
||||
|
||||
Reference in New Issue
Block a user