summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/cmd-refresh-client.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2020-07-06 09:14:21 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2020-07-06 09:14:21 +0000
commita8022757870d7033fd8a3a1f96c45815e32af713 (patch)
tree674e5560136d1367755d25023b14cf3e815d76cf /usr.bin/tmux/cmd-refresh-client.c
parentb42324623d23bb2aa03a41b12b1184dd7f23f9f3 (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.c67
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;