diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-07-06 09:14:21 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-07-06 09:14:21 +0000 |
commit | a8022757870d7033fd8a3a1f96c45815e32af713 (patch) | |
tree | 674e5560136d1367755d25023b14cf3e815d76cf /usr.bin/tmux/cmd-refresh-client.c | |
parent | b42324623d23bb2aa03a41b12b1184dd7f23f9f3 (diff) |
Add a way for control mode clients to subscribe to a format and be
notified of changes rather than having to poll. GitHub issue 2242.
Diffstat (limited to 'usr.bin/tmux/cmd-refresh-client.c')
-rw-r--r-- | usr.bin/tmux/cmd-refresh-client.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/usr.bin/tmux/cmd-refresh-client.c b/usr.bin/tmux/cmd-refresh-client.c index aee99980f08..d939d5e35bb 100644 --- a/usr.bin/tmux/cmd-refresh-client.c +++ b/usr.bin/tmux/cmd-refresh-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-refresh-client.c,v 1.38 2020/06/11 09:55:47 nicm Exp $ */ +/* $OpenBSD: cmd-refresh-client.c,v 1.39 2020/07/06 09:14:20 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -34,27 +34,62 @@ const struct cmd_entry cmd_refresh_client_entry = { .name = "refresh-client", .alias = "refresh", - .args = { "A:cC:Df:F:lLRSt:U", 0, 1 }, - .usage = "[-cDlLRSU] [-A pane:state] [-C XxY] [-f flags] " - CMD_TARGET_CLIENT_USAGE " [adjustment]", + .args = { "A:B:cC:Df:F:lLRSt:U", 0, 1 }, + .usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] " + "[-C XxY] [-f flags] " CMD_TARGET_CLIENT_USAGE " [adjustment]", .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG, .exec = cmd_refresh_client_exec }; static void +cmd_refresh_client_update_subscription(struct client *tc, const char *value) +{ + char *copy, *split, *name, *what; + enum control_sub_type subtype; + int subid = -1; + + copy = name = xstrdup(value); + if ((split = strchr(copy, ':')) == NULL) { + control_remove_sub(tc, copy); + goto out; + } + *split++ = '\0'; + + what = split; + if ((split = strchr(what, ':')) == NULL) + goto out; + *split++ = '\0'; + + if (strcmp(what, "%*") == 0) + subtype = CONTROL_SUB_ALL_PANES; + else if (sscanf(what, "%%%d", &subid) == 1 && subid >= 0) + subtype = CONTROL_SUB_PANE; + else if (strcmp(what, "@*") == 0) + subtype = CONTROL_SUB_ALL_WINDOWS; + else if (sscanf(what, "@%d", &subid) == 1 && subid >= 0) + subtype = CONTROL_SUB_WINDOW; + else + subtype = CONTROL_SUB_SESSION; + control_add_sub(tc, name, subtype, subid, split); + +out: + free(copy); +} + +static void cmd_refresh_client_update_offset(struct client *tc, const char *value) { struct window_pane *wp; - char *copy, *colon; + char *copy, *split; u_int pane; if (*value != '%') return; copy = xstrdup(value); - if ((colon = strchr(copy, ':')) == NULL) + if ((split = strchr(copy, ':')) == NULL) goto out; - *colon++ = '\0'; + *split++ = '\0'; if (sscanf(copy, "%%%u", &pane) != 1) goto out; @@ -62,13 +97,13 @@ cmd_refresh_client_update_offset(struct client *tc, const char *value) if (wp == NULL) goto out; - if (strcmp(colon, "on") == 0) + if (strcmp(split, "on") == 0) control_set_pane_on(tc, wp); - else if (strcmp(colon, "off") == 0) + else if (strcmp(split, "off") == 0) control_set_pane_off(tc, wp); - else if (strcmp(colon, "continue") == 0) + else if (strcmp(split, "continue") == 0) control_continue_pane(tc, wp); - else if (strcmp(colon, "pause") == 0) + else if (strcmp(split, "pause") == 0) control_pause_pane(tc, wp); out: @@ -156,6 +191,16 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) } return (CMD_RETURN_NORMAL); } + if (args_has(args, 'B')) { + if (~tc->flags & CLIENT_CONTROL) + goto not_control_client; + value = args_first_value(args, 'B', &av); + while (value != NULL) { + cmd_refresh_client_update_subscription(tc, value); + value = args_next_value(&av); + } + return (CMD_RETURN_NORMAL); + } if (args_has(args, 'C')) { if (~tc->flags & CLIENT_CONTROL) goto not_control_client; |