From 325cbe90d925d3deb90559463b6d968c31fa5924 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 16 Jun 2016 10:55:47 +0000 Subject: Allow a command to be specified to display-panes, similar to command-prompt, rather than always just selecting the pane. --- cmd-display-panes.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----- server-client.c | 9 ++++---- server-fn.c | 20 ++++++++++-------- tmux.1 | 17 ++++++++++++--- tmux.h | 4 +++- window.c | 1 + 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/cmd-display-panes.c b/cmd-display-panes.c index eed3611e..db85c813 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -18,19 +18,25 @@ #include +#include +#include + #include "tmux.h" /* * Display panes on a client. */ -enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *); +static enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *); + +static void cmd_display_panes_callback(struct client *, + struct window_pane *); const struct cmd_entry cmd_display_panes_entry = { .name = "display-panes", .alias = "displayp", - .args = { "t:", 0, 0 }, + .args = { "t:", 0, 1 }, .usage = CMD_TARGET_CLIENT_USAGE, .tflag = CMD_CLIENT, @@ -39,10 +45,53 @@ const struct cmd_entry cmd_display_panes_entry = { .exec = cmd_display_panes_exec }; -enum cmd_retval -cmd_display_panes_exec(__unused struct cmd *self, struct cmd_q *cmdq) +static enum cmd_retval +cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq) { - server_set_identify(cmdq->state.c); + struct args *args = self->args; + struct client *c = cmdq->state.c; + + if (c->identify_callback != NULL) + return (CMD_RETURN_NORMAL); + + c->identify_callback = cmd_display_panes_callback; + if (args->argc != 0) + c->identify_callback_data = xstrdup(args->argv[0]); + else + c->identify_callback_data = xstrdup("select-pane -t '%%'"); + + server_set_identify(c); return (CMD_RETURN_NORMAL); } + +static void +cmd_display_panes_callback(struct client *c, struct window_pane *wp) +{ + struct cmd_list *cmdlist; + char *template, *cmd, *expanded, *cause; + + template = c->identify_callback_data; + if (wp != NULL) { + xasprintf(&expanded, "%%%u", wp->id); + cmd = cmd_template_replace(template, expanded, 1); + + if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) { + if (cause != NULL) { + *cause = toupper((u_char) *cause); + status_message_set(c, "%s", cause); + free(cause); + } + } else { + cmdq_run(c->cmdq, cmdlist, NULL); + cmd_list_free(cmdlist); + } + + free(cmd); + free(expanded); + } + + free(c->identify_callback_data); + c->identify_callback_data = NULL; + c->identify_callback = NULL; +} diff --git a/server-client.c b/server-client.c index 11995f40..0c0b2cff 100644 --- a/server-client.c +++ b/server-client.c @@ -184,6 +184,7 @@ server_client_lost(struct client *c) c->flags |= CLIENT_DEAD; + server_clear_identify(c, NULL); status_prompt_clear(c); status_message_clear(c); @@ -606,16 +607,16 @@ server_client_handle_key(struct client *c, key_code key) return; window_unzoom(w); wp = window_pane_at_index(w, key - '0'); - if (wp != NULL && window_pane_visible(wp)) - window_set_active_pane(w, wp); - server_clear_identify(c); + if (wp != NULL && !window_pane_visible(wp)) + wp = NULL; + server_clear_identify(c, wp); return; } /* Handle status line. */ if (!(c->flags & CLIENT_READONLY)) { status_message_clear(c); - server_clear_identify(c); + server_clear_identify(c, NULL); } if (c->prompt_string != NULL) { if (!(c->flags & CLIENT_READONLY)) diff --git a/server-fn.c b/server-fn.c index 39d31f3c..89398523 100644 --- a/server-fn.c +++ b/server-fn.c @@ -441,21 +441,23 @@ server_set_identify(struct client *c) } void -server_clear_identify(struct client *c) +server_clear_identify(struct client *c, struct window_pane *wp) { - if (c->flags & CLIENT_IDENTIFY) { - c->flags &= ~CLIENT_IDENTIFY; - c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); - server_redraw_client(c); - } + if (~c->flags & CLIENT_IDENTIFY) + return; + c->flags &= ~CLIENT_IDENTIFY; + + if (c->identify_callback != NULL) + c->identify_callback(c, wp); + + c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); + server_redraw_client(c); } void server_callback_identify(__unused int fd, __unused short events, void *data) { - struct client *c = data; - - server_clear_identify(c); + server_clear_identify(data, NULL); } /* Set stdin callback. */ diff --git a/tmux.1 b/tmux.1 index 394c78d3..ffba05e9 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1458,7 +1458,11 @@ flag, see the .Sx FORMATS section. This command works only if at least one client is attached. -.It Ic display-panes Op Fl t Ar target-client +.It Xo +.Ic display-panes +.Op Fl t Ar target-client +.Op Ar template +.Xc .D1 (alias: Ic displayp ) Display a visible indicator of each pane shown by .Ar target-client . @@ -1468,11 +1472,18 @@ See the and .Ic display-panes-active-colour session options. -While the indicator is on screen, a pane may be selected with the +While the indicator is on screen, a pane may be chosen with the .Ql 0 to .Ql 9 -keys. +keys, which will cause +.Ar template +to be executed as a command with +.Ql %% +substituted by the pane ID. +The default +.Ar template +is "select-pane -t '%%'". .It Xo Ic find-window .Op Fl CNT .Op Fl F Ar format diff --git a/tmux.h b/tmux.h index b84530f2..f6588afe 100644 --- a/tmux.h +++ b/tmux.h @@ -1277,6 +1277,8 @@ struct client { struct key_table *keytable; struct event identify_timer; + void (*identify_callback)(struct client *, struct window_pane *); + void *identify_callback_data; char *message_string; struct event message_timer; @@ -1937,7 +1939,7 @@ void server_destroy_session_group(struct session *); void server_destroy_session(struct session *); void server_check_unattached(void); void server_set_identify(struct client *); -void server_clear_identify(struct client *); +void server_clear_identify(struct client *, struct window_pane *); int server_set_stdin_callback(struct client *, void (*)(struct client *, int, void *), void *, char **); void server_unzoom_window(struct window *); diff --git a/window.c b/window.c index bba8e3b1..0b24d57a 100644 --- a/window.c +++ b/window.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include -- cgit