diff --git a/CHANGES b/CHANGES index 9fd37576..46025a6c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,10 @@ 14 January 2009 +* Rework the prefix-time stuff. The option is now call repeat-time and defaults + to 500 ms. However, it only applies to a small subset of commands, currently: + up-pane, down-pane, next-window, previous-window, resize-pane-up, + resize-pane-down. These are the commands for which it is obviously useful, + having it for everything else was just bloody annoying. * The alt-up and alt-down keys now resize a pane by five lines at a time. * switch-pane is now select-pane and requires -p to select a pane. The "o" key binding is changed to down-pane. @@ -918,7 +923,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.206 2009-01-14 21:08:52 nicm Exp $ +$Id: CHANGES,v 1.207 2009-01-14 22:13:30 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/TODO b/TODO index b1439191..02352245 100644 --- a/TODO +++ b/TODO @@ -77,4 +77,4 @@ for 0.6: - document password/locking commands - document update set/setw in man page with -g and -u flags - document xterm-keys -- remove/fix & document prefix-time (only apply to some commands?) +- document repeat-time diff --git a/cmd-down-pane.c b/cmd-down-pane.c index 109ead28..8958a353 100644 --- a/cmd-down-pane.c +++ b/cmd-down-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-down-pane.c,v 1.1 2009-01-14 19:41:15 nicm Exp $ */ +/* $Id: cmd-down-pane.c,v 1.2 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -29,7 +29,7 @@ void cmd_down_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_down_pane_entry = { "down-pane", "downp", CMD_TARGET_WINDOW_USAGE, - 0, + CMD_CANREPEAT, cmd_target_init, cmd_target_parse, cmd_down_pane_exec, diff --git a/cmd-next-window.c b/cmd-next-window.c index aaa2ac28..6b44ec80 100644 --- a/cmd-next-window.c +++ b/cmd-next-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-next-window.c,v 1.12 2008-06-06 20:02:27 nicm Exp $ */ +/* $Id: cmd-next-window.c,v 1.13 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,7 +29,7 @@ void cmd_next_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_next_window_entry = { "next-window", "next", CMD_TARGET_SESSION_USAGE, - 0, + CMD_CANREPEAT, cmd_target_init, cmd_target_parse, cmd_next_window_exec, diff --git a/cmd-previous-window.c b/cmd-previous-window.c index 5ecc3025..67b94b11 100644 --- a/cmd-previous-window.c +++ b/cmd-previous-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-previous-window.c,v 1.12 2008-06-06 20:02:27 nicm Exp $ */ +/* $Id: cmd-previous-window.c,v 1.13 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,7 +29,7 @@ void cmd_previous_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_previous_window_entry = { "previous-window", "prev", CMD_TARGET_SESSION_USAGE, - 0, + CMD_CANREPEAT, cmd_target_init, cmd_target_parse, cmd_previous_window_exec, diff --git a/cmd-resize-pane-down.c b/cmd-resize-pane-down.c index 4707ab9e..edc63f06 100644 --- a/cmd-resize-pane-down.c +++ b/cmd-resize-pane-down.c @@ -1,4 +1,4 @@ -/* $Id: cmd-resize-pane-down.c,v 1.3 2009-01-14 21:08:52 nicm Exp $ */ +/* $Id: cmd-resize-pane-down.c,v 1.4 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -32,7 +32,7 @@ void cmd_resize_pane_down_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_resize_pane_down_entry = { "resize-pane-down", "resizep-down", CMD_PANE_WINDOW_USAGE " [adjustment]", - CMD_ZEROONEARG, + CMD_ZEROONEARG|CMD_CANREPEAT, cmd_resize_pane_down_init, cmd_pane_parse, cmd_resize_pane_down_exec, diff --git a/cmd-resize-pane-up.c b/cmd-resize-pane-up.c index 8fd67f09..81f1fef2 100644 --- a/cmd-resize-pane-up.c +++ b/cmd-resize-pane-up.c @@ -1,4 +1,4 @@ -/* $Id: cmd-resize-pane-up.c,v 1.3 2009-01-14 21:08:52 nicm Exp $ */ +/* $Id: cmd-resize-pane-up.c,v 1.4 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -32,7 +32,7 @@ void cmd_resize_pane_up_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_resize_pane_up_entry = { "resize-pane-up", "resizep-up", CMD_PANE_WINDOW_USAGE " [adjustment]", - CMD_ZEROONEARG, + CMD_ZEROONEARG|CMD_CANREPEAT, cmd_resize_pane_up_init, cmd_pane_parse, cmd_resize_pane_up_exec, diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index 76ccedd9..26cdd6cc 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.21 2009-01-13 00:48:50 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.22 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -53,12 +53,6 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) key = options_get_number(&s->options, "prefix"); window_pane_key(wl->window->active, ctx->curclient, key); - /* Don't want this to be repeated so reset command timer. */ - if (ctx->curclient != NULL) { - if (gettimeofday(&ctx->curclient->command_timer, NULL) != 0) - fatal("gettimeofday"); - } - if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); } diff --git a/cmd-set-option.c b/cmd-set-option.c index 97c08182..d63cc938 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.53 2009-01-14 19:23:41 nicm Exp $ */ +/* $Id: cmd-set-option.c,v 1.54 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -56,7 +56,7 @@ const struct set_option_entry set_option_table[NSETOPTION] = { { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "message-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "prefix", SET_OPTION_KEY, 0, 0, NULL }, - { "prefix-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, + { "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "set-titles", SET_OPTION_FLAG, 0, 0, NULL }, { "status", SET_OPTION_FLAG, 0, 0, NULL }, { "status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, diff --git a/cmd-up-pane.c b/cmd-up-pane.c index 8e0962f8..b0931603 100644 --- a/cmd-up-pane.c +++ b/cmd-up-pane.c @@ -1,4 +1,4 @@ -/* $Id: cmd-up-pane.c,v 1.1 2009-01-14 19:41:15 nicm Exp $ */ +/* $Id: cmd-up-pane.c,v 1.2 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -29,7 +29,7 @@ void cmd_up_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_up_pane_entry = { "up-pane", "upp", CMD_TARGET_WINDOW_USAGE, - 0, + CMD_CANREPEAT, cmd_target_init, cmd_target_parse, cmd_up_pane_exec, diff --git a/key-bindings.c b/key-bindings.c index d7961bfe..0c4b330c 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.49 2009-01-14 21:08:52 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.50 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -191,14 +191,11 @@ key_bindings_info(struct cmd_ctx *ctx, const char *fmt, ...) } void -key_bindings_dispatch(int key, struct client *c) +key_bindings_dispatch(struct key_binding *bd, struct client *c) { struct cmd_ctx ctx; struct key_binding *bd; - if ((bd = key_bindings_lookup(key)) == NULL) - return; - ctx.msgdata = NULL; ctx.cursession = c->session; ctx.curclient = c; diff --git a/server.c b/server.c index 13e09b8f..a568727a 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.100 2009-01-14 19:29:32 nicm Exp $ */ +/* $Id: server.c,v 1.101 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -573,14 +573,15 @@ server_handle_client(struct client *c) struct winlink *wl = c->session->curw; struct window_pane *wp; struct timeval tv; - int key, prefix, status, xtimeout; + struct key_binding *bd; + int key, prefix, status, flags, xtimeout; - xtimeout = options_get_number(&c->session->options, "prefix-time"); - if (xtimeout != 0) { + xtimeout = options_get_number(&c->session->options, "repeat-time"); + if (xtimeout != 0 && c->flags & CLIENT_REPEAT) { if (gettimeofday(&tv, NULL) != 0) fatal("gettimeofday"); - if (timercmp(&tv, &c->command_timer, >)) - c->flags &= ~CLIENT_PREFIX; + if (timercmp(&tv, &c->repeat_timer, >)) + c->flags &= ~(CLIENT_PREFIX|CLIENT_REPEAT); } /* Process keys. */ @@ -596,24 +597,54 @@ server_handle_client(struct client *c) if (server_locked) continue; wp = wl->window->active; /* could die - do each loop */ + + /* Prefix key pressed. */ + if (key == prefix) { + c->flags |= CLIENT_PREFIX; + continue; + } - if (key == prefix || c->flags & CLIENT_PREFIX) { - memcpy(&c->command_timer, &tv, sizeof c->command_timer); - tv.tv_sec = 0; - tv.tv_usec = xtimeout * 1000L; - timeradd(&c->command_timer, &tv, &c->command_timer); - - if (c->flags & CLIENT_PREFIX) { - key_bindings_dispatch(key, c); - if (xtimeout == 0) - c->flags &= ~CLIENT_PREFIX; - } else if (key == prefix) - c->flags |= CLIENT_PREFIX; - } else + /* Other key and no previous prefix key. */ + if (!(c->flags & CLIENT_PREFIX)) { window_pane_key(wp, c, key); - } - wp = wl->window->active; /* could die - reset again */ + continue; + } + /* Prefix key already pressed. Reset prefix and lookup key. */ + c->flags &= ~CLIENT_PREFIX; + if ((bd = key_bindings_lookup(key)) == NULL) { + /* If repeating, treat this as a key, else ignore. */ + if (c->flags & CLIENT_REPEAT) { + c->flags &= ~CLIENT_REPEAT; + window_pane_key(wp, c, key); + } + continue; + } + flags = bd->cmd->entry->flags; + + /* If already repeating, but this key can't repeat, skip it. */ + if (c->flags & CLIENT_REPEAT && !(flags & CMD_CANREPEAT)) { + c->flags &= ~CLIENT_REPEAT; + window_pane_key(wp, c, key); + continue; + } + + /* If this key can repeat, reset the repeat flags and timer. */ + if (xtimeout != 0 && flags & CMD_CANREPEAT) { + c->flags |= CLIENT_PREFIX|CLIENT_REPEAT; + + tv.tv_sec = xtimeout / 1000; + tv.tv_usec = (xtimeout % 1000) * 1000L; + if (gettimeofday(&c->repeat_timer, NULL) != 0) + fatal("gettimeofday"); + timeradd(&c->repeat_timer, &tv, &c->repeat_timer); + } + + /* Dispatch the command. */ + key_bindings_dispatch(bd, c); + } + wp = wl->window->active; /* could die - reset again */ + /* Ensure the cursor is in the right place and correctly on or off. */ status = options_get_number(&c->session->options, "status"); if (c->prompt_string == NULL && c->message_string == NULL && diff --git a/tmux.c b/tmux.c index c8254b86..81738f24 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.95 2009-01-14 18:41:55 nicm Exp $ */ +/* $Id: tmux.c,v 1.96 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -234,7 +234,7 @@ main(int argc, char **argv) options_set_number(&global_options, "message-bg", 3); options_set_number(&global_options, "message-fg", 0); options_set_number(&global_options, "prefix", META); - options_set_number(&global_options, "prefix-time", 0); + options_set_number(&global_options, "repeat-time", 500); options_set_number(&global_options, "set-titles", 1); options_set_number(&global_options, "lock-after-time", 0); options_set_number(&global_options, "status", 1); diff --git a/tmux.h b/tmux.h index 13cb5a6b..5733cb0a 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.232 2009-01-14 19:56:55 nicm Exp $ */ +/* $Id: tmux.h,v 1.233 2009-01-14 22:13:30 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -63,10 +63,6 @@ extern const char *__progname; -#ifndef GETOPT_PREFIX -#define GETOPT_PREFIX "" -#endif - #ifndef INFTIM #define INFTIM -1 #endif @@ -750,7 +746,7 @@ struct client { struct tty tty; struct timeval status_timer; - struct timeval command_timer; + struct timeval repeat_timer; u_int sx; u_int sy; @@ -762,6 +758,7 @@ struct client { #define CLIENT_MOUSE 0x4 #define CLIENT_REDRAW 0x8 #define CLIENT_STATUS 0x10 +#define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */ int flags; char *message_string; @@ -816,10 +813,11 @@ struct cmd_entry { #define CMD_STARTSERVER 0x1 #define CMD_CANTNEST 0x2 -#define CMD_KFLAG 0x4 -#define CMD_DFLAG 0x8 -#define CMD_ONEARG 0x10 -#define CMD_ZEROONEARG 0x20 +#define CMD_ONEARG 0x4 +#define CMD_ZEROONEARG 0x8 +#define CMD_CANREPEAT 0x10 +#define CMD_KFLAG 0x10 +#define CMD_DFLAG 0x20 #define CMD_GFLAG 0x40 #define CMD_UFLAG 0x80 #define CMD_AFLAG 0x100 @@ -1218,7 +1216,7 @@ void key_bindings_add(int, struct cmd *); void key_bindings_remove(int); void key_bindings_init(void); void key_bindings_free(void); -void key_bindings_dispatch(int, struct client *); +void key_bindings_dispatch(struct key_binding *, struct client *); void printflike2 key_bindings_error(struct cmd_ctx *, const char *, ...); void printflike2 key_bindings_print(struct cmd_ctx *, const char *, ...); void printflike2 key_bindings_info(struct cmd_ctx *, const char *, ...);