Skip to content

Commit

Permalink
Fundamental change to how copy mode key bindings work:
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nicm committed Oct 11, 2016
1 parent 8b804fb commit 76d6d36
Show file tree
Hide file tree
Showing 14 changed files with 806 additions and 1,190 deletions.
51 changes: 6 additions & 45 deletions cmd-bind-key.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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);
}
10 changes: 7 additions & 3 deletions cmd-command-prompt.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
24 changes: 4 additions & 20 deletions cmd-list-keys.c
Expand Up @@ -138,16 +138,15 @@ 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) {
cmdq_error(cmdq, "unknown key table: %s", tablename);
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);
Expand All @@ -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) {
Expand All @@ -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);
}
}

Expand Down
36 changes: 34 additions & 2 deletions cmd-send-keys.c
Expand Up @@ -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,

Expand All @@ -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);
Expand Down
136 changes: 136 additions & 0 deletions key-bindings.c
Expand Up @@ -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;
Expand Down

2 comments on commit 76d6d36

@dafyddcrosby
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any plans on adding this to the CHANGES file? It's a fairly big change.

@ThomasAdam
Copy link
Contributor

@ThomasAdam ThomasAdam commented on 76d6d36 Nov 28, 2016 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.