diff options
author | nicm <nicm> | 2016-10-11 07:23:34 +0000 |
---|---|---|
committer | nicm <nicm> | 2016-10-11 07:23:34 +0000 |
commit | 76d6d3641f271be1756e41494960d96714e7ee58 (patch) | |
tree | ff2b551953111d90ed5f32919fe2f3b329357bc1 | |
parent | 8b804fb5894b6717de36c5c9c96f7fd29b14a864 (diff) | |
download | rtmux-76d6d3641f271be1756e41494960d96714e7ee58.tar.gz rtmux-76d6d3641f271be1756e41494960d96714e7ee58.tar.bz2 rtmux-76d6d3641f271be1756e41494960d96714e7ee58.zip |
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.
-rw-r--r-- | cmd-bind-key.c | 51 | ||||
-rw-r--r-- | cmd-command-prompt.c | 10 | ||||
-rw-r--r-- | cmd-list-keys.c | 24 | ||||
-rw-r--r-- | cmd-send-keys.c | 36 | ||||
-rw-r--r-- | key-bindings.c | 136 | ||||
-rw-r--r-- | mode-key.c | 561 | ||||
-rw-r--r-- | server-client.c | 33 | ||||
-rw-r--r-- | status.c | 2 | ||||
-rw-r--r-- | tmux.1 | 200 | ||||
-rw-r--r-- | tmux.h | 64 | ||||
-rw-r--r-- | window-choose.c | 16 | ||||
-rw-r--r-- | window-clock.c | 8 | ||||
-rw-r--r-- | window-copy.c | 854 | ||||
-rw-r--r-- | window.c | 1 |
14 files changed, 806 insertions, 1190 deletions
diff --git a/cmd-bind-key.c b/cmd-bind-key.c index bcc179c3..69314788 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -36,8 +36,8 @@ const struct cmd_entry cmd_bind_key_entry = { .name = "bind-key", .alias = "bind", - .args = { "cnrR:t:T:", 1, -1 }, - .usage = "[-cnr] [-t mode-table] [-R repeat-count] [-T key-table] key " + .args = { "cnrt:T:", 1, -1 }, + .usage = "[-cnr] [-t mode-table] [-T key-table] key " "command [arguments]", .flags = 0, @@ -97,12 +97,10 @@ static enum cmd_retval cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key) { struct args *args = self->args; - const char *tablename, *arg; + const char *tablename; const struct mode_key_table *mtab; struct mode_key_binding *mbind, mtmp; enum mode_key_cmd cmd; - char *cause; - u_int repeat; tablename = args_get(args, 't'); if ((mtab = mode_key_findtable(tablename)) == NULL) { @@ -116,44 +114,9 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key) return (CMD_RETURN_ERROR); } - switch (cmd) { - case MODEKEYCOPY_APPENDSELECTION: - case MODEKEYCOPY_COPYSELECTION: - case MODEKEYCOPY_STARTNAMEDBUFFER: - if (args->argc == 2) - arg = NULL; - else { - arg = args->argv[2]; - if (strcmp(arg, "-x") != 0) { - cmdq_error(cmdq, "unknown argument"); - return (CMD_RETURN_ERROR); - } - } - break; - case MODEKEYCOPY_COPYPIPE: - if (args->argc != 3) { - cmdq_error(cmdq, "no argument given"); - return (CMD_RETURN_ERROR); - } - arg = args->argv[2]; - break; - default: - if (args->argc != 2) { - cmdq_error(cmdq, "no argument allowed"); - return (CMD_RETURN_ERROR); - } - arg = NULL; - break; - } - - repeat = 1; - if (args_has(args, 'R')) { - repeat = args_strtonum(args, 'R', 1, SHRT_MAX, &cause); - if (cause != NULL) { - cmdq_error(cmdq, "repeat count %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } + if (args->argc != 2) { + cmdq_error(cmdq, "no argument allowed"); + return (CMD_RETURN_ERROR); } mtmp.key = key; @@ -164,8 +127,6 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key) mbind->mode = mtmp.mode; RB_INSERT(mode_key_tree, mtab->tree, mbind); } - mbind->repeat = repeat; mbind->cmd = cmd; - mbind->arg = arg != NULL ? xstrdup(arg) : NULL; return (CMD_RETURN_NORMAL); } diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index a2fc1278..09ab9813 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -38,8 +38,8 @@ const struct cmd_entry cmd_command_prompt_entry = { .name = "command-prompt", .alias = NULL, - .args = { "I:p:t:", 0, 1 }, - .usage = "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " + .args = { "1I:p:t:", 0, 1 }, + .usage = "[-1] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " "[template]", .tflag = CMD_CLIENT, @@ -67,6 +67,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq) struct client *c = cmdq->state.c; char *prompt, *ptr, *input = NULL; size_t n; + int flags; if (c->prompt_string != NULL) return (CMD_RETURN_NORMAL); @@ -108,8 +109,11 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq) input = strsep(&cdata->next_input, ","); } + flags = 0; + if (args_has(args, '1')) + flags |= PROMPT_SINGLE; status_prompt_set(c, prompt, input, cmd_command_prompt_callback, - cmd_command_prompt_free, cdata, 0); + cmd_command_prompt_free, cdata, flags); free(prompt); return (CMD_RETURN_NORMAL); diff --git a/cmd-list-keys.c b/cmd-list-keys.c index d5f516fa..85cb4744 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -138,8 +138,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) const char *tablename, *key, *cmdstr, *mode; const struct mode_key_table *mtab; struct mode_key_binding *mbind; - char repeat[16]; - int width, keywidth, repeatwidth, any_mode; + int width, keywidth, any_mode; tablename = args_get(args, 't'); if ((mtab = mode_key_findtable(tablename)) == NULL) { @@ -147,7 +146,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } - keywidth = repeatwidth = 0; + keywidth = 0; any_mode = 0; RB_FOREACH(mbind, mode_key_tree, mtab->tree) { key = key_string_lookup_key(mbind->key); @@ -158,13 +157,6 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) width = strlen(key); if (width > keywidth) keywidth = width; - - if (mbind->repeat != 1) { - snprintf(repeat, sizeof repeat, "%u", mbind->repeat); - width = strlen(repeat); - if (width > repeatwidth) - repeatwidth = width; - } } RB_FOREACH(mbind, mode_key_tree, mtab->tree) { @@ -173,20 +165,12 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) mode = ""; if (mbind->mode != 0) mode = "c"; - snprintf(repeat, sizeof repeat, "%u", mbind->repeat); cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd); if (cmdstr != NULL) { - cmdq_print(cmdq, - "bind-key -%st %s%s%s%*s %*s %s%s%s%s", + cmdq_print(cmdq, "bind-key -%st %s%s %*s %s", mode, any_mode && *mode == '\0' ? " " : "", mtab->name, - mbind->repeat != 1 ? " -R " : - (repeatwidth == 0 ? "" : " "), - repeatwidth, mbind->repeat != 1 ? repeat : "", - (int)keywidth, key, cmdstr, - mbind->arg != NULL ? " \"" : "", - mbind->arg != NULL ? mbind->arg : "", - mbind->arg != NULL ? "\"": ""); + (int)keywidth, key, cmdstr); } } 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); diff --git a/key-bindings.c b/key-bindings.c index 0d13385d..384a9f8f 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -232,6 +232,142 @@ key_bindings_init(void) "bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'", "bind -n MouseDown3Pane if-shell -Ft= '#{mouse_any_flag}' 'select-pane -t=; send-keys -M' 'select-pane -mt='", "bind -n WheelUpPane if-shell -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'", + + "bind -Tcopy-mode C-Space send -X begin-selection", + "bind -Tcopy-mode C-a send -X start-of-line", + "bind -Tcopy-mode C-c send -X cancel", + "bind -Tcopy-mode C-e send -X end-of-line", + "bind -Tcopy-mode C-f send -X cursor-right", + "bind -Tcopy-mode C-g send -X clear-selection", + "bind -Tcopy-mode C-k send -X copy-end-of-line", + "bind -Tcopy-mode C-n send -X cursor-down", + "bind -Tcopy-mode C-p send -X cursor-up", + "bind -Tcopy-mode C-r command-prompt -p'search up' \"send -X search-backward '%%'\"", + "bind -Tcopy-mode C-s command-prompt -p'search down' \"send -X search-forward '%%'\"", + "bind -Tcopy-mode C-v send -X page-down", + "bind -Tcopy-mode C-w send -X copy-selection-and-cancel", + "bind -Tcopy-mode Escape send -X cancel", + "bind -Tcopy-mode Space send -X page-down", + "bind -Tcopy-mode , send -X jump-reverse", + "bind -Tcopy-mode \\; send -X jump-again", + "bind -Tcopy-mode F command-prompt -1p'jump backward' \"send -X jump-backward '%%'\"", + "bind -Tcopy-mode N send -X search-reverse", + "bind -Tcopy-mode R send -X rectangle-toggle", + "bind -Tcopy-mode T command-prompt -1p'jump to backward' \"send -X jump-to-backward '%%'\"", + "bind -Tcopy-mode f command-prompt -1p'jump forward' \"send -X jump-forward '%%'\"", + "bind -Tcopy-mode g command-prompt -p'goto line' \"send -X goto-line '%%'\"", + "bind -Tcopy-mode n send -X search-again", + "bind -Tcopy-mode q send -X cancel", + "bind -Tcopy-mode t command-prompt -1p'jump to forward' \"send -X jump-to-forward '%%'\"", + "bind -Tcopy-mode MouseDrag1Pane send -X begin-selection", + "bind -Tcopy-mode MouseDragEnd1Pane send -X copy-selection-and-cancel", + "bind -Tcopy-mode WheelUpPane send -N5 -X scroll-up", + "bind -Tcopy-mode WheelDownPane send -N5 -X scroll-down", + "bind -Tcopy-mode NPage send -X page-down", + "bind -Tcopy-mode PPage send -X page-up", + "bind -Tcopy-mode Up send -X cursor-up", + "bind -Tcopy-mode Down send -X cursor-down", + "bind -Tcopy-mode Left send -X cursor-left", + "bind -Tcopy-mode Right send -X cursor-right", + "bind -Tcopy-mode M-1 command-prompt -p'repeat' -I1 \"send -N '%%'\"", + "bind -Tcopy-mode M-2 command-prompt -p'repeat' -I2 \"send -N '%%'\"", + "bind -Tcopy-mode M-3 command-prompt -p'repeat' -I3 \"send -N '%%'\"", + "bind -Tcopy-mode M-4 command-prompt -p'repeat' -I4 \"send -N '%%'\"", + "bind -Tcopy-mode M-5 command-prompt -p'repeat' -I5 \"send -N '%%'\"", + "bind -Tcopy-mode M-6 command-prompt -p'repeat' -I6 \"send -N '%%'\"", + "bind -Tcopy-mode M-7 command-prompt -p'repeat' -I7 \"send -N '%%'\"", + "bind -Tcopy-mode M-8 command-prompt -p'repeat' -I8 \"send -N '%%'\"", + "bind -Tcopy-mode M-9 command-prompt -p'repeat' -I9 \"send -N '%%'\"", + "bind -Tcopy-mode M-< send -X history-top", + "bind -Tcopy-mode M-> send -X history-bottom", + "bind -Tcopy-mode M-R send -X top-line", + "bind -Tcopy-mode M-b send -X previous-word", + "bind -Tcopy-mode M-f send -X next-word-end", + "bind -Tcopy-mode M-m send -X back-to-indentation", + "bind -Tcopy-mode M-r send -X middle-line", + "bind -Tcopy-mode M-v send -X page-up", + "bind -Tcopy-mode M-w send -X copy-selection-and-cancel", + "bind -Tcopy-mode M-{ send -X previous-paragraph", + "bind -Tcopy-mode M-} send -X next-paragraph", + "bind -Tcopy-mode M-Up send -X halfpage-up", + "bind -Tcopy-mode M-Down send -X halfpage-down", + "bind -Tcopy-mode C-Up send -X scroll-up", + "bind -Tcopy-mode C-Down send -X scroll-down", + + "bind -Tcopy-mode-vi C-b send -X page-up", + "bind -Tcopy-mode-vi C-c send -X cancel", + "bind -Tcopy-mode-vi C-d send -X halfpage-down", + "bind -Tcopy-mode-vi C-e send -X scroll-down", + "bind -Tcopy-mode-vi C-f send -X page-down", + "bind -Tcopy-mode-vi C-h send -X cursor-left", + "bind -Tcopy-mode-vi C-j send -X copy-selection-and-cancel", + "bind -Tcopy-mode-vi Enter send -X copy-selection-and-cancel", + "bind -Tcopy-mode-vi C-u send -X halfpage-up", + "bind -Tcopy-mode-vi C-v send -X rectangle-toggle", + "bind -Tcopy-mode-vi C-y send -X scroll-up", + "bind -Tcopy-mode-vi Escape send -X clear-selection", + "bind -Tcopy-mode-vi Space send -X begin-selection", + "bind -Tcopy-mode-vi '$' send -X end-of-line", + "bind -Tcopy-mode-vi , send -X jump-reverse", + "bind -Tcopy-mode-vi / command-prompt -p'search down' \"send -X search-forward '%%'\"", + "bind -Tcopy-mode-vi 0 send -X start-of-line", + "bind -Tcopy-mode-vi 1 command-prompt -p'repeat' -I1 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 2 command-prompt -p'repeat' -I2 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 3 command-prompt -p'repeat' -I3 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 4 command-prompt -p'repeat' -I4 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 5 command-prompt -p'repeat' -I5 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 6 command-prompt -p'repeat' -I6 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 7 command-prompt -p'repeat' -I7 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 8 command-prompt -p'repeat' -I8 \"send -N '%%'\"", + "bind -Tcopy-mode-vi 9 command-prompt -p'repeat' -I9 \"send -N '%%'\"", + "bind -Tcopy-mode-vi : command-prompt -p'goto line' \"send -X goto-line '%%'\"", + "bind -Tcopy-mode-vi \\; send -X jump-again" + "bind -Tcopy-mode-vi ? command-prompt -p'search up' \"send -X search-backward '%%'\"", + "bind -Tcopy-mode-vi A send -X append-selection-and-cancel", + "bind -Tcopy-mode-vi B send -X previous-space", + "bind -Tcopy-mode-vi D send -X copy-end-of-line", + "bind -Tcopy-mode-vi E send -X next-space-end", + "bind -Tcopy-mode-vi F command-prompt -1p'jump backward' \"send -X jump-backward '%%'\"", + "bind -Tcopy-mode-vi G send -X history-bottom", + "bind -Tcopy-mode-vi H send -X top-line", + "bind -Tcopy-mode-vi J send -X scroll-down", + "bind -Tcopy-mode-vi K send -X scroll-up", + "bind -Tcopy-mode-vi L send -X bottom-line", + "bind -Tcopy-mode-vi M send -X middle-line", + "bind -Tcopy-mode-vi N send -X search-reverse", + "bind -Tcopy-mode-vi T command-prompt -1p'jump to backward' \"send -X jump-to-backward '%%'\"", + "bind -Tcopy-mode-vi V send -X select-line", + "bind -Tcopy-mode-vi W send -X next-space", + "bind -Tcopy-mode-vi ^ send -X back-to-indentation", + "bind -Tcopy-mode-vi b send -X previous-word", + "bind -Tcopy-mode-vi e send -X next-word-end", + "bind -Tcopy-mode-vi f command-prompt -1p'jump forward' \"send -X jump-forward '%%'\"", + "bind -Tcopy-mode-vi g send -X history-top", + "bind -Tcopy-mode-vi h send -X cursor-left", + "bind -Tcopy-mode-vi j send -X cursor-down", + "bind -Tcopy-mode-vi k send -X cursor-up", + "bind -Tcopy-mode-vi l send -X cursor-right", + "bind -Tcopy-mode-vi n send -X search-again", + "bind -Tcopy-mode-vi o send -X other-end", + "bind -Tcopy-mode-vi q send -X cancel", + "bind -Tcopy-mode-vi t command-prompt -1p'jump to forward' \"send -X jump-to-forward '%%'\"", + "bind -Tcopy-mode-vi v send -X rectangle-toggle", + "bind -Tcopy-mode-vi w send -X next-word", + "bind -Tcopy-mode-vi { send -X previous-paragraph", + "bind -Tcopy-mode-vi } send -X next-paragraph", + "bind -Tcopy-mode-vi MouseDrag1Pane send -X begin-selection", + "bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-selection-and-cancel", + "bind -Tcopy-mode-vi WheelUpPane send -N5 -X scroll-up", + "bind -Tcopy-mode-vi WheelDownPane send -N5 -X scroll-down", + "bind -Tcopy-mode-vi BSpace send -X cursor-left", + "bind -Tcopy-mode-vi NPage send -X page-down", + "bind -Tcopy-mode-vi PPage send -X page-up", + "bind -Tcopy-mode-vi Up send -X cursor-up", + "bind -Tcopy-mode-vi Down send -X cursor-down", + "bind -Tcopy-mode-vi Left send -X cursor-left", + "bind -Tcopy-mode-vi Right send -X cursor-right", + "bind -Tcopy-mode-vi C-Up send -X scroll-up", + "bind -Tcopy-mode-vi C-Down send -X scroll-down", }; u_int i; struct cmd_list *cmdlist; @@ -50,7 +50,6 @@ struct mode_key_entry { */ int mode; enum mode_key_cmd cmd; - u_int repeat; }; /* Edit keys command strings. */ @@ -113,416 +112,207 @@ static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = { { 0, NULL } }; -/* Copy keys command strings. */ -static const struct mode_key_cmdstr mode_key_cmdstr_copy[] = { - { MODEKEYCOPY_APPENDSELECTION, "append-selection" }, - { MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" }, - { MODEKEYCOPY_BOTTOMLINE, "bottom-line" }, - { MODEKEYCOPY_CANCEL, "cancel" }, - { MODEKEYCOPY_CLEARSELECTION, "clear-selection" }, - { MODEKEYCOPY_COPYPIPE, "copy-pipe" }, - { MODEKEYCOPY_COPYLINE, "copy-line" }, - { MODEKEYCOPY_COPYENDOFLINE, "copy-end-of-line" }, - { MODEKEYCOPY_COPYSELECTION, "copy-selection" }, - { MODEKEYCOPY_DOWN, "cursor-down" }, - { MODEKEYCOPY_ENDOFLINE, "end-of-line" }, - { MODEKEYCOPY_GOTOLINE, "goto-line" }, - { MODEKEYCOPY_HALFPAGEDOWN, "halfpage-down" }, - { MODEKEYCOPY_HALFPAGEUP, "halfpage-up" }, - { MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" }, - { MODEKEYCOPY_HISTORYTOP, "history-top" }, - { MODEKEYCOPY_JUMP, "jump-forward" }, - { MODEKEYCOPY_JUMPAGAIN, "jump-again" }, - { MODEKEYCOPY_JUMPREVERSE, "jump-reverse" }, - { MODEKEYCOPY_JUMPBACK, "jump-backward" }, - { MODEKEYCOPY_JUMPTO, "jump-to-forward" }, - { MODEKEYCOPY_JUMPTOBACK, "jump-to-backward" }, - { MODEKEYCOPY_LEFT, "cursor-left" }, - { MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" }, - { MODEKEYCOPY_MIDDLELINE, "middle-line" }, - { MODEKEYCOPY_NEXTPAGE, "page-down" }, - { MODEKEYCOPY_NEXTPARAGRAPH, "next-paragraph" }, - { MODEKEYCOPY_NEXTSPACE, "next-space" }, - { MODEKEYCOPY_NEXTSPACEEND, "next-space-end" }, - { MODEKEYCOPY_NEXTWORD, "next-word" }, - { MODEKEYCOPY_NEXTWORDEND, "next-word-end" }, - { MODEKEYCOPY_OTHEREND, "other-end" }, - { MODEKEYCOPY_PREVIOUSPAGE, "page-up" }, - { MODEKEYCOPY_PREVIOUSPARAGRAPH, "previous-paragraph" }, - { MODEKEYCOPY_PREVIOUSSPACE, "previous-space" }, - { MODEKEYCOPY_PREVIOUSWORD, "previous-word" }, - { MODEKEYCOPY_RIGHT, "cursor-right" }, - { MODEKEYCOPY_SCROLLDOWN, "scroll-down" }, - { MODEKEYCOPY_SCROLLUP, "scroll-up" }, - { MODEKEYCOPY_SEARCHAGAIN, "search-again" }, - { MODEKEYCOPY_SEARCHDOWN, "search-forward" }, - { MODEKEYCOPY_SEARCHREVERSE, "search-reverse" }, - { MODEKEYCOPY_SEARCHUP, "search-backward" }, - { MODEKEYCOPY_SELECTLINE, "select-line" }, - { MODEKEYCOPY_STARTNAMEDBUFFER, "start-named-buffer" }, - { MODEKEYCOPY_STARTNUMBERPREFIX, "start-number-prefix" }, - { MODEKEYCOPY_STARTOFLINE, "start-of-line" }, - { MODEKEYCOPY_STARTSELECTION, "begin-selection" }, - { MODEKEYCOPY_TOPLINE, "top-line" }, - { MODEKEYCOPY_UP, "cursor-up" }, - - { 0, NULL } -}; - /* vi editing keys. */ static const struct mode_key_entry mode_key_vi_edit[] = { - { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL, 1 }, - { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE, 1 }, - { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE, 1 }, - { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE, 1 }, - { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD, 1 }, - { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE, 1 }, - { '\n', 0, MODEKEYEDIT_ENTER, 1 }, - { '\r', 0, MODEKEYEDIT_ENTER, 1 }, - { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE, 1 }, - { KEYC_DC, 0, MODEKEYEDIT_DELETE, 1 }, - { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN, 1 }, - { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT, 1 }, - { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT, 1 }, - { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP, 1 }, - { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE, 1 }, - { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE, 1 }, - - { '$', 1, MODEKEYEDIT_ENDOFLINE, 1 }, - { '0', 1, MODEKEYEDIT_STARTOFLINE, 1 }, - { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE, 1 }, - { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE, 1 }, - { 'C', 1, MODEKEYEDIT_SWITCHMODECHANGELINE, 1 }, - { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE, 1 }, - { 'E', 1, MODEKEYEDIT_NEXTSPACEEND, 1 }, - { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE, 1 }, - { 'S', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, 1 }, - { 'W', 1, MODEKEYEDIT_NEXTSPACE, 1 }, - { 'X', 1, MODEKEYEDIT_BACKSPACE, 1 }, - { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL, 1 }, - { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE, 1 }, - { '\n', 1, MODEKEYEDIT_ENTER, 1 }, - { '\r', 1, MODEKEYEDIT_ENTER, 1 }, - { '^', 1, MODEKEYEDIT_STARTOFLINE, 1 }, - { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND, 1 }, - { 'b', 1, MODEKEYEDIT_PREVIOUSWORD, 1 }, - { 'd', 1, MODEKEYEDIT_DELETELINE, 1 }, - { 'e', 1, MODEKEYEDIT_NEXTWORDEND, 1 }, - { 'h', 1, MODEKEYEDIT_CURSORLEFT, 1 }, - { 'i', 1, MODEKEYEDIT_SWITCHMODE, 1 }, - { 'j', 1, MODEKEYEDIT_HISTORYDOWN, 1 }, - { 'k', 1, MODEKEYEDIT_HISTORYUP, 1 }, - { 'l', 1, MODEKEYEDIT_CURSORRIGHT, 1 }, - { 'p', 1, MODEKEYEDIT_PASTE, 1 }, - { 's', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTE, 1 }, - { 'w', 1, MODEKEYEDIT_NEXTWORD, 1 }, - { 'x', 1, MODEKEYEDIT_DELETE, 1 }, - { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE, 1 }, - { KEYC_DC, 1, MODEKEYEDIT_DELETE, 1 }, - { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN, 1 }, - { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT, 1 }, - { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT, 1 }, - { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP, 1 }, - - { 0, -1, 0, 1 } + { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, + { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE }, + { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, + { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, + { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, + { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE }, + { '\n', 0, MODEKEYEDIT_ENTER }, + { '\r', 0, MODEKEYEDIT_ENTER }, + { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 0, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, + { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, + + { '$', 1, MODEKEYEDIT_ENDOFLINE }, + { '0', 1, MODEKEYEDIT_STARTOFLINE }, + { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE }, + { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE }, + { 'C', 1, MODEKEYEDIT_SWITCHMODECHANGELINE }, + { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, + { 'E', 1, MODEKEYEDIT_NEXTSPACEEND }, + { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE }, + { 'S', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE }, + { 'W', 1, MODEKEYEDIT_NEXTSPACE }, + { 'X', 1, MODEKEYEDIT_BACKSPACE }, + { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL }, + { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE }, + { '\n', 1, MODEKEYEDIT_ENTER }, + { '\r', 1, MODEKEYEDIT_ENTER }, + { '^', 1, MODEKEYEDIT_STARTOFLINE }, + { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND }, + { 'b', 1, MODEKEYEDIT_PREVIOUSWORD }, + { 'd', 1, MODEKEYEDIT_DELETELINE }, + { 'e', 1, MODEKEYEDIT_NEXTWORDEND }, + { 'h', 1, MODEKEYEDIT_CURSORLEFT }, + { 'i', 1, MODEKEYEDIT_SWITCHMODE }, + { 'j', 1, MODEKEYEDIT_HISTORYDOWN }, + { 'k', 1, MODEKEYEDIT_HISTORYUP }, + { 'l', 1, MODEKEYEDIT_CURSORRIGHT }, + { 'p', 1, MODEKEYEDIT_PASTE }, + { 's', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTE }, + { 'w', 1, MODEKEYEDIT_NEXTWORD }, + { 'x', 1, MODEKEYEDIT_DELETE }, + { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 1, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP }, + + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_vi_edit; /* vi choice selection keys. */ static const struct mode_key_entry mode_key_vi_choice[] = { - { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP, 1 }, - { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL, 1 }, - { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN, 1 }, - { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN, 1 }, - { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP, 1 }, - { '\n', 0, MODEKEYCHOICE_CHOOSE, 1 }, - { '\r', 0, MODEKEYCHOICE_CHOOSE, 1 }, - { 'j', 0, MODEKEYCHOICE_DOWN, 1 }, - { 'k', 0, MODEKEYCHOICE_UP, 1 }, - { 'q', 0, MODEKEYCHOICE_CANCEL, 1 }, - { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST, 1 }, - { 'g', 0, MODEKEYCHOICE_STARTOFLIST, 1 }, - { 'H', 0, MODEKEYCHOICE_TOPLINE, 1 }, - { 'L', 0, MODEKEYCHOICE_BOTTOMLINE, 1 }, - { 'G', 0, MODEKEYCHOICE_ENDOFLIST, 1 }, - { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST, 1 }, - { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE, 1 }, - { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN, 1 }, - { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN, 1 }, - { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN, 1 }, - { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP, 1 }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP, 1 }, - { KEYC_UP, 0, MODEKEYCHOICE_UP, 1 }, - { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE, 1 }, - { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE, 1 }, - { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND, 1 }, - { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL, 1 }, - { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL, 1 }, - { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE, 1 }, - { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE, 1 }, - { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP, 1 }, - { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN, 1 }, - - { 0, -1, 0, 1 } + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, + { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, + { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, + { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN }, + { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP }, + { '\n', 0, MODEKEYCHOICE_CHOOSE }, + { '\r', 0, MODEKEYCHOICE_CHOOSE }, + { 'j', 0, MODEKEYCHOICE_DOWN }, + { 'k', 0, MODEKEYCHOICE_UP }, + { 'q', 0, MODEKEYCHOICE_CANCEL }, + { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST }, + { 'g', 0, MODEKEYCHOICE_STARTOFLIST }, + { 'H', 0, MODEKEYCHOICE_TOPLINE }, + { 'L', 0, MODEKEYCHOICE_BOTTOMLINE }, + { 'G', 0, MODEKEYCHOICE_ENDOFLIST }, + { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST }, + { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, + { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, + { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, + { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, + { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, + { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, + { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, + { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, + { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE }, + { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP }, + { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN }, + + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_vi_choice; -/* vi copy mode keys. */ -static const struct mode_key_entry mode_key_vi_copy[] = { - { ' ', 0, MODEKEYCOPY_STARTSELECTION, 1 }, - { '"', 0, MODEKEYCOPY_STARTNAMEDBUFFER, 1 }, - { '$', 0, MODEKEYCOPY_ENDOFLINE, 1 }, - { ',', 0, MODEKEYCOPY_JUMPREVERSE, 1 }, - { ';', 0, MODEKEYCOPY_JUMPAGAIN, 1 }, - { '/', 0, MODEKEYCOPY_SEARCHDOWN, 1 }, - { '0', 0, MODEKEYCOPY_STARTOFLINE, 1 }, - { '1', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '2', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '3', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '4', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '5', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '6', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '7', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '8', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { ':', 0, MODEKEYCOPY_GOTOLINE, 1 }, - { '?', 0, MODEKEYCOPY_SEARCHUP, 1 }, - { 'A', 0, MODEKEYCOPY_APPENDSELECTION, 1 }, - { 'B', 0, MODEKEYCOPY_PREVIOUSSPACE, 1 }, - { 'D', 0, MODEKEYCOPY_COPYENDOFLINE, 1 }, - { 'E', 0, MODEKEYCOPY_NEXTSPACEEND, 1 }, - { 'F', 0, MODEKEYCOPY_JUMPBACK, 1 }, - { 'G', 0, MODEKEYCOPY_HISTORYBOTTOM, 1 }, - { 'H', 0, MODEKEYCOPY_TOPLINE, 1 }, - { 'J', 0, MODEKEYCOPY_SCROLLDOWN, 1 }, - { 'K', 0, MODEKEYCOPY_SCROLLUP, 1 }, - { 'L', 0, MODEKEYCOPY_BOTTOMLINE, 1 }, - { 'M', 0, MODEKEYCOPY_MIDDLELINE, 1 }, - { 'N', 0, MODEKEYCOPY_SEARCHREVERSE, 1 }, - { 'T', 0, MODEKEYCOPY_JUMPTOBACK, 1 }, - { 'V', 0, MODEKEYCOPY_SELECTLINE, 1 }, - { 'W', 0, MODEKEYCOPY_NEXTSPACE, 1 }, - { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE, 1 }, - { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL, 1 }, - { '\004' /* C-d */, 0, MODEKEYCOPY_HALFPAGEDOWN, 1 }, - { '\005' /* C-e */, 0, MODEKEYCOPY_SCROLLDOWN, 1 }, - { '\006' /* C-f */, 0, MODEKEYCOPY_NEXTPAGE, 1 }, - { '\010' /* C-h */, 0, MODEKEYCOPY_LEFT, 1 }, - { '\025' /* C-u */, 0, MODEKEYCOPY_HALFPAGEUP, 1 }, - { '\031' /* C-y */, 0, MODEKEYCOPY_SCROLLUP, 1 }, - { '\033' /* Escape */, 0, MODEKEYCOPY_CLEARSELECTION, 1 }, - { '\n', 0, MODEKEYCOPY_COPYSELECTION, 1 }, - { '\r', 0, MODEKEYCOPY_COPYSELECTION, 1 }, - { '^', 0, MODEKEYCOPY_BACKTOINDENTATION, 1 }, - { 'b', 0, MODEKEYCOPY_PREVIOUSWORD, 1 }, - { 'e', 0, MODEKEYCOPY_NEXTWORDEND, 1 }, - { 'f', 0, MODEKEYCOPY_JUMP, 1 }, - { 'g', 0, MODEKEYCOPY_HISTORYTOP, 1 }, - { 'h', 0, MODEKEYCOPY_LEFT, 1 }, - { 'j', 0, MODEKEYCOPY_DOWN, 1 }, - { 'k', 0, MODEKEYCOPY_UP, 1 }, - { 'l', 0, MODEKEYCOPY_RIGHT, 1 }, - { 'n', 0, MODEKEYCOPY_SEARCHAGAIN, 1 }, - { 'o', 0, MODEKEYCOPY_OTHEREND, 1 }, - { 't', 0, MODEKEYCOPY_JUMPTO, 1 }, - { 'q', 0, MODEKEYCOPY_CANCEL, 1 }, - { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE, 1 }, - { 'w', 0, MODEKEYCOPY_NEXTWORD, 1 }, - { '{', 0, MODEKEYCOPY_PREVIOUSPARAGRAPH, 1 }, - { '}', 0, MODEKEYCOPY_NEXTPARAGRAPH, 1 }, - { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT, 1 }, - { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN, 1 }, - { KEYC_DOWN, 0, MODEKEYCOPY_DOWN, 1 }, - { KEYC_LEFT, 0, MODEKEYCOPY_LEFT, 1 }, - { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE, 1 }, - { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE, 1 }, - { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT, 1 }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP, 1 }, - { KEYC_UP, 0, MODEKEYCOPY_UP, 1 }, - { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP, 1 }, - { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN, 1 }, - { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION, 1 }, - { KEYC_MOUSEDRAGEND1_PANE, 0, MODEKEYCOPY_COPYSELECTION, 1 }, - - { 0, -1, 0, 1 } -}; -struct mode_key_tree mode_key_tree_vi_copy; - /* emacs editing keys. */ static const struct mode_key_entry mode_key_emacs_edit[] = { - { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE, 1 }, - { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT, 1 }, - { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL, 1 }, - { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE, 1 }, - { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE, 1 }, - { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT, 1 }, - { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE, 1 }, - { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE, 1 }, - { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE, 1 }, - { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN, 1 }, - { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP, 1 }, - { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS, 1 }, - { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE, 1 }, - { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD, 1 }, - { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE, 1 }, - { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL, 1 }, - { '\n', 0, MODEKEYEDIT_ENTER, 1 }, - { '\r', 0, MODEKEYEDIT_ENTER, 1 }, - { 'b' | KEYC_ESCAPE, 0, MODEKEYEDIT_PREVIOUSWORD, 1 }, - { 'f' | KEYC_ESCAPE, 0, MODEKEYEDIT_NEXTWORDEND, 1 }, - { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE, 1 }, - { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE, 1 }, - { KEYC_DC, 0, MODEKEYEDIT_DELETE, 1 }, - { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN, 1 }, - { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT, 1 }, - { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT, 1 }, - { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP, 1 }, - { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE, 1 }, - { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE, 1 }, - - { 0, -1, 0, 1 } + { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE }, + { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT }, + { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, + { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE }, + { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE }, + { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT }, + { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE }, + { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, + { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE }, + { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN }, + { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP }, + { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS }, + { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, + { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, + { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE }, + { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL }, + { '\n', 0, MODEKEYEDIT_ENTER }, + { '\r', 0, MODEKEYEDIT_ENTER }, + { 'b' | KEYC_ESCAPE, 0, MODEKEYEDIT_PREVIOUSWORD }, + { 'f' | KEYC_ESCAPE, 0, MODEKEYEDIT_NEXTWORDEND }, + { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 0, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, + { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, + + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_emacs_edit; /* emacs choice selection keys. */ static const struct mode_key_entry mode_key_emacs_choice[] = { - { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX, 1 }, - { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL, 1 }, - { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN, 1 }, - { '\020' /* C-p */, 0, MODEKEYCHOICE_UP, 1 }, - { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN, 1 }, - { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL, 1 }, - { '\n', 0, MODEKEYCHOICE_CHOOSE, 1 }, - { '\r', 0, MODEKEYCHOICE_CHOOSE, 1 }, - { 'q', 0, MODEKEYCHOICE_CANCEL, 1 }, - { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP, 1 }, - { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST, 1 }, - { '<' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTOFLIST, 1 }, - { 'R' | KEYC_ESCAPE, 0, MODEKEYCHOICE_TOPLINE, 1 }, - { '>' | KEYC_ESCAPE, 0, MODEKEYCHOICE_ENDOFLIST, 1 }, - { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST, 1 }, - { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE, 1 }, - { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN, 1 }, - { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN, 1 }, - { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN, 1 }, - { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP, 1 }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP, 1 }, - { KEYC_UP, 0, MODEKEYCHOICE_UP, 1 }, - { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE, 1 }, - { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE, 1 }, - { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND, 1 }, - { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL, 1 }, - { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL, 1 }, - { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE, 1 }, - { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE, 1 }, - { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP, 5 }, - { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN, 5 }, - - { 0, -1, 0, 1 } + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, + { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, + { '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, + { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN }, + { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL }, + { '\n', 0, MODEKEYCHOICE_CHOOSE }, + { '\r', 0, MODEKEYCHOICE_CHOOSE }, + { 'q', 0, MODEKEYCHOICE_CANCEL }, + { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST }, + { '<' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTOFLIST }, + { 'R' | KEYC_ESCAPE, 0, MODEKEYCHOICE_TOPLINE }, + { '>' | KEYC_ESCAPE, 0, MODEKEYCHOICE_ENDOFLIST }, + { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST }, + { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, + { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, + { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, + { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, + { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, + { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, + { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, + { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, + { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE }, + { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP }, + { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN }, + + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_emacs_choice; -/* emacs copy mode keys. */ -static const struct mode_key_entry mode_key_emacs_copy[] = { - { ' ', 0, MODEKEYCOPY_NEXTPAGE, 1 }, - { ',', 0, MODEKEYCOPY_JUMPREVERSE, 1 }, - { ';', 0, MODEKEYCOPY_JUMPAGAIN, 1 }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX, 1 }, - { '<' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYTOP, 1 }, - { '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM, 1 }, - { 'F', 0, MODEKEYCOPY_JUMPBACK, 1 }, - { 'N', 0, MODEKEYCOPY_SEARCHREVERSE, 1 }, - { 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE, 1 }, - { 'R', 0, MODEKEYCOPY_RECTANGLETOGGLE, 1 }, - { 'T', 0, MODEKEYCOPY_JUMPTOBACK, 1 }, - { '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION, 1 }, - { '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE, 1 }, - { '\002' /* C-b */, 0, MODEKEYCOPY_LEFT, 1 }, - { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL, 1 }, - { '\005' /* C-e */, 0, MODEKEYCOPY_ENDOFLINE, 1 }, - { '\006' /* C-f */, 0, MODEKEYCOPY_RIGHT, 1 }, - { '\007' /* C-g */, 0, MODEKEYCOPY_CLEARSELECTION, 1 }, - { '\013' /* C-k */, 0, MODEKEYCOPY_COPYENDOFLINE, 1 }, - { '\016' /* C-n */, 0, MODEKEYCOPY_DOWN, 1 }, - { '\020' /* C-p */, 0, MODEKEYCOPY_UP, 1 }, - { '\022' /* C-r */, 0, MODEKEYCOPY_SEARCHUP, 1 }, - { '\023' /* C-s */, 0, MODEKEYCOPY_SEARCHDOWN, 1 }, - { '\026' /* C-v */, 0, MODEKEYCOPY_NEXTPAGE, 1 }, - { '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION, 1 }, - { '\033' /* Escape */, 0, MODEKEYCOPY_CANCEL, 1 }, - { 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD, 1 }, - { 'f', 0, MODEKEYCOPY_JUMP, 1 }, - { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORDEND, 1 }, - { 'g', 0, MODEKEYCOPY_GOTOLINE, 1 }, - { 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION, 1 }, - { 'n', 0, MODEKEYCOPY_SEARCHAGAIN, 1 }, - { 'q', 0, MODEKEYCOPY_CANCEL, 1 }, - { 'r' | KEYC_ESCAPE, 0, MODEKEYCOPY_MIDDLELINE, 1 }, - { 't', 0, MODEKEYCOPY_JUMPTO, 1 }, - { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE, 1 }, - { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION, 1 }, - { '{' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPARAGRAPH, 1 }, - { '}' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTPARAGRAPH, 1 }, - { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN, 1 }, - { KEYC_DOWN | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEDOWN, 1 }, - { KEYC_DOWN, 0, MODEKEYCOPY_DOWN, 1 }, - { KEYC_LEFT, 0, MODEKEYCOPY_LEFT, 1 }, - { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE, 1 }, - { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE, 1 }, - { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT, 1 }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP, 1 }, - { KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP, 1 }, - { KEYC_UP, 0, MODEKEYCOPY_UP, 1 }, - { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP, 5 }, - { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN, 5 }, - { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION, 1 }, - { KEYC_MOUSEDRAGEND1_PANE, 0, MODEKEYCOPY_COPYSELECTION, 1 }, - - { 0, -1, 0, 1 } -}; -struct mode_key_tree mode_key_tree_emacs_copy; - /* Table mapping key table names to default settings and trees. */ const struct mode_key_table mode_key_tables[] = { { "vi-edit", mode_key_cmdstr_edit, &mode_key_tree_vi_edit, mode_key_vi_edit }, { "vi-choice", mode_key_cmdstr_choice, &mode_key_tree_vi_choice, mode_key_vi_choice }, - { "vi-copy", mode_key_cmdstr_copy, - &mode_key_tree_vi_copy, mode_key_vi_copy }, { "emacs-edit", mode_key_cmdstr_edit, &mode_key_tree_emacs_edit, mode_key_emacs_edit }, { "emacs-choice", mode_key_cmdstr_choice, &mode_key_tree_emacs_choice, mode_key_emacs_choice }, - { "emacs-copy", mode_key_cmdstr_copy, - &mode_key_tree_emacs_copy, mode_key_emacs_copy }, { NULL, NULL, NULL, NULL } }; @@ -587,10 +377,8 @@ mode_key_init_trees(void) for (ment = mtab->table; ment->mode != -1; ment++) { mbind = xmalloc(sizeof *mbind); mbind->key = ment->key; - mbind->repeat = ment->repeat; mbind->mode = ment->mode; mbind->cmd = ment->cmd; - mbind->arg = NULL; RB_INSERT(mode_key_tree, mtab->tree, mbind); } } @@ -604,8 +392,7 @@ mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree) } enum mode_key_cmd -mode_key_lookup(struct mode_key_data *mdata, key_code key, const char **arg, - u_int *repeat) +mode_key_lookup(struct mode_key_data *mdata, key_code key) { struct mode_key_binding *mbind, mtmp; @@ -616,8 +403,6 @@ mode_key_lookup(struct mode_key_data *mdata, key_code key, const char **arg, return (MODEKEY_NONE); return (MODEKEY_OTHER); } - if (repeat != NULL) - *repeat = mbind->repeat; switch (mbind->cmd) { case MODEKEYEDIT_SWITCHMODE: @@ -630,8 +415,6 @@ mode_key_lookup(struct mode_key_data *mdata, key_code key, const char **arg, mdata->mode = 1 - mdata->mode; /* FALLTHROUGH */ default: - if (arg != NULL) - *arg = mbind->arg; return (mbind->cmd); } } diff --git a/server-client.c b/server-client.c index 859a451e..70fdd51a 100644 --- a/server-client.c +++ b/server-client.c @@ -97,6 +97,13 @@ server_client_get_key_table(struct client *c) return (name); } +/* Is this client using the default key table? */ +int +server_client_is_default_key_table(struct client *c) +{ + return (strcmp(c->keytable->name, server_client_get_key_table(c)) == 0); +} + /* Create a new client. */ void server_client_create(int fd) @@ -587,6 +594,7 @@ server_client_handle_key(struct client *c, key_code key) struct window *w; struct window_pane *wp; struct timeval tv; + const char *name; struct key_table *table; struct key_binding bd_find, *bd; int xtimeout; @@ -595,6 +603,10 @@ server_client_handle_key(struct client *c, key_code key) if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) return; w = s->curw->window; + if (KEYC_IS_MOUSE(key)) + wp = cmd_mouse_pane(m, NULL, NULL); + else + wp = w->active; /* Update the activity timer. */ if (gettimeofday(&c->activity_time, NULL) != 0) @@ -645,9 +657,21 @@ server_client_handle_key(struct client *c, key_code key) goto forward; retry: + /* + * Work out the current key table. If the pane is in a mode, use + * the mode table instead of the default key table. + */ + name = NULL; + if (wp != NULL && wp->mode != NULL && wp->mode->key_table != NULL) + name = wp->mode->key_table(wp); + if (name == NULL || !server_client_is_default_key_table(c)) + table = c->keytable; + else + table = key_bindings_get_table(name, 1); + /* Try to see if there is a key binding in the current table. */ bd_find.key = key; - bd = RB_FIND(key_bindings, &c->keytable->key_bindings, &bd_find); + bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); if (bd != NULL) { /* * Key was matched in this table. If currently repeating but a @@ -665,7 +689,6 @@ retry: * Take a reference to this table to make sure the key binding * doesn't disappear. */ - table = c->keytable; table->references++; /* @@ -704,7 +727,7 @@ retry: } /* If no match and we're not in the root table, that's it. */ - if (strcmp(c->keytable->name, server_client_get_key_table(c)) != 0) { + if (name == NULL && !server_client_is_default_key_table(c)) { server_client_set_key_table(c, NULL); server_status_client(c); return; @@ -724,10 +747,6 @@ retry: forward: if (c->flags & CLIENT_READONLY) return; - if (KEYC_IS_MOUSE(key)) - wp = cmd_mouse_pane(m, NULL, NULL); - else - wp = w->active; if (wp != NULL) window_pane_key(wp, c, s, key, m); } @@ -867,7 +867,7 @@ status_prompt_key(struct client *c, key_code key) struct utf8_data tmp, *first, *last, *ud; size = utf8_strlen(c->prompt_buffer); - switch (mode_key_lookup(&c->prompt_mdata, key, NULL, NULL)) { + switch (mode_key_lookup(&c->prompt_mdata, key)) { case MODEKEYEDIT_CURSORLEFT: if (c->prompt_index > 0) { c->prompt_index--; @@ -1002,63 +1002,76 @@ It is also entered when a command that produces output, such as .Ic list-keys , is executed from a key binding. .Pp -The keys available depend on whether emacs or vi mode is selected -(see the +Commands are sent to copy mode using the +.Fl X +flag to the +.Ic send-keys +command. +When a key is pressed, copy mode automatically uses one of two key tables, +depending on the .Ic mode-keys -option). -The following keys are supported as appropriate for the mode: -.Bl -column "FunctionXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent -.It Sy "Function" Ta Sy "vi" Ta Sy "emacs" -.It Li "Append selection" Ta "A" Ta "" -.It Li "Back to indentation" Ta "^" Ta "M-m" -.It Li "Bottom of history" Ta "G" Ta "M-<" -.It Li "Clear selection" Ta "Escape" Ta "C-g" -.It Li "Copy selection" Ta "Enter" Ta "M-w" -.It Li "Copy to named buffer" Ta \&" Ta "" -.It Li "Cursor down" Ta "j" Ta "Down" -.It Li "Cursor left" Ta "h" Ta "Left" -.It Li "Cursor right" Ta "l" Ta "Right" -.It Li "Cursor to bottom line" Ta "L" Ta "" -.It Li "Cursor to middle line" Ta "M" Ta "M-r" -.It Li "Cursor to top line" Ta "H" Ta "M-R" -.It Li "Cursor up" Ta "k" Ta "Up" -.It Li "Delete entire line" Ta "d" Ta "C-u" -.It Li "Delete/Copy to end of line" Ta "D" Ta "C-k" -.It Li "End of line" Ta "$" Ta "C-e" -.It Li "Go to line" Ta ":" Ta "g" -.It Li "Half page down" Ta "C-d" Ta "M-Down" -.It Li "Half page up" Ta "C-u" Ta "M-Up" -.It Li "Jump again" Ta ";" Ta ";" -.It Li "Jump again in reverse" Ta "," Ta "," -.It Li "Jump backward" Ta "F" Ta "F" -.It Li "Jump forward" Ta "f" Ta "f" -.It Li "Jump to backward" Ta "T" Ta "" -.It Li "Jump to forward" Ta "t" Ta "" -.It Li "Next page" Ta "C-f" Ta "Page down" -.It Li "Next paragraph" Ta "}" Ta "M-}" -.It Li "Next space" Ta "W" Ta "" -.It Li "Next space, end of word" Ta "E" Ta "" -.It Li "Next word" Ta "w" Ta "" -.It Li "Next word end" Ta "e" Ta "M-f" -.It Li "Other end of selection" Ta "o" Ta "" -.It Li "Paste buffer" Ta "p" Ta "C-y" -.It Li "Previous page" Ta "C-b" Ta "Page up" -.It Li "Previous paragraph" Ta "{" Ta "M-{" -.It Li "Previous space" Ta "B" Ta "" -.It Li "Previous word" Ta "b" Ta "M-b" -.It Li "Quit mode" Ta "q" Ta "Escape" -.It Li "Rectangle toggle" Ta "v" Ta "R" -.It Li "Scroll down" Ta "C-Down or C-e" Ta "C-Down" -.It Li "Scroll up" Ta "C-Up or C-y" Ta "C-Up" -.It Li "Search again" Ta "n" Ta "n" -.It Li "Search again in reverse" Ta "N" Ta "N" -.It Li "Search backward" Ta "?" Ta "C-r" -.It Li "Search forward" Ta "/" Ta "C-s" -.It Li "Select line" Ta "V" Ta "" -.It Li "Start of line" Ta "0" Ta "C-a" -.It Li "Start selection" Ta "Space" Ta "C-Space" -.It Li "Top of history" Ta "g" Ta "M->" -.It Li "Transpose characters" Ta "" Ta "C-t" +option: +.Ic copy-mode +for emacs, or +.Ic copy-mode-vi +for vi. +Key tables may be viewed with the +.Ic list-keys +command. +.Pp +The following commands are supported in copy mode: +.Bl -column "CommandXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent +.It Sy "Command" Ta Sy "vi" Ta Sy "emacs" +.It Li "append-selection" Ta "" Ta "" +.It Li "append-selection-and-cancel" Ta "A" Ta "" +.It Li "back-to-indentation" Ta "^" Ta "M-m" +.It Li "begin-selection" Ta "Space" Ta "C-Space" +.It Li "bottom-line" Ta "L" Ta "" +.It Li "cancel" Ta "q" Ta "Escape" +.It Li "clear-selection" Ta "Escape" Ta "C-g" +.It Li "copy-end-of-line" Ta "D" Ta "C-k" +.It Li "copy-line" Ta "" Ta "" +.It Li "copy-pipe <command>" Ta "" Ta "" +.It Li "copy-selection" Ta "" Ta "" +.It Li "copy-selection-and-cancel" Ta "Enter" Ta "M-w" +.It Li "cursor-down" Ta "j" Ta "Down" +.It Li "cursor-left" Ta "h" Ta "Left" +.It Li "cursor-right" Ta "l" Ta "Right" +.It Li "cursor-up" Ta "k" Ta "Up" +.It Li "end-of-line" Ta "$" Ta "C-e" +.It Li "goto-line <line>" Ta ":" Ta "g" +.It Li "halfpage-down" Ta "C-d" Ta "M-Down" +.It Li "halfpage-up" Ta "C-u" Ta "M-Up" +.It Li "history-bottom" Ta "G" Ta "M-<" +.It Li "history-top" Ta "g" Ta "M->" +.It Li "jump-again" Ta ";" Ta ";" +.It Li "jump-backward <to>" Ta "F" Ta "F" +.It Li "jump-forward <to>" Ta "f" Ta "f" +.It Li "jump-reverse" Ta "," Ta "," +.It Li "jump-to-backward <to>" Ta "T" Ta "" +.It Li "jump-to-forward <to>" Ta "t" Ta "" +.It Li "middle-line" Ta "M" Ta "M-r" +.It Li "next-paragraph" Ta "}" Ta "M-}" +.It Li "next-space" Ta "W" Ta "" +.It Li "next-space-end" Ta "E" Ta "" +.It Li "next-word" Ta "w" Ta "" +.It Li "next-word-end" Ta "e" Ta "M-f" +.It Li "other-end" Ta "o" Ta "" +.It Li "page-down" Ta "C-f" Ta "PageDown" +.It Li "page-up" Ta "C-b" Ta "PageUp" +.It Li "previous-paragraph" Ta "{" Ta "M-{" +.It Li "previous-space" Ta "B" Ta "" +.It Li "previous-word" Ta "b" Ta "M-b" +.It Li "rectangle-toggle" Ta "v" Ta "R" +.It Li "scroll-down" Ta "C-e" Ta "C-Down" +.It Li "scroll-up" Ta "C-y" Ta "C-Up" +.It Li "search-again" Ta "n" Ta "n" +.It Li "search-backward <for>" Ta "?" Ta "C-r" +.It Li "search-forward <for>" Ta "/" Ta "C-s" +.It Li "search-reverse" Ta "N" Ta "N" +.It Li "select-line" Ta "V" Ta "" +.It Li "start-of-line" Ta "0" Ta "C-a" +.It Li "top-line" Ta "H" Ta "M-R" .El .Pp The next and previous word keys use space and the @@ -1090,59 +1103,18 @@ will then jump to the next occurrence. Commands in copy mode may be prefaced by an optional repeat count. With vi key bindings, a prefix is entered using the number keys; with emacs, the Alt (meta) key and a number begins prefix entry. -For example, to move the cursor forward by ten words, use -.Ql M-1 0 M-f -in emacs mode, and -.Ql 10w -in vi. .Pp Mode key bindings are defined in a set of named tables: .Em vi-edit and .Em emacs-edit -for keys used when line editing at the command prompt; +for keys used when line editing at the command prompt; and .Em vi-choice and .Em emacs-choice for keys used when choosing from lists (such as produced by the .Ic choose-window -command); and -.Em vi-copy -and -.Em emacs-copy -used in copy mode. -The tables may be viewed with the -.Ic list-keys -command and keys modified or removed with -.Ic bind-key -and -.Ic unbind-key . -If -.Ic append-selection , -.Ic copy-selection , -or -.Ic start-named-buffer -are given the -.Fl x -flag, -.Nm -will not exit copy mode after copying. -.Ic copy-pipe -copies the selection and pipes it to a command. -For example the following will bind -.Ql C-w -not to exit after copying and -.Ql C-q -to copy the selection into -.Pa /tmp -as well as the paste buffer: -.Bd -literal -offset indent -bind-key -temacs-copy C-w copy-selection -x -bind-key -temacs-copy C-q copy-pipe "cat >/tmp/out" -.Ed -.Pp -The paste buffer key pastes the first line from the top paste buffer on the -stack. +command). .Pp The synopsis for the .Ic copy-mode @@ -2133,7 +2105,6 @@ Commands related to key bindings are as follows: .Bl -tag -width Ds .It Xo Ic bind-key .Op Fl cnr -.Op Fl R Ar repeat-count .Op Fl t Ar mode-table .Op Fl T Ar key-table .Ar key Ar command Op Ar arguments @@ -2192,19 +2163,6 @@ is bound in the binding for command mode with .Fl c or for normal mode without. -For keys in the -.Em vi-copy -or -.Em emacs-copy -tables, -.Fl R -specifies how many times the command should be repeated. -.Pp -See the -.Sx WINDOWS AND PANES -section and the -.Ic list-keys -command for information on mode key bindings. .Pp To view the default bindings and possible commands, see the .Ic list-keys @@ -2236,7 +2194,8 @@ are listed; this may be one of: or .Em emacs-copy . .It Xo Ic send-keys -.Op Fl lMR +.Op Fl lMRX +.Op Fl N Ar repeat-count .Op Fl t Ar target-pane .Ar key Ar ... .Xc @@ -2261,6 +2220,14 @@ flag causes the terminal state to be reset. .Fl M passes through a mouse event (only valid if bound to a mouse key binding, see .Sx MOUSE SUPPORT ) . +.Pp +.Fl X +is used to send a command into copy mode - see +the +.Sx WINDOWS AND PANES +section. +.Fl N +specifies a repeat count to a copy mode command. .It Xo Ic send-prefix .Op Fl 2 .Op Fl t Ar target-pane @@ -3779,6 +3746,7 @@ session option. Commands related to the status line are as follows: .Bl -tag -width Ds .It Xo Ic command-prompt +.Op Fl 1 .Op Fl I Ar inputs .Op Fl p Ar prompts .Op Fl t Ar target-client @@ -3828,6 +3796,10 @@ Up to nine prompt responses may be replaced to .Ql %9 .Pc . +.Pp +.Fl 1 +makes the prompt only accept one key press, in this case the resulting input +is a single character. .It Xo Ic confirm-before .Op Fl p Ar prompt .Op Fl t Ar target-client @@ -38,6 +38,7 @@ extern char **environ; +struct args; struct client; struct environ; struct input_ctx; @@ -511,58 +512,6 @@ enum mode_key_cmd { MODEKEYCHOICE_TREE_EXPAND_ALL, MODEKEYCHOICE_TREE_TOGGLE, MODEKEYCHOICE_UP, - - /* Copy keys. */ - MODEKEYCOPY_APPENDSELECTION, - MODEKEYCOPY_BACKTOINDENTATION, - MODEKEYCOPY_BOTTOMLINE, - MODEKEYCOPY_CANCEL, - MODEKEYCOPY_CLEARSELECTION, - MODEKEYCOPY_COPYPIPE, - MODEKEYCOPY_COPYLINE, - MODEKEYCOPY_COPYENDOFLINE, - MODEKEYCOPY_COPYSELECTION, - MODEKEYCOPY_DOWN, - MODEKEYCOPY_ENDOFLINE, - MODEKEYCOPY_GOTOLINE, - MODEKEYCOPY_HALFPAGEDOWN, - MODEKEYCOPY_HALFPAGEUP, - MODEKEYCOPY_HISTORYBOTTOM, - MODEKEYCOPY_HISTORYTOP, - MODEKEYCOPY_JUMP, - MODEKEYCOPY_JUMPAGAIN, - MODEKEYCOPY_JUMPREVERSE, - MODEKEYCOPY_JUMPBACK, - MODEKEYCOPY_JUMPTO, - MODEKEYCOPY_JUMPTOBACK, - MODEKEYCOPY_LEFT, - MODEKEYCOPY_MIDDLELINE, - MODEKEYCOPY_NEXTPAGE, - MODEKEYCOPY_NEXTPARAGRAPH, - MODEKEYCOPY_NEXTSPACE, - MODEKEYCOPY_NEXTSPACEEND, - MODEKEYCOPY_NEXTWORD, - MODEKEYCOPY_NEXTWORDEND, - MODEKEYCOPY_OTHEREND, - MODEKEYCOPY_PREVIOUSPAGE, - MODEKEYCOPY_PREVIOUSPARAGRAPH, - MODEKEYCOPY_PREVIOUSSPACE, - MODEKEYCOPY_PREVIOUSWORD, - MODEKEYCOPY_RECTANGLETOGGLE, - MODEKEYCOPY_RIGHT, - MODEKEYCOPY_SCROLLDOWN, - MODEKEYCOPY_SCROLLUP, - MODEKEYCOPY_SEARCHAGAIN, - MODEKEYCOPY_SEARCHDOWN, - MODEKEYCOPY_SEARCHREVERSE, - MODEKEYCOPY_SEARCHUP, - MODEKEYCOPY_SELECTLINE, - MODEKEYCOPY_STARTNAMEDBUFFER, - MODEKEYCOPY_STARTNUMBERPREFIX, - MODEKEYCOPY_STARTOFLINE, - MODEKEYCOPY_STARTSELECTION, - MODEKEYCOPY_TOPLINE, - MODEKEYCOPY_UP, }; /* Data required while mode keys are in use. */ @@ -576,11 +525,9 @@ struct mode_key_data { /* Binding between a key and a command. */ struct mode_key_binding { key_code key; - u_int repeat; int mode; enum mode_key_cmd cmd; - const char *arg; RB_ENTRY(mode_key_binding) entry; }; @@ -832,6 +779,10 @@ struct window_mode { void (*resize)(struct window_pane *, u_int, u_int); void (*key)(struct window_pane *, struct client *, struct session *, key_code, struct mouse_event *); + + const char *(*key_table)(struct window_pane *); + void (*command)(struct window_pane *, struct client *, + struct session *, struct args *, struct mouse_event *); }; #define WINDOW_MODE_TIMEOUT 180 @@ -923,6 +874,7 @@ struct window_pane { void *modedata; struct event modetimer; time_t modelast; + u_int modeprefix; TAILQ_ENTRY(window_pane) entry; RB_ENTRY(window_pane) tree_entry; @@ -1650,8 +1602,7 @@ enum mode_key_cmd mode_key_fromstring(const struct mode_key_cmdstr *, const struct mode_key_table *mode_key_findtable(const char *); void mode_key_init_trees(void); void mode_key_init(struct mode_key_data *, struct mode_key_tree *); -enum mode_key_cmd mode_key_lookup(struct mode_key_data *, key_code, - const char **, u_int *); +enum mode_key_cmd mode_key_lookup(struct mode_key_data *, key_code); /* notify.c */ void notify_enable(void); @@ -1920,6 +1871,7 @@ void server_add_accept(int); /* server-client.c */ void server_client_set_key_table(struct client *, const char *); const char *server_client_get_key_table(struct client *); +int server_client_is_default_key_table(struct client *); int server_client_check_nested(struct client *); void server_client_handle_key(struct client *, key_code); void server_client_create(int); diff --git a/window-choose.c b/window-choose.c index 715915b6..19677c86 100644 --- a/window-choose.c +++ b/window-choose.c @@ -52,10 +52,10 @@ enum window_choose_input_type { }; const struct window_mode window_choose_mode = { - window_choose_init, - window_choose_free, - window_choose_resize, - window_choose_key, + .init = window_choose_init, + .free = window_choose_free, + .resize = window_choose_resize, + .key = window_choose_key, }; struct window_choose_mode_item { @@ -552,7 +552,7 @@ window_choose_key(struct window_pane *wp, __unused struct client *c, items = data->list_size; if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) { - switch (mode_key_lookup(&data->mdata, key, NULL, NULL)) { + switch (mode_key_lookup(&data->mdata, key)) { case MODEKEYCHOICE_CANCEL: data->input_type = WINDOW_CHOOSE_NORMAL; window_choose_redraw_screen(wp); @@ -582,7 +582,7 @@ window_choose_key(struct window_pane *wp, __unused struct client *c, return; } - switch (mode_key_lookup(&data->mdata, key, NULL, NULL)) { + switch (mode_key_lookup(&data->mdata, key)) { case MODEKEYCHOICE_CANCEL: window_choose_fire_callback(wp, NULL); break; @@ -837,7 +837,7 @@ window_choose_key_index(struct window_choose_mode_data *data, u_int idx) int mkey; for (ptr = keys; *ptr != '\0'; ptr++) { - mkey = mode_key_lookup(&data->mdata, *ptr, NULL, NULL); + mkey = mode_key_lookup(&data->mdata, *ptr); if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) continue; if (idx-- == 0) @@ -857,7 +857,7 @@ window_choose_index_key(struct window_choose_mode_data *data, key_code key) u_int idx = 0; for (ptr = keys; *ptr != '\0'; ptr++) { - mkey = mode_key_lookup(&data->mdata, *ptr, NULL, NULL); + mkey = mode_key_lookup(&data->mdata, *ptr); if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) continue; if (key == (key_code)*ptr) diff --git a/window-clock.c b/window-clock.c index a9bbb75a..c80e9af7 100644 --- a/window-clock.c +++ b/window-clock.c @@ -34,10 +34,10 @@ static void window_clock_timer_callback(int, short, void *); static void window_clock_draw_screen(struct window_pane *); const struct window_mode window_clock_mode = { - window_clock_init, - window_clock_free, - window_clock_resize, - window_clock_key, + .init = window_clock_init, + .free = window_clock_free, + .resize = window_clock_resize, + .key = window_clock_key, }; struct window_clock_mode_data { diff --git a/window-copy.c b/window-copy.c index f1379604..d5140fc7 100644 --- a/window-copy.c +++ b/window-copy.c @@ -24,16 +24,15 @@ #include "tmux.h" +const char *window_copy_key_table(struct window_pane *); +void window_copy_command(struct window_pane *, struct client *, + struct session *, struct args *, struct mouse_event *); struct screen *window_copy_init(struct window_pane *); void window_copy_free(struct window_pane *); void window_copy_pagedown(struct window_pane *, int); void window_copy_next_paragraph(struct window_pane *); void window_copy_previous_paragraph(struct window_pane *); void window_copy_resize(struct window_pane *, u_int, u_int); -void window_copy_key(struct window_pane *, struct client *, struct session *, - key_code, struct mouse_event *); -int window_copy_key_input(struct window_pane *, key_code); -int window_copy_key_numeric_prefix(struct window_pane *, key_code); void window_copy_redraw_selection(struct window_pane *, u_int); void window_copy_redraw_lines(struct window_pane *, u_int, u_int); @@ -96,23 +95,21 @@ void window_copy_drag_update(struct client *, struct mouse_event *); void window_copy_drag_release(struct client *, struct mouse_event *); const struct window_mode window_copy_mode = { - window_copy_init, - window_copy_free, - window_copy_resize, - window_copy_key, + .init = window_copy_init, + .free = window_copy_free, + .resize = window_copy_resize, + .key_table = window_copy_key_table, + .command = window_copy_command, }; -enum window_copy_input_type { +enum { WINDOW_COPY_OFF, - WINDOW_COPY_NAMEDBUFFER, - WINDOW_COPY_NUMERICPREFIX, WINDOW_COPY_SEARCHUP, WINDOW_COPY_SEARCHDOWN, WINDOW_COPY_JUMPFORWARD, - WINDOW_COPY_JUMPBACK, + WINDOW_COPY_JUMPBACKWARD, WINDOW_COPY_JUMPTOFORWARD, - WINDOW_COPY_JUMPTOBACK, - WINDOW_COPY_GOTOLINE, + WINDOW_COPY_JUMPTOBACKWARD, }; /* @@ -132,39 +129,30 @@ enum window_copy_input_type { * mode ends). */ struct window_copy_mode_data { - struct screen screen; + struct screen screen; - struct screen *backing; - int backing_written; /* backing display started */ + struct screen *backing; + int backing_written; /* backing display started */ - struct mode_key_data mdata; + u_int oy; - u_int oy; + u_int selx; + u_int sely; - u_int selx; - u_int sely; + int rectflag; /* in rectangle copy mode? */ + int scroll_exit; /* exit on scroll to end? */ - int rectflag; /* in rectangle copy mode? */ - int scroll_exit; /* exit on scroll to end? */ + u_int cx; + u_int cy; - u_int cx; - u_int cy; + u_int lastcx; /* position in last line w/ content */ + u_int lastsx; /* size of last line w/ content */ - u_int lastcx; /* position in last line w/ content */ - u_int lastsx; /* size of last line w/ content */ + int searchtype; + char *searchstr; - enum window_copy_input_type inputtype; - const char *inputprompt; - char *inputstr; - int inputexit; - - int numprefix; - - enum window_copy_input_type searchtype; - char *searchstr; - - enum window_copy_input_type jumptype; - char jumpchar; + int jumptype; + char jumpchar; }; struct screen * @@ -172,7 +160,6 @@ window_copy_init(struct window_pane *wp) { struct window_copy_mode_data *data; struct screen *s; - int keys; wp->modedata = data = xmalloc(sizeof *data); data->oy = 0; @@ -187,11 +174,6 @@ window_copy_init(struct window_pane *wp) data->rectflag = 0; data->scroll_exit = 0; - data->inputtype = WINDOW_COPY_OFF; - data->inputprompt = NULL; - data->inputstr = xstrdup(""); - data->numprefix = -1; - data->searchtype = WINDOW_COPY_OFF; data->searchstr = NULL; @@ -203,13 +185,7 @@ window_copy_init(struct window_pane *wp) s = &data->screen; screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); - - keys = options_get_number(wp->window->options, "mode-keys"); - if (keys == MODEKEY_EMACS) - mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); - else - mode_key_init(&data->mdata, &mode_key_tree_vi_copy); - s->sel.modekeys = keys; + s->sel.modekeys = options_get_number(wp->window->options, "mode-keys"); data->backing = NULL; @@ -261,7 +237,6 @@ window_copy_free(struct window_pane *wp) bufferevent_enable(wp->event, EV_READ|EV_WRITE); free(data->searchstr); - free(data->inputstr); if (data->backing != &wp->base) { screen_free(data->backing); @@ -483,529 +458,337 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy) window_copy_redraw_screen(wp); } +const char * +window_copy_key_table(struct window_pane *wp) +{ + if (options_get_number(wp->window->options, "mode-keys") == MODEKEY_VI) + return ("copy-mode-vi"); + return ("copy-mode"); +} + void -window_copy_key(struct window_pane *wp, struct client *c, struct session *sess, - key_code key, struct mouse_event *m) +window_copy_command(struct window_pane *wp, struct client *c, struct session *s, + struct args *args, struct mouse_event *m) { - const char *word_separators; struct window_copy_mode_data *data = wp->modedata; - struct screen *s = &data->screen; - u_int np; - int keys; - enum mode_key_cmd cmd; - const char *arg, *ss; - - np = 1; - if (data->numprefix > 0) - np = data->numprefix; - - if (data->inputtype == WINDOW_COPY_JUMPFORWARD || - data->inputtype == WINDOW_COPY_JUMPBACK || - data->inputtype == WINDOW_COPY_JUMPTOFORWARD || - data->inputtype == WINDOW_COPY_JUMPTOBACK) { - /* Ignore keys with modifiers. */ - if ((key & KEYC_MASK_MOD) == 0) { - data->jumpchar = key; - if (data->inputtype == WINDOW_COPY_JUMPFORWARD) { - for (; np != 0; np--) - window_copy_cursor_jump(wp); - } - if (data->inputtype == WINDOW_COPY_JUMPBACK) { - for (; np != 0; np--) - window_copy_cursor_jump_back(wp); - } - if (data->inputtype == WINDOW_COPY_JUMPTOFORWARD) { - for (; np != 0; np--) - window_copy_cursor_jump_to(wp, 0); - } - if (data->inputtype == WINDOW_COPY_JUMPTOBACK) { - for (; np != 0; np--) - window_copy_cursor_jump_to_back(wp, 0); - } - } - data->jumptype = data->inputtype; - data->inputtype = WINDOW_COPY_OFF; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; - } else if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { - if (window_copy_key_numeric_prefix(wp, key) == 0) - return; - data->inputtype = WINDOW_COPY_OFF; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - } else if (data->inputtype != WINDOW_COPY_OFF) { - if (window_copy_key_input(wp, key) != 0) - goto input_off; + struct screen *sn = &data->screen; + const char *command, *argument, *ws, *ss; + u_int np = wp->modeprefix; + + if (args->argc == 0) return; - } + command = args->argv[0]; - cmd = mode_key_lookup(&data->mdata, key, &arg, &np); - if (data->numprefix > 0) - np = data->numprefix; - if (cmd != MODEKEYCOPY_PREVIOUSPAGE && - cmd != MODEKEYCOPY_NEXTPAGE && - cmd != MODEKEYCOPY_SCROLLUP && - cmd != MODEKEYCOPY_SCROLLDOWN && - cmd != MODEKEYCOPY_HALFPAGEUP && - cmd != MODEKEYCOPY_HALFPAGEDOWN) - data->scroll_exit = 0; - switch (cmd) { - case MODEKEYCOPY_APPENDSELECTION: - if (sess != NULL) { - window_copy_append_selection(wp, NULL); - if (arg == NULL) { - window_pane_reset_mode(wp); - return; - } + if (args->argc == 1) { + if (strcmp(command, "append-selection") == 0) { + if (s != NULL) + window_copy_append_selection(wp, NULL); window_copy_clear_selection(wp); window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_CANCEL: - window_pane_reset_mode(wp); - return; - case MODEKEYCOPY_OTHEREND: - if (np % 2) - window_copy_other_end(wp); - break; - case MODEKEYCOPY_LEFT: - for (; np != 0; np--) - window_copy_cursor_left(wp); - break; - case MODEKEYCOPY_RIGHT: - for (; np != 0; np--) - window_copy_cursor_right(wp); - break; - case MODEKEYCOPY_UP: - for (; np != 0; np--) - window_copy_cursor_up(wp, 0); - break; - case MODEKEYCOPY_DOWN: - for (; np != 0; np--) - window_copy_cursor_down(wp, 0); - break; - case MODEKEYCOPY_SCROLLUP: - for (; np != 0; np--) - window_copy_cursor_up(wp, 1); - break; - case MODEKEYCOPY_SCROLLDOWN: - for (; np != 0; np--) - window_copy_cursor_down(wp, 1); - if (data->scroll_exit && data->oy == 0) { + if (strcmp(command, "append-selection-and-cancel") == 0) { + if (s != NULL) + window_copy_append_selection(wp, NULL); + window_copy_clear_selection(wp); + window_copy_redraw_screen(wp); window_pane_reset_mode(wp); - return; } - break; - case MODEKEYCOPY_PREVIOUSPAGE: - for (; np != 0; np--) - window_copy_pageup(wp, 0); - break; - case MODEKEYCOPY_NEXTPAGE: - for (; np != 0; np--) - window_copy_pagedown(wp, 0); - break; - case MODEKEYCOPY_PREVIOUSPARAGRAPH: - for (; np != 0; np--) - window_copy_previous_paragraph(wp); - break; - case MODEKEYCOPY_NEXTPARAGRAPH: - for (; np != 0; np--) - window_copy_next_paragraph(wp); - break; - case MODEKEYCOPY_HALFPAGEUP: - for (; np != 0; np--) - window_copy_pageup(wp, 1); - break; - case MODEKEYCOPY_HALFPAGEDOWN: - for (; np != 0; np--) - window_copy_pagedown(wp, 1); - break; - case MODEKEYCOPY_TOPLINE: - data->cx = 0; - data->cy = 0; - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_MIDDLELINE: - data->cx = 0; - data->cy = (screen_size_y(s) - 1) / 2; - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_BOTTOMLINE: - data->cx = 0; - data->cy = screen_size_y(s) - 1; - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_HISTORYTOP: - data->cx = 0; - data->cy = 0; - data->oy = screen_hsize(data->backing); - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_HISTORYBOTTOM: - data->cx = 0; - data->cy = screen_size_y(s) - 1; - data->oy = 0; - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_STARTSELECTION: - if (KEYC_IS_MOUSE(key)) { - if (c != NULL) + if (strcmp(command, "back-to-indentation") == 0) + window_copy_cursor_back_to_indentation(wp); + if (strcmp(command, "begin-selection") == 0) { + if (m != NULL) window_copy_start_drag(c, m); - } else { - s->sel.lineflag = LINE_SEL_NONE; - window_copy_start_selection(wp); + else { + sn->sel.lineflag = LINE_SEL_NONE; + window_copy_start_selection(wp); + window_copy_redraw_screen(wp); + } + } + if (strcmp(command, "bottom-line") == 0) { + data->cx = 0; + data->cy = screen_size_y(sn) - 1; + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_SELECTLINE: - s->sel.lineflag = LINE_SEL_LEFT_RIGHT; - data->rectflag = 0; - /* FALLTHROUGH */ - case MODEKEYCOPY_COPYLINE: - window_copy_cursor_start_of_line(wp); - /* FALLTHROUGH */ - case MODEKEYCOPY_COPYENDOFLINE: - window_copy_start_selection(wp); - for (; np > 1; np--) - window_copy_cursor_down(wp, 0); - window_copy_cursor_end_of_line(wp); - window_copy_redraw_screen(wp); - - /* If a copy command then copy the selection and exit. */ - if (sess != NULL && - (cmd == MODEKEYCOPY_COPYLINE || - cmd == MODEKEYCOPY_COPYENDOFLINE)) { - window_copy_copy_selection(wp, NULL); + if (strcmp(command, "cancel") == 0) window_pane_reset_mode(wp); - return; + if (strcmp(command, "clear-selection") == 0) { + window_copy_clear_selection(wp); + window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_CLEARSELECTION: - window_copy_clear_selection(wp); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_COPYPIPE: - if (sess != NULL) { - window_copy_copy_pipe(wp, sess, NULL, arg); - window_pane_reset_mode(wp); - return; + if (strcmp(command, "copy-end-of-line") == 0) { + window_copy_start_selection(wp); + for (; np > 1; np--) + window_copy_cursor_down(wp, 0); + window_copy_cursor_end_of_line(wp); + window_copy_redraw_screen(wp); + + if (s != NULL) { + window_copy_copy_selection(wp, NULL); + window_pane_reset_mode(wp); + } } - break; - case MODEKEYCOPY_COPYSELECTION: - if (sess != NULL) { - window_copy_copy_selection(wp, NULL); - if (arg == NULL) { + if (strcmp(command, "copy-line") == 0) { + window_copy_cursor_start_of_line(wp); + window_copy_start_selection(wp); + for (; np > 1; np--) + window_copy_cursor_down(wp, 0); + window_copy_cursor_end_of_line(wp); + window_copy_redraw_screen(wp); + + if (s != NULL) { + window_copy_copy_selection(wp, NULL); window_pane_reset_mode(wp); - return; } + } + if (strcmp(command, "copy-selection") == 0) { + if (s != NULL) + window_copy_copy_selection(wp, NULL); window_copy_clear_selection(wp); window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_STARTOFLINE: - window_copy_cursor_start_of_line(wp); - break; - case MODEKEYCOPY_BACKTOINDENTATION: - window_copy_cursor_back_to_indentation(wp); - break; - case MODEKEYCOPY_ENDOFLINE: - window_copy_cursor_end_of_line(wp); - break; - case MODEKEYCOPY_NEXTSPACE: - for (; np != 0; np--) - window_copy_cursor_next_word(wp, " "); - break; - case MODEKEYCOPY_NEXTSPACEEND: - for (; np != 0; np--) - window_copy_cursor_next_word_end(wp, " "); - break; - case MODEKEYCOPY_NEXTWORD: - word_separators = - options_get_string(sess->options, "word-separators"); - for (; np != 0; np--) - window_copy_cursor_next_word(wp, word_separators); - break; - case MODEKEYCOPY_NEXTWORDEND: - word_separators = - options_get_string(sess->options, "word-separators"); - for (; np != 0; np--) - window_copy_cursor_next_word_end(wp, word_separators); - break; - case MODEKEYCOPY_PREVIOUSSPACE: - for (; np != 0; np--) - window_copy_cursor_previous_word(wp, " "); - break; - case MODEKEYCOPY_PREVIOUSWORD: - word_separators = - options_get_string(sess->options, "word-separators"); - for (; np != 0; np--) - window_copy_cursor_previous_word(wp, word_separators); - break; - case MODEKEYCOPY_JUMP: - data->inputtype = WINDOW_COPY_JUMPFORWARD; - data->inputprompt = "Jump Forward"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_JUMPAGAIN: - if (data->jumptype == WINDOW_COPY_JUMPFORWARD) { + if (strcmp(command, "copy-selection-and-cancel") == 0) { + if (s != NULL) + window_copy_copy_selection(wp, NULL); + window_copy_clear_selection(wp); + window_copy_redraw_screen(wp); + window_pane_reset_mode(wp); + } + if (strcmp(command, "cursor-down") == 0) { for (; np != 0; np--) - window_copy_cursor_jump(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPBACK) { + window_copy_cursor_down(wp, 0); + } + if (strcmp(command, "cursor-left") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_back(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { + window_copy_cursor_left(wp); + } + if (strcmp(command, "cursor-right") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to(wp, 1); - } else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { + window_copy_cursor_right(wp); + } + if (strcmp(command, "cursor-up") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to_back(wp, 1); + window_copy_cursor_up(wp, 0); } - break; - case MODEKEYCOPY_JUMPREVERSE: - if (data->jumptype == WINDOW_COPY_JUMPFORWARD) { + if (strcmp(command, "end-of-line") == 0) + window_copy_cursor_end_of_line(wp); + if (strcmp(command, "halfpage-down") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_back(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPBACK) { + window_copy_pagedown(wp, 1); + } + if (strcmp(command, "halfpage-up") == 0) { for (; np != 0; np--) - window_copy_cursor_jump(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { + window_copy_pageup(wp, 1); + } + if (strcmp(command, "history-bottom") == 0) { + data->cx = 0; + data->cy = screen_size_y(sn) - 1; + data->oy = 0; + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); + } + if (strcmp(command, "history-top") == 0) { + data->cx = 0; + data->cy = 0; + data->oy = screen_hsize(data->backing); + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); + } + if (strcmp(command, "jump-again") == 0) { + switch (data->jumptype) { + case WINDOW_COPY_JUMPFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump(wp); + break; + case WINDOW_COPY_JUMPBACKWARD: + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + break; + case WINDOW_COPY_JUMPTOFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump_to(wp, 1); + break; + case WINDOW_COPY_JUMPTOBACKWARD: + for (; np != 0; np--) + window_copy_cursor_jump_to_back(wp, 1); + break; + } + } + if (strcmp(command, "jump-reverse") == 0) { + switch (data->jumptype) { + case WINDOW_COPY_JUMPFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + break; + case WINDOW_COPY_JUMPBACKWARD: + for (; np != 0; np--) + window_copy_cursor_jump(wp); + break; + case WINDOW_COPY_JUMPTOFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump_to_back(wp, 1); + break; + case WINDOW_COPY_JUMPTOBACKWARD: + for (; np != 0; np--) + window_copy_cursor_jump_to(wp, 1); + break; + } + } + if (strcmp(command, "middle-line") == 0) { + data->cx = 0; + data->cy = (screen_size_y(sn) - 1) / 2; + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); + } + if (strcmp(command, "next-paragraph") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to_back(wp, 1); - } else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { + window_copy_next_paragraph(wp); + } + if (strcmp(command, "next-space") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to(wp, 1); + window_copy_cursor_next_word(wp, " "); } - break; - case MODEKEYCOPY_JUMPBACK: - data->inputtype = WINDOW_COPY_JUMPBACK; - data->inputprompt = "Jump Back"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_JUMPTO: - data->inputtype = WINDOW_COPY_JUMPTOFORWARD; - data->inputprompt = "Jump To"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_JUMPTOBACK: - data->inputtype = WINDOW_COPY_JUMPTOBACK; - data->inputprompt = "Jump To Back"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_SEARCHUP: - data->inputtype = WINDOW_COPY_SEARCHUP; - data->inputprompt = "Search Up"; - goto input_on; - case MODEKEYCOPY_SEARCHDOWN: - data->inputtype = WINDOW_COPY_SEARCHDOWN; - data->inputprompt = "Search Down"; - goto input_on; - case MODEKEYCOPY_SEARCHAGAIN: - case MODEKEYCOPY_SEARCHREVERSE: - switch (data->searchtype) { - case WINDOW_COPY_OFF: - case WINDOW_COPY_GOTOLINE: - case WINDOW_COPY_JUMPFORWARD: - case WINDOW_COPY_JUMPBACK: - case WINDOW_COPY_JUMPTOFORWARD: - case WINDOW_COPY_JUMPTOBACK: - case WINDOW_COPY_NAMEDBUFFER: - case WINDOW_COPY_NUMERICPREFIX: - break; - case WINDOW_COPY_SEARCHUP: + if (strcmp(command, "next-space-end") == 0) { + for (; np != 0; np--) + window_copy_cursor_next_word_end(wp, " "); + } + if (strcmp(command, "next-word") == 0) { + ws = options_get_string(s->options, "word-separators"); + for (; np != 0; np--) + window_copy_cursor_next_word(wp, ws); + } + if (strcmp(command, "next-word-end") == 0) { + ws = options_get_string(s->options, "word-separators"); + for (; np != 0; np--) + window_copy_cursor_next_word_end(wp, ws); + } + if (strcmp(command, "other-end") == 0) { + if ((np % 2) != 0) + window_copy_other_end(wp); + } + if (strcmp(command, "page-down") == 0) { + for (; np != 0; np--) + window_copy_pagedown(wp, 0); + } + if (strcmp(command, "page-up") == 0) { + for (; np != 0; np--) + window_copy_pageup(wp, 0); + } + if (strcmp(command, "previous-paragraph") == 0) { + for (; np != 0; np--) + window_copy_previous_paragraph(wp); + } + if (strcmp(command, "previous-space") == 0) { + for (; np != 0; np--) + window_copy_cursor_previous_word(wp, " "); + } + if (strcmp(command, "previous-word") == 0) { + ws = options_get_string(s->options, "word-separators"); + for (; np != 0; np--) + window_copy_cursor_previous_word(wp, ws); + } + if (strcmp(command, "rectangle-toggle") == 0) { + sn->sel.lineflag = LINE_SEL_NONE; + window_copy_rectangle_toggle(wp); + } + if (strcmp(command, "scroll-down") == 0) { + for (; np != 0; np--) + window_copy_cursor_down(wp, 1); + if (data->scroll_exit && data->oy == 0) + window_pane_reset_mode(wp); + } + if (strcmp(command, "scroll-up") == 0) { + for (; np != 0; np--) + window_copy_cursor_up(wp, 1); + } + if (strcmp(command, "search-again") == 0) { ss = data->searchstr; - if (cmd == MODEKEYCOPY_SEARCHAGAIN) { + if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) window_copy_search_up(wp, ss, 1); - } else { + } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) window_copy_search_down(wp, ss, 1); } - break; - case WINDOW_COPY_SEARCHDOWN: + } + if (strcmp(command, "search-reverse") == 0) { ss = data->searchstr; - if (cmd == MODEKEYCOPY_SEARCHAGAIN) { + if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) window_copy_search_down(wp, ss, 1); - } else { + } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) window_copy_search_up(wp, ss, 1); } - break; } - break; - case MODEKEYCOPY_GOTOLINE: - data->inputtype = WINDOW_COPY_GOTOLINE; - data->inputprompt = "Goto Line"; - *data->inputstr = '\0'; - goto input_on; - case MODEKEYCOPY_STARTNAMEDBUFFER: - data->inputtype = WINDOW_COPY_NAMEDBUFFER; - data->inputexit = (arg == NULL); - data->inputprompt = "Buffer"; - *data->inputstr = '\0'; - goto input_on; - case MODEKEYCOPY_STARTNUMBERPREFIX: - key &= KEYC_MASK_KEY; - if (key >= '0' && key <= '9') { - data->inputtype = WINDOW_COPY_NUMERICPREFIX; - data->numprefix = 0; - window_copy_key_numeric_prefix(wp, key); - return; + if (strcmp(command, "select-line") == 0) { + sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; + data->rectflag = 0; + window_copy_cursor_start_of_line(wp); + window_copy_start_selection(wp); + for (; np > 1; np--) + window_copy_cursor_down(wp, 0); + window_copy_cursor_end_of_line(wp); + window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_RECTANGLETOGGLE: - s->sel.lineflag = LINE_SEL_NONE; - window_copy_rectangle_toggle(wp); - break; - default: - break; - } - - data->numprefix = -1; - return; - -input_on: - keys = options_get_number(wp->window->options, "mode-keys"); - if (keys == MODEKEY_EMACS) - mode_key_init(&data->mdata, &mode_key_tree_emacs_edit); - else - mode_key_init(&data->mdata, &mode_key_tree_vi_edit); - - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; - -input_off: - keys = options_get_number(wp->window->options, "mode-keys"); - if (keys == MODEKEY_EMACS) - mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); - else - mode_key_init(&data->mdata, &mode_key_tree_vi_copy); - - data->inputtype = WINDOW_COPY_OFF; - data->inputprompt = NULL; - - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); -} - -int -window_copy_key_input(struct window_pane *wp, key_code key) -{ - struct window_copy_mode_data *data = wp->modedata; - struct screen *s = &data->screen; - const char *bufdata; - size_t inputlen, n, bufsize; - u_int np; - struct paste_buffer *pb; - u_char ch; - - switch (mode_key_lookup(&data->mdata, key, NULL, &np)) { - case MODEKEYEDIT_CANCEL: - data->numprefix = -1; - return (-1); - case MODEKEYEDIT_BACKSPACE: - inputlen = strlen(data->inputstr); - if (inputlen > 0) - data->inputstr[inputlen - 1] = '\0'; - break; - case MODEKEYEDIT_DELETELINE: - *data->inputstr = '\0'; - break; - case MODEKEYEDIT_PASTE: - if ((pb = paste_get_top(NULL)) == NULL) - break; - bufdata = paste_buffer_data(pb, &bufsize); - for (n = 0; n < bufsize; n++) { - ch = (u_char)bufdata[n]; - if (ch < 32 || ch == 127) - break; + if (strcmp(command, "start-of-line") == 0) { + window_copy_cursor_start_of_line(wp); } - inputlen = strlen(data->inputstr); - - data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); - memcpy(data->inputstr + inputlen, bufdata, n); - data->inputstr[inputlen + n] = '\0'; - break; - case MODEKEYEDIT_ENTER: - if (data->numprefix > 0) - np = data->numprefix; - switch (data->inputtype) { - case WINDOW_COPY_OFF: - case WINDOW_COPY_JUMPFORWARD: - case WINDOW_COPY_JUMPBACK: - case WINDOW_COPY_JUMPTOFORWARD: - case WINDOW_COPY_JUMPTOBACK: - case WINDOW_COPY_NUMERICPREFIX: - break; - case WINDOW_COPY_SEARCHUP: - data->searchtype = data->inputtype; - data->searchstr = xstrdup(data->inputstr); - for (; np != 0; np--) - window_copy_search_up(wp, data->inputstr, 1); - break; - case WINDOW_COPY_SEARCHDOWN: - data->searchtype = data->inputtype; - data->searchstr = xstrdup(data->inputstr); - for (; np != 0; np--) - window_copy_search_down(wp, data->inputstr, 1); - break; - case WINDOW_COPY_NAMEDBUFFER: - window_copy_copy_selection(wp, data->inputstr); - *data->inputstr = '\0'; - if (data->inputexit) { + if (strcmp(command, "top-line") == 0) { + data->cx = 0; + data->cy = 0; + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); + } + } else if (args->argc == 2 && *args->argv[1] != '\0') { + argument = args->argv[1]; + if (strcmp(command, "copy-pipe") == 0) { + if (s != NULL) { + window_copy_copy_pipe(wp, s, NULL, argument); window_pane_reset_mode(wp); - return (0); } - window_copy_clear_selection(wp); - window_copy_redraw_screen(wp); - break; - case WINDOW_COPY_GOTOLINE: - window_copy_goto_line(wp, data->inputstr); - *data->inputstr = '\0'; - break; } - data->numprefix = -1; - return (1); - case MODEKEY_OTHER: - if (key < 32 || key > 126) - break; - inputlen = strlen(data->inputstr) + 2; - - data->inputstr = xrealloc(data->inputstr, inputlen); - data->inputstr[inputlen - 2] = key; - data->inputstr[inputlen - 1] = '\0'; - break; - default: - break; + if (strcmp(command, "goto-line") == 0) + window_copy_goto_line(wp, argument); + if (strcmp(command, "jump-backward") == 0) { + data->jumptype = WINDOW_COPY_JUMPBACKWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + } + if (strcmp(command, "jump-forward") == 0) { + data->jumptype = WINDOW_COPY_JUMPFORWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + window_copy_cursor_jump(wp); + } + if (strcmp(command, "jump-to-backward") == 0) { + data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + window_copy_cursor_jump_to_back(wp, 1); + } + if (strcmp(command, "jump-to-forward") == 0) { + data->jumptype = WINDOW_COPY_JUMPTOFORWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + window_copy_cursor_jump_to(wp, 1); + } + if (strcmp(command, "search-backward") == 0) { + data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchstr = xstrdup(argument); + for (; np != 0; np--) + window_copy_search_up(wp, data->searchstr, 1); + } + if (strcmp(command, "search-forward") == 0) { + data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchstr = xstrdup(argument); + for (; np != 0; np--) + window_copy_search_down(wp, data->searchstr, 1); + } } - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return (0); -} - -int -window_copy_key_numeric_prefix(struct window_pane *wp, key_code key) -{ - struct window_copy_mode_data *data = wp->modedata; - struct screen *s = &data->screen; - - key &= KEYC_MASK_KEY; - if (key < '0' || key > '9') - return (1); - - if (data->numprefix >= 100) /* no more than three digits */ - return (0); - data->numprefix = data->numprefix * 10 + key - '0'; - - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return (0); + wp->modeprefix = 1; } void @@ -1268,7 +1051,7 @@ window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx, struct options *oo = wp->window->options; struct grid_cell gc; char hdr[512]; - size_t last, xoff = 0, size = 0, limit; + size_t last, xoff = 0, size = 0; style_apply(&gc, oo, "mode-style"); @@ -1280,20 +1063,6 @@ window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx, size = screen_size_x(s); screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_puts(ctx, &gc, "%s", hdr); - } else if (py == last && data->inputtype != WINDOW_COPY_OFF) { - limit = sizeof hdr; - if (limit > screen_size_x(s) + 1) - limit = screen_size_x(s) + 1; - if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { - xoff = size = xsnprintf(hdr, limit, - "Repeat: %d", data->numprefix); - } else { - /* We don't care about truncation. */ - xoff = size = snprintf(hdr, limit, - "%s: %s", data->inputprompt, data->inputstr); - } - screen_write_cursormove(ctx, 0, last); - screen_write_puts(ctx, &gc, "%s", hdr); } else size = 0; @@ -2342,6 +2111,9 @@ window_copy_start_drag(struct client *c, struct mouse_event *m) struct window_pane *wp; u_int x, y; + if (c == NULL) + return; + wp = cmd_mouse_pane(m, NULL, NULL); if (wp == NULL || wp->mode != &window_copy_mode) return; @@ -2350,7 +2122,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m) return; c->tty.mouse_drag_update = window_copy_drag_update; - c->tty.mouse_drag_release = NULL; /* will fire MouseUp key */ + c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */ window_copy_update_cursor(wp, x, y); window_copy_start_selection(wp); @@ -1124,6 +1124,7 @@ window_pane_reset_mode(struct window_pane *wp) wp->mode->free(wp); wp->mode = NULL; + wp->modeprefix = 1; wp->screen = &wp->base; wp->flags |= (PANE_REDRAW|PANE_CHANGED); |