summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2024-09-16 20:28:23 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2024-09-16 20:28:23 +0000
commitd3629fb7f0e5555191c03e9e799d25183f0d4ba6 (patch)
treea83756ccde1bfc889984ab2c866d0fa8947a8515
parent5fc70b9425f8da0468713fbf2e2c2cd61af60f0f (diff)
Add a prefix timeout option, from Conor Taylor in GitHub issue 4108.
-rw-r--r--usr.bin/tmux/options-table.c13
-rw-r--r--usr.bin/tmux/server-client.c43
-rw-r--r--usr.bin/tmux/tmux.111
-rw-r--r--usr.bin/tmux/tmux.h3
4 files changed, 63 insertions, 7 deletions
diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c
index 59cf34654aa..9ef6dedc7f7 100644
--- a/usr.bin/tmux/options-table.c
+++ b/usr.bin/tmux/options-table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.177 2024/08/21 04:37:42 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.178 2024/09/16 20:28:22 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -386,6 +386,17 @@ const struct options_table_entry options_table[] = {
.text = "Maximum number of server messages to keep."
},
+ { .name = "prefix-timeout",
+ .type = OPTIONS_TABLE_NUMBER,
+ .scope = OPTIONS_TABLE_SERVER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0,
+ .unit = "milliseconds",
+ .text = "The timeout for the prefix key if no subsequent key is "
+ "pressed. Zero means disabled."
+ },
+
{ .name = "prompt-history-limit",
.type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_SERVER,
diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c
index a8c5012224a..b929c2002c8 100644
--- a/usr.bin/tmux/server-client.c
+++ b/usr.bin/tmux/server-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.408 2024/09/11 19:12:33 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.409 2024/09/16 20:28:22 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -226,6 +226,17 @@ server_client_set_key_table(struct client *c, const char *name)
key_bindings_unref_table(c->keytable);
c->keytable = key_bindings_get_table(name, 1);
c->keytable->references++;
+ if (gettimeofday(&c->keytable->activity_time, NULL) != 0)
+ fatal("gettimeofday failed");
+}
+
+static uint64_t
+server_client_key_table_activity_diff(struct client *c)
+{
+ struct timeval diff;
+
+ timersub(&c->activity_time, &c->keytable->activity_time, &diff);
+ return ((diff.tv_sec * 1000ULL) + (diff.tv_usec / 1000ULL));
}
/* Get default key table. */
@@ -1870,7 +1881,7 @@ server_client_key_callback(struct cmdq_item *item, void *data)
struct key_table *table, *first;
struct key_binding *bd;
int xtimeout;
- uint64_t flags;
+ uint64_t flags, prefix_delay;
struct cmd_find_state fs;
key_code key0, prefix, prefix2;
@@ -1965,8 +1976,34 @@ try_again:
if (c->flags & CLIENT_REPEAT)
log_debug("currently repeating");
- /* Try to see if there is a key binding in the current table. */
bd = key_bindings_get(table, key0);
+
+ /*
+ * If prefix-timeout is enabled and we're in the prefix table, see if
+ * the timeout has been exceeded. Revert to the root table if so.
+ */
+ prefix_delay = options_get_number(global_options, "prefix-timeout");
+ if (prefix_delay > 0 &&
+ strcmp(table->name, "prefix") == 0 &&
+ server_client_key_table_activity_diff(c) > prefix_delay) {
+ /*
+ * If repeating is active and this is a repeating binding,
+ * ignore the timeout.
+ */
+ if (bd != NULL &&
+ (c->flags & CLIENT_REPEAT) &&
+ (bd->flags & KEY_BINDING_REPEAT)) {
+ log_debug("prefix timeout ignored, repeat is active");
+ } else {
+ log_debug("prefix timeout exceeded");
+ server_client_set_key_table(c, NULL);
+ first = table = c->keytable;
+ server_status_client(c);
+ goto table_changed;
+ }
+ }
+
+ /* Try to see if there is a key binding in the current table. */
if (bd != NULL) {
/*
* Key was matched in this table. If currently repeating but a
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 9165234df21..c8a7d8bc4bb 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.954 2024/08/27 07:49:07 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.955 2024/09/16 20:28:22 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 27 2024 $
+.Dd $Mdocdate: September 16 2024 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -4228,6 +4228,13 @@ Like
.Ic prefix2
can be set to
.Ql None .
+.It Ic prefix-timeout Ar time
+Set the time in milliseconds for which
+.Nm
+waits after
+.Ic prefix
+is input before dismissing it.
+Can be set to zero to disable any timeout.
.It Xo Ic renumber-windows
.Op Ic on | off
.Xc
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 99f5343b5f8..f6bfb91b50a 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1226 2024/08/27 07:49:07 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1227 2024/09/16 20:28:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1982,6 +1982,7 @@ RB_HEAD(key_bindings, key_binding);
struct key_table {
const char *name;
+ struct timeval activity_time;
struct key_bindings key_bindings;
struct key_bindings default_key_bindings;