From 76d6d3641f271be1756e41494960d96714e7ee58 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 11 Oct 2016 07:23:34 +0000 Subject: Fundamental change to how copy mode key bindings work: The vi-copy and emacs-copy mode key tables are gone, and instead copy mode commands are bound in one of two normal key tables ("copy-mode" or "copy-mode-vi"). Keys are bound to "send-keys -X copy-mode-command". So: bind -temacs-copy C-Up scroll-up bind -temacs-copy -R5 WheelUpPane scroll-up Becomes: bind -Tcopy-mode C-Up send -X scroll-up bind -Tcopy-mode WheelUpPane send -N5 -X scroll-up This allows the full command parser and command set to be used - for example, we can use the normal command prompt for searching, jumping, and so on instead of a custom one: bind -Tcopy-mode C-r command-prompt -p'search up' "send -X search-backward '%%'" command-prompt also gets a -1 option to only require on key press, which is needed for jumping. The plan is to get rid of mode keys entirely, so more to come eventually. --- cmd-send-keys.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'cmd-send-keys.c') diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 9d6b41d8..e3b8d6e4 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -33,8 +33,8 @@ const struct cmd_entry cmd_send_keys_entry = { .name = "send-keys", .alias = "send", - .args = { "lRMt:", 0, -1 }, - .usage = "[-lRM] " CMD_TARGET_PANE_USAGE " key ...", + .args = { "lXRMN:t:", 0, -1 }, + .usage = "[-lXRM] [-N repeat-count] " CMD_TARGET_PANE_USAGE " key ...", .tflag = CMD_PANE, @@ -59,12 +59,44 @@ static enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; + struct client *c = cmdq->state.c; struct window_pane *wp = cmdq->state.tflag.wp; struct session *s = cmdq->state.tflag.s; struct mouse_event *m = &cmdq->item->mouse; const u_char *keystr; int i, literal; key_code key; + u_int np; + char *cause = NULL; + + if (args_has(args, 'N')) { + if (wp->mode == NULL || wp->mode->command == NULL) { + cmdq_error(cmdq, "not in a mode"); + return (CMD_RETURN_ERROR); + } + np = args_strtonum(args, 'N', 1, UINT_MAX, &cause); + if (cause != NULL) { + cmdq_error(cmdq, "prefix %s", cause); + free(cause); + return (CMD_RETURN_ERROR); + } + wp->modeprefix = np; + } + + if (args_has(args, 'X')) { + if (wp->mode == NULL || wp->mode->command == NULL) { + cmdq_error(cmdq, "not in a mode"); + return (CMD_RETURN_ERROR); + } + if (!m->valid) + wp->mode->command(wp, c, s, args, NULL); + else + wp->mode->command(wp, c, s, args, m); + return (CMD_RETURN_NORMAL); + } + + if (args_has(args, 'N')) /* only with -X */ + return (CMD_RETURN_NORMAL); if (args_has(args, 'M')) { wp = cmd_mouse_pane(m, &s, NULL); -- cgit