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

command prompt.
This commit is contained in:
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.key = key;
mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) { if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
mbind = xmalloc(sizeof *mbind); mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key; mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
RB_INSERT(mode_key_tree, mtab->tree, mbind); RB_INSERT(mode_key_tree, mtab->tree, mbind);
} }
mbind->cmd = cmd; mbind->cmd = cmd;

View File

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

View File

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

View File

@ -47,52 +47,9 @@ struct mode_key_cmdstr {
/* Entry in the default mode key tables. */ /* Entry in the default mode key tables. */
struct mode_key_entry { struct mode_key_entry {
key_code key; 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; 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. */ /* Choice keys command strings. */
static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = { static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ MODEKEYCHOICE_BACKSPACE, "backspace" }, { MODEKEYCHOICE_BACKSPACE, "backspace" },
@ -118,205 +75,106 @@ static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ 0, NULL } { 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. */ /* vi choice selection keys. */
static const struct mode_key_entry mode_key_vi_choice[] = { static const struct mode_key_entry mode_key_vi_choice[] = {
{ '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '0' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, { '\002' /* C-b */, MODEKEYCHOICE_PAGEUP },
{ '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, { '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
{ '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, { '\005' /* C-e */, MODEKEYCHOICE_SCROLLDOWN },
{ '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN }, { '\006' /* C-f */, MODEKEYCHOICE_PAGEDOWN },
{ '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP }, { '\031' /* C-y */, MODEKEYCHOICE_SCROLLUP },
{ '\n', 0, MODEKEYCHOICE_CHOOSE }, { '\n', MODEKEYCHOICE_CHOOSE },
{ '\r', 0, MODEKEYCHOICE_CHOOSE }, { '\r', MODEKEYCHOICE_CHOOSE },
{ 'j', 0, MODEKEYCHOICE_DOWN }, { 'j', MODEKEYCHOICE_DOWN },
{ 'k', 0, MODEKEYCHOICE_UP }, { 'k', MODEKEYCHOICE_UP },
{ 'q', 0, MODEKEYCHOICE_CANCEL }, { 'q', MODEKEYCHOICE_CANCEL },
{ KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST }, { KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
{ 'g', 0, MODEKEYCHOICE_STARTOFLIST }, { 'g', MODEKEYCHOICE_STARTOFLIST },
{ 'H', 0, MODEKEYCHOICE_TOPLINE }, { 'H', MODEKEYCHOICE_TOPLINE },
{ 'L', 0, MODEKEYCHOICE_BOTTOMLINE }, { 'L', MODEKEYCHOICE_BOTTOMLINE },
{ 'G', 0, MODEKEYCHOICE_ENDOFLIST }, { 'G', MODEKEYCHOICE_ENDOFLIST },
{ KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST }, { KEYC_END, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, { KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
{ KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, { KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
{ KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, { KEYC_DOWN, MODEKEYCHOICE_DOWN },
{ KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, { KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
{ KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, { KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, { KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
{ KEYC_UP, 0, MODEKEYCHOICE_UP }, { KEYC_UP, MODEKEYCHOICE_UP },
{ ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, { ' ', MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, { KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, { KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, { KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, { KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
{ KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE }, { KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
{ KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE }, { KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP }, { KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN }, { KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
{ 0, -1, 0 } { KEYC_NONE, -1 }
}; };
struct mode_key_tree mode_key_tree_vi_choice; 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. */ /* emacs choice selection keys. */
static const struct mode_key_entry mode_key_emacs_choice[] = { static const struct mode_key_entry mode_key_emacs_choice[] = {
{ '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '0' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
{ '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, { '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
{ '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, { '\016' /* C-n */, MODEKEYCHOICE_DOWN },
{ '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, { '\020' /* C-p */, MODEKEYCHOICE_UP },
{ '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN }, { '\026' /* C-v */, MODEKEYCHOICE_PAGEDOWN },
{ '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL }, { '\033' /* Escape */, MODEKEYCHOICE_CANCEL },
{ '\n', 0, MODEKEYCHOICE_CHOOSE }, { '\n', MODEKEYCHOICE_CHOOSE },
{ '\r', 0, MODEKEYCHOICE_CHOOSE }, { '\r', MODEKEYCHOICE_CHOOSE },
{ 'q', 0, MODEKEYCHOICE_CANCEL }, { 'q', MODEKEYCHOICE_CANCEL },
{ 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP }, { 'v' | KEYC_ESCAPE, MODEKEYCHOICE_PAGEUP },
{ KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST }, { KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
{ '<' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTOFLIST }, { '<' | KEYC_ESCAPE, MODEKEYCHOICE_STARTOFLIST },
{ 'R' | KEYC_ESCAPE, 0, MODEKEYCHOICE_TOPLINE }, { 'R' | KEYC_ESCAPE, MODEKEYCHOICE_TOPLINE },
{ '>' | KEYC_ESCAPE, 0, MODEKEYCHOICE_ENDOFLIST }, { '>' | KEYC_ESCAPE, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST }, { KEYC_END, MODEKEYCHOICE_ENDOFLIST },
{ KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, { KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
{ KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, { KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
{ KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, { KEYC_DOWN, MODEKEYCHOICE_DOWN },
{ KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, { KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
{ KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, { KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, { KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
{ KEYC_UP, 0, MODEKEYCHOICE_UP }, { KEYC_UP, MODEKEYCHOICE_UP },
{ ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, { ' ', MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, { KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, { KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, { KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, { KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
{ KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE }, { KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
{ KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE }, { KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
{ KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP }, { KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN }, { KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
{ 0, -1, 0 } { KEYC_NONE, -1 }
}; };
struct mode_key_tree mode_key_tree_emacs_choice; struct mode_key_tree mode_key_tree_emacs_choice;
/* Table mapping key table names to default settings and trees. */ /* Table mapping key table names to default settings and trees. */
static const struct mode_key_table mode_key_tables[] = { 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, { "vi-choice", mode_key_cmdstr_choice,
&mode_key_tree_vi_choice, mode_key_vi_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, { "emacs-choice", mode_key_cmdstr_choice,
&mode_key_tree_emacs_choice, mode_key_emacs_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 int
mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2) 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) if (mbind1->key < mbind2->key)
return (-1); return (-1);
if (mbind1->key > mbind2->key) if (mbind1->key > mbind2->key)
@ -380,10 +234,9 @@ mode_key_init_trees(void)
for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { for (mtab = mode_key_tables; mtab->name != NULL; mtab++) {
RB_INIT(mtab->tree); 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 = xmalloc(sizeof *mbind);
mbind->key = ment->key; mbind->key = ment->key;
mbind->mode = ment->mode;
mbind->cmd = ment->cmd; mbind->cmd = ment->cmd;
RB_INSERT(mode_key_tree, mtab->tree, mbind); 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) mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
{ {
mdata->tree = mtree; mdata->tree = mtree;
mdata->mode = 0;
} }
enum mode_key_cmd 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; struct mode_key_binding *mbind, mtmp;
mtmp.key = key; mtmp.key = key;
mtmp.mode = mdata->mode; if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL)
if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL) {
if (mdata->mode != 0)
return (MODEKEY_NONE);
return (MODEKEY_OTHER); return (MODEKEY_OTHER);
} return (mbind->cmd);
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);
}
} }

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) void *data, int flags)
{ {
struct format_tree *ft; struct format_tree *ft;
int keys;
time_t t; time_t t;
char *tmp; char *tmp;
@ -685,12 +684,7 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
c->prompt_hindex = 0; c->prompt_hindex = 0;
c->prompt_flags = flags; c->prompt_flags = flags;
c->prompt_mode = PROMPT_ENTRY;
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->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE); c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE);
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
@ -765,7 +759,7 @@ status_prompt_redraw(struct client *c)
memcpy(&old_status, &c->status, sizeof old_status); memcpy(&old_status, &c->status, sizeof old_status);
screen_init(&c->status, c->tty.sx, 1, 0); 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"); style_apply(&gc, s->options, "message-command-style");
else else
style_apply(&gc, s->options, "message-style"); style_apply(&gc, s->options, "message-style");
@ -854,6 +848,127 @@ status_prompt_space(const struct utf8_data *ud)
return (*ud->data == ' '); 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. */ /* Handle keys in prompt. */
int int
status_prompt_key(struct client *c, key_code key) 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; u_char ch;
size_t size, n, off, idx, bufsize, used; size_t size, n, off, idx, bufsize, used;
struct utf8_data tmp, *first, *last, *ud; struct utf8_data tmp, *first, *last, *ud;
int keys;
size = utf8_strlen(c->prompt_buffer); size = utf8_strlen(c->prompt_buffer);
@ -878,44 +994,49 @@ status_prompt_key(struct client *c, key_code key)
return (1); return (1);
} }
switch (mode_key_lookup(&c->prompt_mdata, key)) { keys = options_get_number(c->session->options, "status-keys");
case MODEKEYEDIT_CURSORLEFT: 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) { if (c->prompt_index > 0) {
c->prompt_index--; c->prompt_index--;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_SWITCHMODE: case KEYC_RIGHT:
c->flags |= CLIENT_STATUS; case '\006': /* C-f */
break;
case MODEKEYEDIT_SWITCHMODEAPPEND:
c->flags |= CLIENT_STATUS;
/* FALLTHROUGH */
case MODEKEYEDIT_CURSORRIGHT:
if (c->prompt_index < size) { if (c->prompt_index < size) {
c->prompt_index++; c->prompt_index++;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_SWITCHMODEBEGINLINE: case KEYC_HOME:
c->flags |= CLIENT_STATUS; case '\001': /* C-a */
/* FALLTHROUGH */
case MODEKEYEDIT_STARTOFLINE:
if (c->prompt_index != 0) { if (c->prompt_index != 0) {
c->prompt_index = 0; c->prompt_index = 0;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_SWITCHMODEAPPENDLINE: case KEYC_END:
c->flags |= CLIENT_STATUS; case '\005': /* C-e */
/* FALLTHROUGH */
case MODEKEYEDIT_ENDOFLINE:
if (c->prompt_index != size) { if (c->prompt_index != size) {
c->prompt_index = size; c->prompt_index = size;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_COMPLETE: case '\011': /* Tab */
if (c->prompt_buffer[0].size == 0) if (c->prompt_buffer[0].size == 0)
break; break;
@ -974,7 +1095,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_BACKSPACE: case KEYC_BSPACE:
case '\010': /* C-h */
if (c->prompt_index != 0) { if (c->prompt_index != 0) {
if (c->prompt_index == size) if (c->prompt_index == size)
c->prompt_buffer[--c->prompt_index].size = 0; 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; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_DELETE: case KEYC_DC:
case MODEKEYEDIT_SWITCHMODESUBSTITUTE: case '\004': /* C-d */
if (c->prompt_index != size) { if (c->prompt_index != size) {
memmove(c->prompt_buffer + c->prompt_index, memmove(c->prompt_buffer + c->prompt_index,
c->prompt_buffer + c->prompt_index + 1, c->prompt_buffer + c->prompt_index + 1,
@ -998,20 +1120,18 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_DELETELINE: case '\025': /* C-u */
case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
c->prompt_buffer[0].size = 0; c->prompt_buffer[0].size = 0;
c->prompt_index = 0; c->prompt_index = 0;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_DELETETOENDOFLINE: case '\013': /* C-k */
case MODEKEYEDIT_SWITCHMODECHANGELINE:
if (c->prompt_index < size) { if (c->prompt_index < size) {
c->prompt_buffer[c->prompt_index].size = 0; c->prompt_buffer[c->prompt_index].size = 0;
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_DELETEWORD: case '\027': /* C-w */
ws = options_get_string(oo, "word-separators"); ws = options_get_string(oo, "word-separators");
idx = c->prompt_index; idx = c->prompt_index;
@ -1042,35 +1162,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_NEXTSPACE: case 'f'|KEYC_ESCAPE:
ws = " "; ws = options_get_string(oo, "word-separators");
/* 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");
/* Find a word. */ /* Find a word. */
while (c->prompt_index != size) { while (c->prompt_index != size) {
@ -1093,12 +1186,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_PREVIOUSSPACE: case 'b'|KEYC_ESCAPE:
ws = " "; ws = options_get_string(oo, "word-separators");
/* FALLTHROUGH */
case MODEKEYEDIT_PREVIOUSWORD:
if (ws == NULL)
ws = options_get_string(oo, "word-separators");
/* Find a non-separator. */ /* Find a non-separator. */
while (c->prompt_index != 0) { while (c->prompt_index != 0) {
@ -1119,7 +1208,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_HISTORYUP: case KEYC_UP:
case '\020': /* C-p */
histstr = status_prompt_up_history(&c->prompt_hindex); histstr = status_prompt_up_history(&c->prompt_hindex);
if (histstr == NULL) if (histstr == NULL)
break; break;
@ -1128,7 +1218,8 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer); c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_HISTORYDOWN: case KEYC_DOWN:
case '\016': /* C-n */
histstr = status_prompt_down_history(&c->prompt_hindex); histstr = status_prompt_down_history(&c->prompt_hindex);
if (histstr == NULL) if (histstr == NULL)
break; break;
@ -1137,7 +1228,7 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer); c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_PASTE: case '\031': /* C-y */
if ((pb = paste_get_top(NULL)) == NULL) if ((pb = paste_get_top(NULL)) == NULL)
break; break;
bufdata = paste_buffer_data(pb, &bufsize); bufdata = paste_buffer_data(pb, &bufsize);
@ -1170,7 +1261,7 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
break; break;
case MODEKEYEDIT_TRANSPOSECHARS: case '\024': /* C-t */
idx = c->prompt_index; idx = c->prompt_index;
if (idx < size) if (idx < size)
idx++; idx++;
@ -1183,7 +1274,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
break; break;
case MODEKEYEDIT_ENTER: case '\r':
case '\n':
s = utf8_tocstr(c->prompt_buffer); s = utf8_tocstr(c->prompt_buffer);
if (*s != '\0') if (*s != '\0')
status_prompt_add_history(s); status_prompt_add_history(s);
@ -1191,14 +1283,11 @@ status_prompt_key(struct client *c, key_code key)
status_prompt_clear(c); status_prompt_clear(c);
free(s); free(s);
break; break;
case MODEKEYEDIT_CANCEL: case '\033': /* Escape */
case '\003': /* C-c */
if (c->prompt_callbackfn(c->prompt_data, NULL) == 0) if (c->prompt_callbackfn(c->prompt_data, NULL) == 0)
status_prompt_clear(c); status_prompt_clear(c);
break; break;
case MODEKEY_OTHER:
break;
default:
return (0);
} }
append_key: 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 With vi key bindings, a prefix is entered using the number keys; with
emacs, the Alt (meta) key and a number begins prefix entry. emacs, the Alt (meta) key and a number begins prefix entry.
.Pp .Pp
Mode key bindings are defined in a set of named tables: Mode key bindings are defined in two tables:
.Em vi-edit
and
.Em emacs-edit
for keys used when line editing at the command prompt; and
.Em vi-choice .Em vi-choice
and and
.Em emacs-choice .Em emacs-choice
@ -3000,10 +2996,8 @@ layouts.
.It Xo Ic mode-keys .It Xo Ic mode-keys
.Op Ic vi | emacs .Op Ic vi | emacs
.Xc .Xc
Use vi or emacs-style key bindings in copy and choice modes. Use vi or emacs-style key bindings in copy mode.
As with the The default is emacs, unless
.Ic status-keys
option, the default is emacs, unless
.Ev VISUAL .Ev VISUAL
or or
.Ev EDITOR .Ev EDITOR
@ -3748,7 +3742,7 @@ session option.
Commands related to the status line are as follows: Commands related to the status line are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic command-prompt .It Xo Ic command-prompt
.Op Fl 1N .Op Fl 1
.Op Fl I Ar inputs .Op Fl I Ar inputs
.Op Fl p Ar prompts .Op Fl p Ar prompts
.Op Fl t Ar target-client .Op Fl t Ar target-client
@ -3776,13 +3770,6 @@ if it is present, or
.Ql \&: .Ql \&:
if not. if not.
.Pp .Pp
Both
.Ar inputs
and
.Ar prompts
may contain the special character sequences supported by the
.Ic status-left
option.
.Pp .Pp
Before the command is executed, the first occurrence of the string Before the command is executed, the first occurrence of the string
.Ql %% .Ql %%
@ -3802,8 +3789,30 @@ to
.Fl 1 .Fl 1
makes the prompt only accept one key press, in this case the resulting input makes the prompt only accept one key press, in this case the resulting input
is a single character. is a single character.
.Fl N .Pp
accepts only numbers and exit the prompt on any other key press. 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 .It Xo Ic confirm-before
.Op Fl p Ar prompt .Op Fl p Ar prompt
.Op Fl t Ar target-client .Op Fl t Ar target-client

37
tmux.h
View File

@ -471,37 +471,6 @@ enum mode_key_cmd {
MODEKEY_NONE, MODEKEY_NONE,
MODEKEY_OTHER, 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. */ /* Menu (choice) keys. */
MODEKEYCHOICE_BACKSPACE, MODEKEYCHOICE_BACKSPACE,
MODEKEYCHOICE_BOTTOMLINE, MODEKEYCHOICE_BOTTOMLINE,
@ -527,7 +496,6 @@ enum mode_key_cmd {
/* Data required while mode keys are in use. */ /* Data required while mode keys are in use. */
struct mode_key_data { struct mode_key_data {
struct mode_key_tree *tree; struct mode_key_tree *tree;
int mode;
}; };
#define MODEKEY_EMACS 0 #define MODEKEY_EMACS 0
#define MODEKEY_VI 1 #define MODEKEY_VI 1
@ -535,8 +503,6 @@ struct mode_key_data {
/* Binding between a key and a command. */ /* Binding between a key and a command. */
struct mode_key_binding { struct mode_key_binding {
key_code key; key_code key;
int mode;
enum mode_key_cmd cmd; enum mode_key_cmd cmd;
RB_ENTRY(mode_key_binding) entry; RB_ENTRY(mode_key_binding) entry;
@ -1267,13 +1233,12 @@ struct client {
void (*prompt_freefn)(void *); void (*prompt_freefn)(void *);
void *prompt_data; void *prompt_data;
u_int prompt_hindex; u_int prompt_hindex;
enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
#define PROMPT_SINGLE 0x1 #define PROMPT_SINGLE 0x1
#define PROMPT_NUMERIC 0x2 #define PROMPT_NUMERIC 0x2
int prompt_flags; int prompt_flags;
struct mode_key_data prompt_mdata;
struct session *session; struct session *session;
struct session *last_session; struct session *last_session;