From a3dea81b496be2dd1665947a66844aa1c85434b0 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 7 Oct 2024 08:50:47 +0000 Subject: [PATCH] Add initial-repeat-time option to allow the first repeat time to be increased and later reduced, from David le Blanc in GitHub issue 4164. --- options-table.c | 14 +++++++++++++- server-client.c | 31 ++++++++++++++++++++++++++----- tmux.1 | 23 +++++++++++++++++++++-- tmux.h | 1 + 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/options-table.c b/options-table.c index 084be7e4..9e9c16f4 100644 --- a/options-table.c +++ b/options-table.c @@ -572,6 +572,18 @@ const struct options_table_entry options_table[] = { "If changed, the new value applies only to new panes." }, + { .name = "initial-repeat-time", + .type = OPTIONS_TABLE_NUMBER, + .scope = OPTIONS_TABLE_SESSION, + .minimum = 0, + .maximum = 10000, + .default_num = 0, + .unit = "milliseconds", + .text = "Time to wait for a key binding to repeat the first time the " + "key is pressed, if it is bound with the '-r' flag. " + "Subsequent presses use the 'repeat-time' option." + }, + { .name = "key-table", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SESSION, @@ -659,7 +671,7 @@ const struct options_table_entry options_table[] = { .type = OPTIONS_TABLE_NUMBER, .scope = OPTIONS_TABLE_SESSION, .minimum = 0, - .maximum = SHRT_MAX, + .maximum = 10000, .default_num = 500, .unit = "milliseconds", .text = "Time to wait for a key binding to repeat, if it is bound " diff --git a/server-client.c b/server-client.c index 8c5f3645..eda1cb83 100644 --- a/server-client.c +++ b/server-client.c @@ -1866,6 +1866,26 @@ server_client_update_latest(struct client *c) notify_client("client-active", c); } +/* Get repeat time. */ +static u_int +server_client_repeat_time(struct client *c, struct key_binding *bd) +{ + struct session *s = c->session; + u_int repeat, initial; + + if (~bd->flags & KEY_BINDING_REPEAT) + return (0); + repeat = options_get_number(s->options, "repeat-time"); + if (repeat == 0) + return (0); + if ((~c->flags & CLIENT_REPEAT) || bd->key != c->last_key) { + initial = options_get_number(s->options, "initial-repeat-time"); + if (initial != 0) + repeat = initial; + } + return (repeat); +} + /* * Handle data key input from client. This owns and can modify the key event it * is given and is responsible for freeing it. @@ -1884,7 +1904,7 @@ server_client_key_callback(struct cmdq_item *item, void *data) struct timeval tv; struct key_table *table, *first; struct key_binding *bd; - int xtimeout; + u_int repeat; uint64_t flags, prefix_delay; struct cmd_find_state fs; key_code key0, prefix, prefix2; @@ -2040,12 +2060,13 @@ try_again: * If this is a repeating key, start the timer. Otherwise reset * the client back to the root table. */ - xtimeout = options_get_number(s->options, "repeat-time"); - if (xtimeout != 0 && (bd->flags & KEY_BINDING_REPEAT)) { + repeat = server_client_repeat_time(c, bd); + if (repeat != 0) { c->flags |= CLIENT_REPEAT; + c->last_key = bd->key; - tv.tv_sec = xtimeout / 1000; - tv.tv_usec = (xtimeout % 1000) * 1000L; + tv.tv_sec = repeat / 1000; + tv.tv_usec = (repeat % 1000) * 1000L; evtimer_del(&c->repeat_timer); evtimer_add(&c->repeat_timer, &tv); } else { diff --git a/tmux.1 b/tmux.1 index a964fb04..2431a956 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3687,8 +3687,10 @@ command used to switch to them from a key binding. The .Fl r flag indicates this key may repeat, see the +.Ic initial-repeat-time +and .Ic repeat-time -option. +options. .Fl N attaches a note to the key (shown with .Ic list-keys @@ -4436,6 +4438,20 @@ is in milliseconds. Set the maximum number of lines held in window history. This setting applies only to new windows - existing window histories are not resized and retain the limit at the point they were created. +.It Ic initial-repeat-time Ar time +Set the time in milliseconds for the initial repeat when a key is bound with the +.Fl r +flag. +This allows multiple commands to be entered without pressing the prefix key +again. +See also the +.Ic repeat-time +option. +If +.Ic initial-repeat-time +is zero, +.Ic repeat-time +is used for the first key press. .It Ic key-table Ar key-table Set the default key table to .Ar key-table @@ -4544,7 +4560,7 @@ This respects the option if it has been set. If off, do not renumber the windows. .It Ic repeat-time Ar time -Allow multiple commands to be entered without pressing the prefix-key again +Allow multiple commands to be entered without pressing the prefix key again in the specified .Ar time milliseconds (the default is 500). @@ -4555,6 +4571,9 @@ flag to Repeat is enabled for the default keys bound to the .Ic resize-pane command. +See also the +.Ic initial-repeat-time +option. .It Xo Ic set-titles .Op Ic on | off .Xc diff --git a/tmux.h b/tmux.h index 579f4c70..52fb13ad 100644 --- a/tmux.h +++ b/tmux.h @@ -1909,6 +1909,7 @@ struct client { char *exit_message; struct key_table *keytable; + key_code last_key; uint64_t redraw_panes;