Drop the edit mode key tables and just use fixed key bindings for the

command prompt.
pull/581/head
nicm 2016-10-12 14:50:14 +00:00
parent 4160df4ca4
commit c484c5a2a1
7 changed files with 292 additions and 409 deletions

View File

@ -120,11 +120,9 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
}
mtmp.key = key;
mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
mbind->cmd = cmd;

View File

@ -135,10 +135,10 @@ static enum cmd_retval
cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
const char *tablename, *key, *cmdstr, *mode;
const char *tablename, *cmdstr;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
int width, keywidth, any_mode;
int width, keywidth;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
@ -147,30 +147,18 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
}
keywidth = 0;
any_mode = 0;
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (mbind->mode != 0)
any_mode = 1;
width = strlen(key);
width = strlen(key_string_lookup_key(mbind->key));
if (width > keywidth)
keywidth = width;
}
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
mode = "";
if (mbind->mode != 0)
mode = "c";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL) {
cmdq_print(cmdq, "bind-key -%st %s%s %*s %s",
mode, any_mode && *mode == '\0' ? " " : "",
mtab->name,
(int)keywidth, key, cmdstr);
cmdq_print(cmdq, "bind-key -t %s %*s %s",
mtab->name, (int)keywidth,
key_string_lookup_key(mbind->key), cmdstr);
}
}

View File

@ -34,8 +34,8 @@ const struct cmd_entry cmd_unbind_key_entry = {
.name = "unbind-key",
.alias = "unbind",
.args = { "acnt:T:", 0, 1 },
.usage = "[-acn] [-t mode-table] [-T key-table] key",
.args = { "ant:T:", 0, 1 },
.usage = "[-an] [-t mode-table] [-T key-table] key",
.flags = 0,
.exec = cmd_unbind_key_exec
@ -122,7 +122,6 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
}
mtmp.key = key;
mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
RB_REMOVE(mode_key_tree, mtab->tree, mbind);
free(mbind);

View File

@ -47,52 +47,9 @@ struct mode_key_cmdstr {
/* Entry in the default mode key tables. */
struct mode_key_entry {
key_code key;
/*
* Editing mode for vi: 0 is edit mode, keys not in the table are
* returned as MODEKEY_OTHER; 1 is command mode, keys not in the table
* are returned as MODEKEY_NONE. This is also matched on, allowing some
* keys to be bound in edit mode.
*/
int mode;
enum mode_key_cmd cmd;
};
/* Edit keys command strings. */
static const struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
{ MODEKEYEDIT_BACKSPACE, "backspace" },
{ MODEKEYEDIT_CANCEL, "cancel" },
{ MODEKEYEDIT_COMPLETE, "complete" },
{ MODEKEYEDIT_CURSORLEFT, "cursor-left" },
{ MODEKEYEDIT_CURSORRIGHT, "cursor-right" },
{ MODEKEYEDIT_DELETE, "delete" },
{ MODEKEYEDIT_DELETELINE, "delete-line" },
{ MODEKEYEDIT_DELETETOENDOFLINE, "delete-end-of-line" },
{ MODEKEYEDIT_DELETEWORD, "delete-word" },
{ MODEKEYEDIT_ENDOFLINE, "end-of-line" },
{ MODEKEYEDIT_ENTER, "enter" },
{ MODEKEYEDIT_HISTORYDOWN, "history-down" },
{ MODEKEYEDIT_HISTORYUP, "history-up" },
{ MODEKEYEDIT_NEXTSPACE, "next-space" },
{ MODEKEYEDIT_NEXTSPACEEND, "next-space-end" },
{ MODEKEYEDIT_NEXTWORD, "next-word" },
{ MODEKEYEDIT_NEXTWORDEND, "next-word-end" },
{ MODEKEYEDIT_PASTE, "paste" },
{ MODEKEYEDIT_PREVIOUSSPACE, "previous-space" },
{ MODEKEYEDIT_PREVIOUSWORD, "previous-word" },
{ MODEKEYEDIT_STARTOFLINE, "start-of-line" },
{ MODEKEYEDIT_SWITCHMODE, "switch-mode" },
{ MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" },
{ MODEKEYEDIT_SWITCHMODEAPPENDLINE, "switch-mode-append-line" },
{ MODEKEYEDIT_SWITCHMODEBEGINLINE, "switch-mode-begin-line" },
{ MODEKEYEDIT_SWITCHMODECHANGELINE, "switch-mode-change-line" },
{ MODEKEYEDIT_SWITCHMODESUBSTITUTE, "switch-mode-substitute" },
{ MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, "switch-mode-substitute-line" },
{ MODEKEYEDIT_TRANSPOSECHARS, "transpose-chars" },
{ 0, NULL }
};
/* Choice keys command strings. */
static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ MODEKEYCHOICE_BACKSPACE, "backspace" },
@ -118,205 +75,106 @@ static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ 0, NULL }
};
/* vi editing keys. */
static const struct mode_key_entry mode_key_vi_edit[] = {
{ '\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' | 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' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '\002' /* C-b */, MODEKEYCHOICE_PAGEUP },
{ '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
{ '\005' /* C-e */, MODEKEYCHOICE_SCROLLDOWN },
{ '\006' /* C-f */, MODEKEYCHOICE_PAGEDOWN },
{ '\031' /* C-y */, MODEKEYCHOICE_SCROLLUP },
{ '\n', MODEKEYCHOICE_CHOOSE },
{ '\r', MODEKEYCHOICE_CHOOSE },
{ 'j', MODEKEYCHOICE_DOWN },
{ 'k', MODEKEYCHOICE_UP },
{ 'q', MODEKEYCHOICE_CANCEL },
{ KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
{ 'g', MODEKEYCHOICE_STARTOFLIST },
{ 'H', MODEKEYCHOICE_TOPLINE },
{ 'L', MODEKEYCHOICE_BOTTOMLINE },
{ 'G', MODEKEYCHOICE_ENDOFLIST },
{ KEYC_END, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
{ KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
{ KEYC_DOWN, MODEKEYCHOICE_DOWN },
{ KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
{ KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
{ KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
{ KEYC_UP, MODEKEYCHOICE_UP },
{ ' ', MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
{ KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
{ KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
{ KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
{ KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
{ KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
{ KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
{ 0, -1, 0 }
{ KEYC_NONE, -1 }
};
struct mode_key_tree mode_key_tree_vi_choice;
/* emacs editing keys. */
static const struct mode_key_entry mode_key_emacs_edit[] = {
{ '\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' | 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' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
{ '\016' /* C-n */, MODEKEYCHOICE_DOWN },
{ '\020' /* C-p */, MODEKEYCHOICE_UP },
{ '\026' /* C-v */, MODEKEYCHOICE_PAGEDOWN },
{ '\033' /* Escape */, MODEKEYCHOICE_CANCEL },
{ '\n', MODEKEYCHOICE_CHOOSE },
{ '\r', MODEKEYCHOICE_CHOOSE },
{ 'q', MODEKEYCHOICE_CANCEL },
{ 'v' | KEYC_ESCAPE, MODEKEYCHOICE_PAGEUP },
{ KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
{ '<' | KEYC_ESCAPE, MODEKEYCHOICE_STARTOFLIST },
{ 'R' | KEYC_ESCAPE, MODEKEYCHOICE_TOPLINE },
{ '>' | KEYC_ESCAPE, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_END, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
{ KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
{ KEYC_DOWN, MODEKEYCHOICE_DOWN },
{ KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
{ KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
{ KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
{ KEYC_UP, MODEKEYCHOICE_UP },
{ ' ', MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
{ KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
{ KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
{ KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
{ KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
{ KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
{ KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
{ 0, -1, 0 }
{ KEYC_NONE, -1 }
};
struct mode_key_tree mode_key_tree_emacs_choice;
/* Table mapping key table names to default settings and trees. */
static 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 },
{ "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 },
@ -328,10 +186,6 @@ RB_GENERATE(mode_key_tree, mode_key_binding, entry, mode_key_cmp);
int
mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2)
{
if (mbind1->mode < mbind2->mode)
return (-1);
if (mbind1->mode > mbind2->mode)
return (1);
if (mbind1->key < mbind2->key)
return (-1);
if (mbind1->key > mbind2->key)
@ -380,10 +234,9 @@ mode_key_init_trees(void)
for (mtab = mode_key_tables; mtab->name != NULL; mtab++) {
RB_INIT(mtab->tree);
for (ment = mtab->table; ment->mode != -1; ment++) {
for (ment = mtab->table; ment->key != KEYC_NONE; ment++) {
mbind = xmalloc(sizeof *mbind);
mbind->key = ment->key;
mbind->mode = ment->mode;
mbind->cmd = ment->cmd;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
@ -394,7 +247,6 @@ void
mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
{
mdata->tree = mtree;
mdata->mode = 0;
}
enum mode_key_cmd
@ -403,24 +255,7 @@ mode_key_lookup(struct mode_key_data *mdata, key_code key)
struct mode_key_binding *mbind, mtmp;
mtmp.key = key;
mtmp.mode = mdata->mode;
if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL) {
if (mdata->mode != 0)
return (MODEKEY_NONE);
if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL)
return (MODEKEY_OTHER);
}
switch (mbind->cmd) {
case MODEKEYEDIT_SWITCHMODE:
case MODEKEYEDIT_SWITCHMODEAPPEND:
case MODEKEYEDIT_SWITCHMODEAPPENDLINE:
case MODEKEYEDIT_SWITCHMODEBEGINLINE:
case MODEKEYEDIT_SWITCHMODECHANGELINE:
case MODEKEYEDIT_SWITCHMODESUBSTITUTE:
case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
mdata->mode = 1 - mdata->mode;
/* FALLTHROUGH */
default:
return (mbind->cmd);
}
return (mbind->cmd);
}

247
status.c
View File

@ -660,7 +660,6 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
void *data, int flags)
{
struct format_tree *ft;
int keys;
time_t t;
char *tmp;
@ -685,12 +684,7 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
c->prompt_hindex = 0;
c->prompt_flags = flags;
keys = options_get_number(c->session->options, "status-keys");
if (keys == MODEKEY_EMACS)
mode_key_init(&c->prompt_mdata, &mode_key_tree_emacs_edit);
else
mode_key_init(&c->prompt_mdata, &mode_key_tree_vi_edit);
c->prompt_mode = PROMPT_ENTRY;
c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE);
c->flags |= CLIENT_STATUS;
@ -765,7 +759,7 @@ status_prompt_redraw(struct client *c)
memcpy(&old_status, &c->status, sizeof old_status);
screen_init(&c->status, c->tty.sx, 1, 0);
if (c->prompt_mdata.mode == 1)
if (c->prompt_mode == PROMPT_COMMAND)
style_apply(&gc, s->options, "message-command-style");
else
style_apply(&gc, s->options, "message-style");
@ -854,6 +848,127 @@ status_prompt_space(const struct utf8_data *ud)
return (*ud->data == ' ');
}
/*
* Translate key from emacs to vi. Return 0 to drop key, 1 to process the key
* as an emacs key; return 2 to append to the buffer.
*/
static int
status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
{
if (c->prompt_mode == PROMPT_ENTRY) {
switch (key) {
case '\003': /* C-c */
case '\010': /* C-h */
case '\011': /* Tab */
case '\025': /* C-u */
case '\027': /* C-w */
case '\n':
case '\r':
case KEYC_BSPACE:
case KEYC_DC:
case KEYC_DOWN:
case KEYC_END:
case KEYC_HOME:
case KEYC_LEFT:
case KEYC_RIGHT:
case KEYC_UP:
*new_key = key;
return (1);
case '\033': /* Escape */
c->prompt_mode = PROMPT_COMMAND;
c->flags |= CLIENT_STATUS;
return (0);
}
*new_key = key;
return (2);
}
switch (key) {
case 'A':
case 'I':
case 'C':
case 's':
case 'a':
c->prompt_mode = PROMPT_ENTRY;
c->flags |= CLIENT_STATUS;
break; /* switch mode and... */
case 'S':
c->prompt_mode = PROMPT_ENTRY;
c->flags |= CLIENT_STATUS;
*new_key = '\025'; /* C-u */
return (1);
case 'i':
case '\033': /* Escape */
c->prompt_mode = PROMPT_ENTRY;
c->flags |= CLIENT_STATUS;
return (0);
}
switch (key) {
case 'A':
case '$':
*new_key = KEYC_END;
return (1);
case 'I':
case '0':
case '^':
*new_key = KEYC_HOME;
return (1);
case 'C':
case 'D':
*new_key = '\013'; /* C-k */
return (1);
case KEYC_BSPACE:
case 'X':
*new_key = KEYC_BSPACE;
return (1);
case 'b':
case 'B':
*new_key = 'b'|KEYC_ESCAPE;
return (1);
case 'd':
*new_key = '\025';
return (1);
case 'e':
case 'E':
case 'w':
case 'W':
*new_key = 'f'|KEYC_ESCAPE;
return (1);
case 'p':
*new_key = '\031'; /* C-y */
return (1);
case 's':
case KEYC_DC:
case 'x':
*new_key = KEYC_DC;
return (1);
case KEYC_DOWN:
case 'j':
*new_key = KEYC_DOWN;
return (1);
case KEYC_LEFT:
case 'h':
*new_key = KEYC_LEFT;
return (1);
case 'a':
case KEYC_RIGHT:
case 'l':
*new_key = KEYC_RIGHT;
return (1);
case KEYC_UP:
case 'k':
*new_key = KEYC_UP;
return (1);
case '\010' /* C-h */:
case '\003' /* C-c */:
case '\n':
case '\r':
return (1);
}
return (0);
}
/* Handle keys in prompt. */
int
status_prompt_key(struct client *c, key_code key)
@ -865,6 +980,7 @@ status_prompt_key(struct client *c, key_code key)
u_char ch;
size_t size, n, off, idx, bufsize, used;
struct utf8_data tmp, *first, *last, *ud;
int keys;
size = utf8_strlen(c->prompt_buffer);
@ -878,44 +994,49 @@ status_prompt_key(struct client *c, key_code key)
return (1);
}
switch (mode_key_lookup(&c->prompt_mdata, key)) {
case MODEKEYEDIT_CURSORLEFT:
keys = options_get_number(c->session->options, "status-keys");
if (keys == MODEKEY_VI) {
switch (status_prompt_translate_key(c, key, &key)) {
case 1:
goto process_key;
case 2:
goto append_key;
default:
return (0);
}
}
process_key:
switch (key) {
case KEYC_LEFT:
case '\002': /* C-b */
if (c->prompt_index > 0) {
c->prompt_index--;
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_SWITCHMODE:
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_SWITCHMODEAPPEND:
c->flags |= CLIENT_STATUS;
/* FALLTHROUGH */
case MODEKEYEDIT_CURSORRIGHT:
case KEYC_RIGHT:
case '\006': /* C-f */
if (c->prompt_index < size) {
c->prompt_index++;
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_SWITCHMODEBEGINLINE:
c->flags |= CLIENT_STATUS;
/* FALLTHROUGH */
case MODEKEYEDIT_STARTOFLINE:
case KEYC_HOME:
case '\001': /* C-a */
if (c->prompt_index != 0) {
c->prompt_index = 0;
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_SWITCHMODEAPPENDLINE:
c->flags |= CLIENT_STATUS;
/* FALLTHROUGH */
case MODEKEYEDIT_ENDOFLINE:
case KEYC_END:
case '\005': /* C-e */
if (c->prompt_index != size) {
c->prompt_index = size;
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_COMPLETE:
case '\011': /* Tab */
if (c->prompt_buffer[0].size == 0)
break;
@ -974,7 +1095,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_BACKSPACE:
case KEYC_BSPACE:
case '\010': /* C-h */
if (c->prompt_index != 0) {
if (c->prompt_index == size)
c->prompt_buffer[--c->prompt_index].size = 0;
@ -988,8 +1110,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_DELETE:
case MODEKEYEDIT_SWITCHMODESUBSTITUTE:
case KEYC_DC:
case '\004': /* C-d */
if (c->prompt_index != size) {
memmove(c->prompt_buffer + c->prompt_index,
c->prompt_buffer + c->prompt_index + 1,
@ -998,20 +1120,18 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_DELETELINE:
case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
case '\025': /* C-u */
c->prompt_buffer[0].size = 0;
c->prompt_index = 0;
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_DELETETOENDOFLINE:
case MODEKEYEDIT_SWITCHMODECHANGELINE:
case '\013': /* C-k */
if (c->prompt_index < size) {
c->prompt_buffer[c->prompt_index].size = 0;
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_DELETEWORD:
case '\027': /* C-w */
ws = options_get_string(oo, "word-separators");
idx = c->prompt_index;
@ -1042,35 +1162,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_NEXTSPACE:
ws = " ";
/* FALLTHROUGH */
case MODEKEYEDIT_NEXTWORD:
if (ws == NULL)
ws = options_get_string(oo, "word-separators");
/* Find a separator. */
while (c->prompt_index != size) {
idx = ++c->prompt_index;
if (status_prompt_in_list(ws, &c->prompt_buffer[idx]))
break;
}
/* Find the word right after the separator. */
while (c->prompt_index != size) {
idx = ++c->prompt_index;
if (!status_prompt_in_list(ws, &c->prompt_buffer[idx]))
break;
}
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_NEXTSPACEEND:
ws = " ";
/* FALLTHROUGH */
case MODEKEYEDIT_NEXTWORDEND:
if (ws == NULL)
ws = options_get_string(oo, "word-separators");
case 'f'|KEYC_ESCAPE:
ws = options_get_string(oo, "word-separators");
/* Find a word. */
while (c->prompt_index != size) {
@ -1093,12 +1186,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_PREVIOUSSPACE:
ws = " ";
/* FALLTHROUGH */
case MODEKEYEDIT_PREVIOUSWORD:
if (ws == NULL)
ws = options_get_string(oo, "word-separators");
case 'b'|KEYC_ESCAPE:
ws = options_get_string(oo, "word-separators");
/* Find a non-separator. */
while (c->prompt_index != 0) {
@ -1119,7 +1208,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_HISTORYUP:
case KEYC_UP:
case '\020': /* C-p */
histstr = status_prompt_up_history(&c->prompt_hindex);
if (histstr == NULL)
break;
@ -1128,7 +1218,8 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_HISTORYDOWN:
case KEYC_DOWN:
case '\016': /* C-n */
histstr = status_prompt_down_history(&c->prompt_hindex);
if (histstr == NULL)
break;
@ -1137,7 +1228,7 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_PASTE:
case '\031': /* C-y */
if ((pb = paste_get_top(NULL)) == NULL)
break;
bufdata = paste_buffer_data(pb, &bufsize);
@ -1170,7 +1261,7 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_TRANSPOSECHARS:
case '\024': /* C-t */
idx = c->prompt_index;
if (idx < size)
idx++;
@ -1183,7 +1274,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
case MODEKEYEDIT_ENTER:
case '\r':
case '\n':
s = utf8_tocstr(c->prompt_buffer);
if (*s != '\0')
status_prompt_add_history(s);
@ -1191,14 +1283,11 @@ status_prompt_key(struct client *c, key_code key)
status_prompt_clear(c);
free(s);
break;
case MODEKEYEDIT_CANCEL:
case '\033': /* Escape */
case '\003': /* C-c */
if (c->prompt_callbackfn(c->prompt_data, NULL) == 0)
status_prompt_clear(c);
break;
case MODEKEY_OTHER:
break;
default:
return (0);
}
append_key:

47
tmux.1
View File

@ -1104,11 +1104,7 @@ 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.
.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; and
Mode key bindings are defined in two tables:
.Em vi-choice
and
.Em emacs-choice
@ -3000,10 +2996,8 @@ layouts.
.It Xo Ic mode-keys
.Op Ic vi | emacs
.Xc
Use vi or emacs-style key bindings in copy and choice modes.
As with the
.Ic status-keys
option, the default is emacs, unless
Use vi or emacs-style key bindings in copy mode.
The default is emacs, unless
.Ev VISUAL
or
.Ev EDITOR
@ -3748,7 +3742,7 @@ session option.
Commands related to the status line are as follows:
.Bl -tag -width Ds
.It Xo Ic command-prompt
.Op Fl 1N
.Op Fl 1
.Op Fl I Ar inputs
.Op Fl p Ar prompts
.Op Fl t Ar target-client
@ -3776,13 +3770,6 @@ if it is present, or
.Ql \&:
if not.
.Pp
Both
.Ar inputs
and
.Ar prompts
may contain the special character sequences supported by the
.Ic status-left
option.
.Pp
Before the command is executed, the first occurrence of the string
.Ql %%
@ -3802,8 +3789,30 @@ to
.Fl 1
makes the prompt only accept one key press, in this case the resulting input
is a single character.
.Fl N
accepts only numbers and exit the prompt on any other key press.
.Pp
The following keys have a special meaning in the command prompt, depending
on the value of the
.Ic status-keys
option:
.Bl -column "FunctionXXXXXXXXXXXXXXXXXXXXXXXXX" "viXXXX" "emacsX" -offset indent
.It Sy "Function" Ta Sy "vi" Ta Sy "emacs"
.It Li "Cancel command prompt" Ta "Escape" Ta "Escape"
.It Li "Delete current word" Ta "" Ta "C-w"
.It Li "Delete entire command" Ta "d" Ta "C-u"
.It Li "Delete from cursor to end" Ta "D" Ta "C-k"
.It Li "Execute command" Ta "Enter" Ta "Enter"
.It Li "Get next command from history" Ta "" Ta "Down"
.It Li "Get previous command from history" Ta "" Ta "Up"
.It Li "Insert top paste buffer" Ta "p" Ta "C-y"
.It Li "Look for completions" Ta "Tab" Ta "Tab"
.It Li "Move cursor left" Ta "h" Ta "Left"
.It Li "Move cursor right" Ta "l" Ta "Right"
.It Li "Move cursor to end" Ta "$" Ta "C-e"
.It Li "Move cursor to next word" Ta "w" Ta "M-f"
.It Li "Move cursor to previous word" Ta "b" Ta "M-b"
.It Li "Move cursor to start" Ta "0" Ta "C-a"
.It Li "Transpose characters" Ta "" Ta "C-t"
.El
.It Xo Ic confirm-before
.Op Fl p Ar prompt
.Op Fl t Ar target-client

37
tmux.h
View File

@ -471,37 +471,6 @@ enum mode_key_cmd {
MODEKEY_NONE,
MODEKEY_OTHER,
/* Editing keys. */
MODEKEYEDIT_BACKSPACE,
MODEKEYEDIT_CANCEL,
MODEKEYEDIT_COMPLETE,
MODEKEYEDIT_CURSORLEFT,
MODEKEYEDIT_CURSORRIGHT,
MODEKEYEDIT_DELETE,
MODEKEYEDIT_DELETELINE,
MODEKEYEDIT_DELETETOENDOFLINE,
MODEKEYEDIT_DELETEWORD,
MODEKEYEDIT_ENDOFLINE,
MODEKEYEDIT_ENTER,
MODEKEYEDIT_HISTORYDOWN,
MODEKEYEDIT_HISTORYUP,
MODEKEYEDIT_NEXTSPACE,
MODEKEYEDIT_NEXTSPACEEND,
MODEKEYEDIT_NEXTWORD,
MODEKEYEDIT_NEXTWORDEND,
MODEKEYEDIT_PASTE,
MODEKEYEDIT_PREVIOUSSPACE,
MODEKEYEDIT_PREVIOUSWORD,
MODEKEYEDIT_STARTOFLINE,
MODEKEYEDIT_SWITCHMODE,
MODEKEYEDIT_SWITCHMODEAPPEND,
MODEKEYEDIT_SWITCHMODEAPPENDLINE,
MODEKEYEDIT_SWITCHMODEBEGINLINE,
MODEKEYEDIT_SWITCHMODECHANGELINE,
MODEKEYEDIT_SWITCHMODESUBSTITUTE,
MODEKEYEDIT_SWITCHMODESUBSTITUTELINE,
MODEKEYEDIT_TRANSPOSECHARS,
/* Menu (choice) keys. */
MODEKEYCHOICE_BACKSPACE,
MODEKEYCHOICE_BOTTOMLINE,
@ -527,7 +496,6 @@ enum mode_key_cmd {
/* Data required while mode keys are in use. */
struct mode_key_data {
struct mode_key_tree *tree;
int mode;
};
#define MODEKEY_EMACS 0
#define MODEKEY_VI 1
@ -535,8 +503,6 @@ struct mode_key_data {
/* Binding between a key and a command. */
struct mode_key_binding {
key_code key;
int mode;
enum mode_key_cmd cmd;
RB_ENTRY(mode_key_binding) entry;
@ -1267,13 +1233,12 @@ struct client {
void (*prompt_freefn)(void *);
void *prompt_data;
u_int prompt_hindex;
enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
#define PROMPT_SINGLE 0x1
#define PROMPT_NUMERIC 0x2
int prompt_flags;
struct mode_key_data prompt_mdata;
struct session *session;
struct session *last_session;