summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-07-27 19:29:35 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-07-27 19:29:35 +0000
commitd95274c5f294ddf1341f66019fee47a35b4f2561 (patch)
treeb0e4b6d58f3c64091a740ab4de2e186549860fd5
parent13e29dd7b5dfcefdfda6a1dd3c3f78c9cd7f1cc9 (diff)
Change mode key bindings from big switches into a set of tables. Rather than
lumping them all together, split editing keys from those used in choice/more mode and those for copy/scroll mode. Tidier and clearer, and the first step towards customisable mode keys.
-rw-r--r--mode-key.c346
-rw-r--r--status.c40
-rw-r--r--tmux.h100
-rw-r--r--window-choose.c22
-rw-r--r--window-copy.c38
-rw-r--r--window-more.c18
-rw-r--r--window-scroll.c22
7 files changed, 314 insertions, 272 deletions
diff --git a/mode-key.c b/mode-key.c
index a4a534b9..58769eda 100644
--- a/mode-key.c
+++ b/mode-key.c
@@ -20,198 +20,182 @@
#include "tmux.h"
-enum mode_key_cmd mode_key_lookup_vi(struct mode_key_data *, int);
-enum mode_key_cmd mode_key_lookup_emacs(struct mode_key_data *, int);
+/* vi editing keys. */
+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 },
+ { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE },
+ { '\r', 0, MODEKEYEDIT_ENTER },
+ { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE },
+ { KEYC_DC, 0, MODEKEYEDIT_DELETE },
-void
-mode_key_init(struct mode_key_data *mdata, int type, int flags)
-{
- mdata->type = type;
+ { '$', 1, MODEKEYEDIT_ENDOFLINE },
+ { '0', 1, MODEKEYEDIT_STARTOFLINE },
+ { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE },
+ { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL },
+ { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE },
+ { '\r', 1, MODEKEYEDIT_ENTER },
+ { '^', 1, MODEKEYEDIT_STARTOFLINE },
+ { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND },
+ { 'h', 1, MODEKEYEDIT_CURSORLEFT },
+ { 'i', 1, MODEKEYEDIT_SWITCHMODE },
+ { 'j', 1, MODEKEYEDIT_HISTORYDOWN },
+ { 'k', 1, MODEKEYEDIT_HISTORYUP },
+ { 'l', 1, MODEKEYEDIT_CURSORRIGHT },
+ { 'p', 1, MODEKEYEDIT_PASTE },
+ { 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 },
- if (flags & MODEKEY_CANEDIT)
- flags |= MODEKEY_EDITMODE;
- mdata->flags = flags;
-}
+ { 0, -1, 0 }
+};
-enum mode_key_cmd
-mode_key_lookup(struct mode_key_data *mdata, int key)
-{
- switch (mdata->type) {
- case MODEKEY_VI:
- return (mode_key_lookup_vi(mdata, key));
- case MODEKEY_EMACS:
- return (mode_key_lookup_emacs(mdata, key));
- default:
- fatalx("unknown mode key type");
- }
-}
+/* vi choice selection keys. */
+const struct mode_key_entry mode_key_vi_choice[] = {
+ { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL },
+ { '\r', 0, MODEKEYCHOICE_CHOOSE },
+ { 'j', 0, MODEKEYCHOICE_DOWN },
+ { 'k', 0, MODEKEYCHOICE_UP },
+ { 'q', 0, MODEKEYCHOICE_CANCEL },
+ { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN },
+ { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN },
+ { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP },
+ { KEYC_UP, 0, MODEKEYCHOICE_UP },
-enum mode_key_cmd
-mode_key_lookup_vi(struct mode_key_data *mdata, int key)
-{
- if (key & KEYC_ESCAPE) {
- key &= ~KEYC_ESCAPE;
- if (mdata->flags & MODEKEY_CANEDIT)
- mdata->flags ^= MODEKEY_EDITMODE;
- }
+ { 0, -1, 0 }
+};
+/* vi copy mode keys. */
+const struct mode_key_entry mode_key_vi_copy[] = {
+ { ' ', 0, MODEKEYCOPY_STARTSELECTION },
+ { '$', 0, MODEKEYCOPY_ENDOFLINE },
+ { '0', 0, MODEKEYCOPY_STARTOFLINE },
+ { '\003' /* C-c */, 0, MODEKEYCOPY_QUIT },
+ { '\006' /* C-f */, 0, MODEKEYCOPY_NEXTPAGE },
+ { '\010' /* C-h */, 0, MODEKEYCOPY_LEFT },
+ { '\025' /* C-u */, 0, MODEKEYCOPY_PREVIOUSPAGE },
+ { '\033' /* Escape */, 0, MODEKEYCOPY_CLEARSELECTION },
+ { '\r', 0, MODEKEYCOPY_COPYSELECTION },
+ { '^', 0, MODEKEYCOPY_BACKTOINDENTATION },
+ { 'b', 0, MODEKEYCOPY_PREVIOUSWORD },
+ { 'h', 0, MODEKEYCOPY_LEFT },
+ { 'j', 0, MODEKEYCOPY_DOWN },
+ { 'k', 0, MODEKEYCOPY_UP },
+ { 'l', 0, MODEKEYCOPY_RIGHT },
+ { 'q', 0, MODEKEYCOPY_QUIT },
+ { 'w', 0, MODEKEYCOPY_NEXTWORD },
+ { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT },
+ { KEYC_DOWN, 0, MODEKEYCOPY_DOWN },
+ { KEYC_LEFT, 0, MODEKEYCOPY_LEFT },
+ { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE },
+ { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE },
+ { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT },
+ { KEYC_UP, 0, MODEKEYCOPY_UP },
- if (mdata->flags & MODEKEY_EDITMODE) {
- switch (key) {
- case '\003':
- return (MODEKEYCMD_QUIT);
- case '\033':
- if (mdata->flags & MODEKEY_CANEDIT)
- mdata->flags &= ~MODEKEY_EDITMODE;
- return (MODEKEYCMD_NONE);
- case '\010':
- case KEYC_BSPACE:
- return (MODEKEYCMD_BACKSPACE);
- case '\011':
- return (MODEKEYCMD_COMPLETE);
- case KEYC_DC:
- return (MODEKEYCMD_DELETE);
- case '\r':
- return (MODEKEYCMD_CHOOSE);
- }
- return (MODEKEYCMD_OTHERKEY);
- }
+ { 0, -1, 0 }
+};
- switch (key) {
- case '\010':
- case KEYC_BSPACE:
- return (MODEKEYCMD_LEFT);
- case KEYC_DC:
- return (MODEKEYCMD_DELETE);
- case '\011':
- return (MODEKEYCMD_COMPLETE);
- case 'i':
- if (mdata->flags & MODEKEY_CANEDIT)
- mdata->flags |= MODEKEY_EDITMODE;
- break;
- case 'a':
- if (mdata->flags & MODEKEY_CANEDIT) {
- mdata->flags |= MODEKEY_EDITMODE;
- return (MODEKEYCMD_RIGHT);
- }
- break;
- case '\r':
- if (mdata->flags & (MODEKEY_CANEDIT|MODEKEY_CHOOSEMODE))
- return (MODEKEYCMD_CHOOSE);
- return (MODEKEYCMD_COPYSELECTION);
- case '0':
- return (MODEKEYCMD_STARTOFLINE);
- case '^':
- return (MODEKEYCMD_BACKTOINDENTATION);
- case '\033':
- return (MODEKEYCMD_CLEARSELECTION);
- case 'C':
- if (mdata->flags & MODEKEY_CANEDIT)
- mdata->flags |= MODEKEY_EDITMODE;
- return (MODEKEYCMD_DELETETOENDOFLINE);
- case 'D':
- return (MODEKEYCMD_DELETETOENDOFLINE);
- case 'j':
- case KEYC_DOWN:
- return (MODEKEYCMD_DOWN);
- case '$':
- return (MODEKEYCMD_ENDOFLINE);
- case 'h':
- case KEYC_LEFT:
- return (MODEKEYCMD_LEFT);
- case '\006':
- case KEYC_NPAGE:
- return (MODEKEYCMD_NEXTPAGE);
- case 'w':
- return (MODEKEYCMD_NEXTWORD);
- case '\025':
- case KEYC_PPAGE:
- return (MODEKEYCMD_PREVIOUSPAGE);
- case 'b':
- return (MODEKEYCMD_PREVIOUSWORD);
- case 'q':
- case '\003':
- return (MODEKEYCMD_QUIT);
- case 'l':
- case KEYC_RIGHT:
- return (MODEKEYCMD_RIGHT);
- case ' ':
- return (MODEKEYCMD_STARTSELECTION);
- case 'k':
- case KEYC_UP:
- return (MODEKEYCMD_UP);
- case 'p':
- return (MODEKEYCMD_PASTE);
- }
+/* emacs editing keys. */
+const struct mode_key_entry mode_key_emacs_edit[] = {
+ { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE },
+ { '\002' /* C-p */, 0, MODEKEYEDIT_CURSORLEFT },
+ { '\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 },
+ { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE },
+ { '\r', 0, MODEKEYEDIT_ENTER },
+ { '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 },
+
+ { 0, -1, 0 }
+};
+
+/* emacs choice selection keys. */
+const struct mode_key_entry mode_key_emacs_choice[] = {
+ { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL },
+ { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL },
+ { '\r', 0, MODEKEYCHOICE_CHOOSE },
+ { 'q', 0, MODEKEYCHOICE_CANCEL },
+ { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN },
+ { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN },
+ { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP },
+ { KEYC_UP, 0, MODEKEYCHOICE_UP },
+
+ { 0, -1, 0 }
+};
+
+/* emacs copy mode keys. */
+const struct mode_key_entry mode_key_emacs_copy[] = {
+ { ' ', 0, MODEKEYCOPY_NEXTPAGE },
+ { '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION },
+ { '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE },
+ { '\002' /* C-b */, 0, MODEKEYCOPY_LEFT },
+ { '\003' /* C-c */, 0, MODEKEYCOPY_QUIT },
+ { '\005' /* C-e */, 0, MODEKEYCOPY_ENDOFLINE },
+ { '\006' /* C-f */, 0, MODEKEYCOPY_RIGHT },
+ { '\007' /* C-g */, 0, MODEKEYCOPY_CLEARSELECTION },
+ { '\016' /* C-n */, 0, MODEKEYCOPY_DOWN },
+ { '\020' /* C-p */, 0, MODEKEYCOPY_UP },
+ { '\026' /* C-v */, 0, MODEKEYCOPY_NEXTPAGE },
+ { '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION },
+ { '\033' /* Escape */, 0, MODEKEYCOPY_QUIT },
+ { 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD },
+ { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORD },
+ { 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION },
+ { 'q', 0, MODEKEYCOPY_QUIT },
+ { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE },
+ { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION },
+ { KEYC_DOWN, 0, MODEKEYCOPY_DOWN },
+ { KEYC_LEFT, 0, MODEKEYCOPY_LEFT },
+ { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE },
+ { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE },
+ { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT },
+ { KEYC_UP, 0, MODEKEYCOPY_UP },
+
+ { 0, -1, 0 }
+};
- return (MODEKEYCMD_NONE);
+void
+mode_key_init(struct mode_key_data *mdata, const struct mode_key_entry *table)
+{
+ mdata->table = table;
+ mdata->mode = 0;
}
enum mode_key_cmd
-mode_key_lookup_emacs(struct mode_key_data *mdata, int key)
+mode_key_lookup(struct mode_key_data *mdata, int key)
{
- switch (key) {
- case '\010':
- case KEYC_BSPACE:
- return (MODEKEYCMD_BACKSPACE);
- case '\004':
- case KEYC_DC:
- return (MODEKEYCMD_DELETE);
- case '\011':
- return (MODEKEYCMD_COMPLETE);
- case '\r':
- return (MODEKEYCMD_CHOOSE);
- case '\001':
- return (MODEKEYCMD_STARTOFLINE);
- case 'm' | KEYC_ESCAPE:
- return (MODEKEYCMD_BACKTOINDENTATION);
- case '\007':
- return (MODEKEYCMD_CLEARSELECTION);
- case '\027':
- case 'w' | KEYC_ESCAPE:
- return (MODEKEYCMD_COPYSELECTION);
- case '\013':
- return (MODEKEYCMD_DELETETOENDOFLINE);
- case '\016':
- case KEYC_DOWN:
- return (MODEKEYCMD_DOWN);
- case '\005':
- return (MODEKEYCMD_ENDOFLINE);
- case '\002':
- case KEYC_LEFT:
- return (MODEKEYCMD_LEFT);
- case ' ':
- if (mdata->flags & MODEKEY_CANEDIT)
- break;
- /* FALLTHROUGH */
- case '\026':
- case KEYC_NPAGE:
- return (MODEKEYCMD_NEXTPAGE);
- case 'f' | KEYC_ESCAPE:
- return (MODEKEYCMD_NEXTWORD);
- case '\031':
- return (MODEKEYCMD_PASTE);
- case 'v' | KEYC_ESCAPE:
- case KEYC_PPAGE:
- return (MODEKEYCMD_PREVIOUSPAGE);
- case 'b' | KEYC_ESCAPE:
- return (MODEKEYCMD_PREVIOUSWORD);
- case '\006':
- case KEYC_RIGHT:
- return (MODEKEYCMD_RIGHT);
- case '\000':
- return (MODEKEYCMD_STARTSELECTION);
- case '\020':
- case KEYC_UP:
- return (MODEKEYCMD_UP);
- case 'q':
- if (mdata->flags & MODEKEY_CANEDIT)
- break;
- /* FALLTHROUGH */
- case '\003':
- case '\033':
- return (MODEKEYCMD_QUIT);
- }
+ const struct mode_key_entry *ment;
+ int mode;
- return (MODEKEYCMD_OTHERKEY);
+ mode = mdata->mode;
+ for (ment = mdata->table; ment->mode != -1; ment++) {
+ if (ment->mode == mode && key == ment->key) {
+ switch (ment->cmd) {
+ case MODEKEYEDIT_SWITCHMODE:
+ case MODEKEYEDIT_SWITCHMODEAPPEND:
+ mdata->mode = 1 - mdata->mode;
+ /* FALLTHROUGH */
+ default:
+ return (ment->cmd);
+ }
+ }
+ }
+ if (mode != 0)
+ return (MODEKEY_NONE);
+ return (MODEKEY_OTHER);
}
diff --git a/status.c b/status.c
index 98f7967b..fef440eb 100644
--- a/status.c
+++ b/status.c
@@ -589,6 +589,8 @@ status_prompt_set(struct client *c, const char *msg,
int (*callbackfn)(void *, const char *), void (*freefn)(void *),
void *data, int flags)
{
+ int keys;
+
status_message_clear(c);
status_prompt_clear(c);
@@ -605,9 +607,11 @@ status_prompt_set(struct client *c, const char *msg,
c->prompt_flags = flags;
- mode_key_init(&c->prompt_mdata,
- options_get_number(&c->session->options, "status-keys"),
- MODEKEY_CANEDIT);
+ keys = options_get_number(&c->session->options, "status-keys");
+ if (keys == MODEKEY_EMACS)
+ mode_key_init(&c->prompt_mdata, mode_key_emacs_edit);
+ else
+ mode_key_init(&c->prompt_mdata, mode_key_vi_edit);
c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE);
c->flags |= CLIENT_STATUS;
@@ -727,32 +731,32 @@ status_prompt_key(struct client *c, int key)
size = strlen(c->prompt_buffer);
switch (mode_key_lookup(&c->prompt_mdata, key)) {
- case MODEKEYCMD_LEFT:
+ case MODEKEYEDIT_CURSORLEFT:
if (c->prompt_index > 0) {
c->prompt_index--;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_RIGHT:
+ case MODEKEYEDIT_SWITCHMODEAPPEND:
+ case MODEKEYEDIT_CURSORRIGHT:
if (c->prompt_index < size) {
c->prompt_index++;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_STARTOFLINE:
- case MODEKEYCMD_BACKTOINDENTATION:
+ case MODEKEYEDIT_STARTOFLINE:
if (c->prompt_index != 0) {
c->prompt_index = 0;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_ENDOFLINE:
+ case MODEKEYEDIT_ENDOFLINE:
if (c->prompt_index != size) {
c->prompt_index = size;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_COMPLETE:
+ case MODEKEYEDIT_COMPLETE:
if (*c->prompt_buffer == '\0')
break;
@@ -800,7 +804,7 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYCMD_BACKSPACE:
+ case MODEKEYEDIT_BACKSPACE:
if (c->prompt_index != 0) {
if (c->prompt_index == size)
c->prompt_buffer[--c->prompt_index] = '\0';
@@ -813,7 +817,7 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_DELETE:
+ case MODEKEYEDIT_DELETE:
if (c->prompt_index != size) {
memmove(c->prompt_buffer + c->prompt_index,
c->prompt_buffer + c->prompt_index + 1,
@@ -821,13 +825,13 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_DELETETOENDOFLINE:
+ case MODEKEYEDIT_DELETETOENDOFLINE:
if (c->prompt_index < size) {
c->prompt_buffer[c->prompt_index] = '\0';
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYCMD_UP:
+ case MODEKEYEDIT_HISTORYUP:
if (server_locked)
break;
@@ -845,7 +849,7 @@ status_prompt_key(struct client *c, int key)
c->prompt_index = strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYCMD_DOWN:
+ case MODEKEYEDIT_HISTORYDOWN:
if (server_locked)
break;
@@ -864,7 +868,7 @@ status_prompt_key(struct client *c, int key)
c->prompt_index = strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYCMD_PASTE:
+ case MODEKEYEDIT_PASTE:
if ((pb = paste_get_top(&c->session->buffers)) == NULL)
break;
if ((last = strchr(pb->data, '\n')) == NULL)
@@ -886,7 +890,7 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYCMD_CHOOSE:
+ case MODEKEYEDIT_ENTER:
if (*c->prompt_buffer != '\0') {
status_prompt_add_history(c);
if (c->prompt_callbackfn(
@@ -895,11 +899,11 @@ status_prompt_key(struct client *c, int key)
break;
}
/* FALLTHROUGH */
- case MODEKEYCMD_QUIT:
+ case MODEKEYEDIT_CANCEL:
if (c->prompt_callbackfn(c->prompt_data, NULL) == 0)
status_prompt_clear(c);
break;
- case MODEKEYCMD_OTHERKEY:
+ case MODEKEY_OTHER:
if (key < 32 || key > 126)
break;
c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + 2);
diff --git a/tmux.h b/tmux.h
index 3dc82eca..505e3d68 100644
--- a/tmux.h
+++ b/tmux.h
@@ -358,40 +358,71 @@ struct msg_unlock_data {
/* Editing keys. */
enum mode_key_cmd {
- MODEKEYCMD_BACKSPACE = 0x1000,
- MODEKEYCMD_BACKTOINDENTATION,
- MODEKEYCMD_CHOOSE,
- MODEKEYCMD_CLEARSELECTION,
- MODEKEYCMD_COMPLETE,
- MODEKEYCMD_COPYSELECTION,
- MODEKEYCMD_DELETE,
- MODEKEYCMD_DELETETOENDOFLINE,
- MODEKEYCMD_DOWN,
- MODEKEYCMD_ENDOFLINE,
- MODEKEYCMD_LEFT,
- MODEKEYCMD_NEXTPAGE,
- MODEKEYCMD_NEXTWORD,
- MODEKEYCMD_NONE,
- MODEKEYCMD_OTHERKEY,
- MODEKEYCMD_PASTE,
- MODEKEYCMD_PREVIOUSPAGE,
- MODEKEYCMD_PREVIOUSWORD,
- MODEKEYCMD_QUIT,
- MODEKEYCMD_RIGHT,
- MODEKEYCMD_STARTOFLINE,
- MODEKEYCMD_STARTSELECTION,
- MODEKEYCMD_UP,
+ MODEKEY_NONE,
+ MODEKEY_OTHER,
+
+ /* Editing keys. */
+ MODEKEYEDIT_BACKSPACE,
+ MODEKEYEDIT_CANCEL,
+ MODEKEYEDIT_COMPLETE,
+ MODEKEYEDIT_CURSORLEFT,
+ MODEKEYEDIT_CURSORRIGHT,
+ MODEKEYEDIT_DELETE,
+ MODEKEYEDIT_DELETETOENDOFLINE,
+ MODEKEYEDIT_ENDOFLINE,
+ MODEKEYEDIT_ENTER,
+ MODEKEYEDIT_HISTORYDOWN,
+ MODEKEYEDIT_HISTORYUP,
+ MODEKEYEDIT_PASTE,
+ MODEKEYEDIT_STARTOFLINE,
+ MODEKEYEDIT_SWITCHMODE,
+ MODEKEYEDIT_SWITCHMODEAPPEND,
+
+ /* Menu (choice) keys. */
+ MODEKEYCHOICE_CANCEL,
+ MODEKEYCHOICE_CHOOSE,
+ MODEKEYCHOICE_DOWN,
+ MODEKEYCHOICE_PAGEDOWN,
+ MODEKEYCHOICE_PAGEUP,
+ MODEKEYCHOICE_UP,
+
+ /* Copy keys. */
+ MODEKEYCOPY_CANCEL,
+ MODEKEYCOPY_BACKTOINDENTATION,
+ MODEKEYCOPY_CLEARSELECTION,
+ MODEKEYCOPY_COPYSELECTION,
+ MODEKEYCOPY_DOWN,
+ MODEKEYCOPY_ENDOFLINE,
+ MODEKEYCOPY_LEFT,
+ MODEKEYCOPY_NEXTPAGE,
+ MODEKEYCOPY_NEXTWORD,
+ MODEKEYCOPY_NONE,
+ MODEKEYCOPY_PREVIOUSPAGE,
+ MODEKEYCOPY_PREVIOUSWORD,
+ MODEKEYCOPY_QUIT,
+ MODEKEYCOPY_RIGHT,
+ MODEKEYCOPY_STARTOFLINE,
+ MODEKEYCOPY_STARTSELECTION,
+ MODEKEYCOPY_UP,
};
-struct mode_key_data {
- int type;
+struct mode_key_entry {
+ int key;
- int flags;
-#define MODEKEY_EDITMODE 0x1
-#define MODEKEY_CANEDIT 0x2
-#define MODEKEY_CHOOSEMODE 0x4
-};
+ /*
+ * 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;
+};
+struct mode_key_data {
+ const struct mode_key_entry *table;
+ int mode;
+};
#define MODEKEY_EMACS 0
#define MODEKEY_VI 1
@@ -1032,7 +1063,14 @@ void sighandler(int);
int load_cfg(const char *, char **x);
/* mode-key.c */
-void mode_key_init(struct mode_key_data *, int, int);
+extern const struct mode_key_entry mode_key_vi_edit[];
+extern const struct mode_key_entry mode_key_vi_choice[];
+extern const struct mode_key_entry mode_key_vi_copy[];
+extern const struct mode_key_entry mode_key_emacs_edit[];
+extern const struct mode_key_entry mode_key_emacs_choice[];
+extern const struct mode_key_entry mode_key_emacs_copy[];
+void mode_key_init(
+ struct mode_key_data *, const struct mode_key_entry *);
enum mode_key_cmd mode_key_lookup(struct mode_key_data *, int);
/* options.c */
diff --git a/window-choose.c b/window-choose.c
index 8439c9a0..b1ae3bc5 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -109,6 +109,7 @@ window_choose_init(struct window_pane *wp)
{
struct window_choose_mode_data *data;
struct screen *s;
+ int keys;
wp->modedata = data = xmalloc(sizeof *data);
@@ -124,9 +125,11 @@ window_choose_init(struct window_pane *wp)
s->mode &= ~MODE_CURSOR;
s->mode |= MODE_MOUSE;
- mode_key_init(&data->mdata,
- options_get_number(&wp->window->options, "mode-keys"),
- MODEKEY_CHOOSEMODE);
+ keys = options_get_number(&wp->window->options, "mode-keys");
+ if (keys == MODEKEY_EMACS)
+ mode_key_init(&data->mdata, mode_key_emacs_choice);
+ else
+ mode_key_init(&data->mdata, mode_key_vi_choice);
return (s);
}
@@ -174,16 +177,16 @@ window_choose_key(struct window_pane *wp, unused struct client *c, int key)
items = ARRAY_LENGTH(&data->list);
switch (mode_key_lookup(&data->mdata, key)) {
- case MODEKEYCMD_QUIT:
+ case MODEKEYCHOICE_CANCEL:
data->callbackfn(data->data, -1);
window_pane_reset_mode(wp);
break;
- case MODEKEYCMD_CHOOSE:
+ case MODEKEYCHOICE_CHOOSE:
item = &ARRAY_ITEM(&data->list, data->selected);
data->callbackfn(data->data, item->idx);
window_pane_reset_mode(wp);
break;
- case MODEKEYCMD_UP:
+ case MODEKEYCHOICE_UP:
if (items == 0)
break;
if (data->selected == 0) {
@@ -205,7 +208,7 @@ window_choose_key(struct window_pane *wp, unused struct client *c, int key)
screen_write_stop(&ctx);
}
break;
- case MODEKEYCMD_DOWN:
+ case MODEKEYCHOICE_DOWN:
if (items == 0)
break;
if (data->selected == items - 1) {
@@ -215,6 +218,7 @@ window_choose_key(struct window_pane *wp, unused struct client *c, int key)
break;
}
data->selected++;
+
if (data->selected >= data->top + screen_size_y(&data->screen))
window_choose_scroll_down(wp);
else {
@@ -226,7 +230,7 @@ window_choose_key(struct window_pane *wp, unused struct client *c, int key)
screen_write_stop(&ctx);
}
break;
- case MODEKEYCMD_PREVIOUSPAGE:
+ case MODEKEYCHOICE_PAGEUP:
if (data->selected < screen_size_y(s)) {
data->selected = 0;
data->top = 0;
@@ -239,7 +243,7 @@ window_choose_key(struct window_pane *wp, unused struct client *c, int key)
}
window_choose_redraw_screen(wp);
break;
- case MODEKEYCMD_NEXTPAGE:
+ case MODEKEYCHOICE_PAGEDOWN:
data->selected += screen_size_y(s);
if (data->selected > items - 1)
data->selected = items - 1;
diff --git a/window-copy.c b/window-copy.c
index d87a645e..7ca4cd34 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -94,6 +94,7 @@ window_copy_init(struct window_pane *wp)
struct screen *s;
struct screen_write_ctx ctx;
u_int i;
+ int keys;
wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0;
@@ -105,8 +106,11 @@ window_copy_init(struct window_pane *wp)
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode |= MODE_MOUSE;
- mode_key_init(&data->mdata,
- options_get_number(&wp->window->options, "mode-keys"), 0);
+ keys = options_get_number(&wp->window->options, "mode-keys");
+ if (keys == MODEKEY_EMACS)
+ mode_key_init(&data->mdata, mode_key_emacs_copy);
+ else
+ mode_key_init(&data->mdata, mode_key_vi_copy);
s->cx = data->cx;
s->cy = data->cy;
@@ -164,25 +168,25 @@ window_copy_key(struct window_pane *wp, struct client *c, int key)
struct screen *s = &data->screen;
switch (mode_key_lookup(&data->mdata, key)) {
- case MODEKEYCMD_QUIT:
+ case MODEKEYCOPY_QUIT:
window_pane_reset_mode(wp);
break;
- case MODEKEYCMD_LEFT:
+ case MODEKEYCOPY_LEFT:
window_copy_cursor_left(wp);
return;
- case MODEKEYCMD_RIGHT:
+ case MODEKEYCOPY_RIGHT:
window_copy_cursor_right(wp);
return;
- case MODEKEYCMD_UP:
+ case MODEKEYCOPY_UP:
window_copy_cursor_up(wp);
return;
- case MODEKEYCMD_DOWN:
+ case MODEKEYCOPY_DOWN:
window_copy_cursor_down(wp);
return;
- case MODEKEYCMD_PREVIOUSPAGE:
+ case MODEKEYCOPY_PREVIOUSPAGE:
window_copy_pageup(wp);
break;
- case MODEKEYCMD_NEXTPAGE:
+ case MODEKEYCOPY_NEXTPAGE:
if (data->oy < screen_size_y(s))
data->oy = 0;
else
@@ -190,33 +194,33 @@ window_copy_key(struct window_pane *wp, struct client *c, int key)
window_copy_update_selection(wp);
window_copy_redraw_screen(wp);
break;
- case MODEKEYCMD_STARTSELECTION:
+ case MODEKEYCOPY_STARTSELECTION:
window_copy_start_selection(wp);
window_copy_redraw_screen(wp);
break;
- case MODEKEYCMD_CLEARSELECTION:
+ case MODEKEYCOPY_CLEARSELECTION:
screen_clear_selection(&data->screen);
window_copy_redraw_screen(wp);
break;
- case MODEKEYCMD_COPYSELECTION:
+ case MODEKEYCOPY_COPYSELECTION:
if (c != NULL && c->session != NULL) {
window_copy_copy_selection(wp, c);
window_pane_reset_mode(wp);
}
break;
- case MODEKEYCMD_STARTOFLINE:
+ case MODEKEYCOPY_STARTOFLINE:
window_copy_cursor_start_of_line(wp);
break;
- case MODEKEYCMD_BACKTOINDENTATION:
+ case MODEKEYCOPY_BACKTOINDENTATION:
window_copy_cursor_back_to_indentation(wp);
break;
- case MODEKEYCMD_ENDOFLINE:
+ case MODEKEYCOPY_ENDOFLINE:
window_copy_cursor_end_of_line(wp);
break;
- case MODEKEYCMD_NEXTWORD:
+ case MODEKEYCOPY_NEXTWORD:
window_copy_cursor_next_word(wp);
break;
- case MODEKEYCMD_PREVIOUSWORD:
+ case MODEKEYCOPY_PREVIOUSWORD:
window_copy_cursor_previous_word(wp);
break;
default:
diff --git a/window-more.c b/window-more.c
index d92a06a2..a113c4ba 100644
--- a/window-more.c
+++ b/window-more.c
@@ -80,6 +80,7 @@ window_more_init(struct window_pane *wp)
{
struct window_more_mode_data *data;
struct screen *s;
+ int keys;
wp->modedata = data = xmalloc(sizeof *data);
ARRAY_INIT(&data->list);
@@ -89,8 +90,11 @@ window_more_init(struct window_pane *wp)
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
- mode_key_init(&data->mdata,
- options_get_number(&wp->window->options, "mode-keys"), 0);
+ keys = options_get_number(&wp->window->options, "mode-keys");
+ if (keys == MODEKEY_EMACS)
+ mode_key_init(&data->mdata, mode_key_emacs_choice);
+ else
+ mode_key_init(&data->mdata, mode_key_vi_choice);
return (s);
}
@@ -126,23 +130,23 @@ window_more_key(struct window_pane *wp, unused struct client *c, int key)
struct screen *s = &data->screen;
switch (mode_key_lookup(&data->mdata, key)) {
- case MODEKEYCMD_QUIT:
+ case MODEKEYCHOICE_CANCEL:
window_pane_reset_mode(wp);
break;
- case MODEKEYCMD_UP:
+ case MODEKEYCHOICE_UP:
window_more_scroll_up(wp);
break;
- case MODEKEYCMD_DOWN:
+ case MODEKEYCHOICE_DOWN:
window_more_scroll_down(wp);
break;
- case MODEKEYCMD_PREVIOUSPAGE:
+ case MODEKEYCHOICE_PAGEUP:
if (data->top < screen_size_y(s))
data->top = 0;
else
data->top -= screen_size_y(s);
window_more_redraw_screen(wp);
break;
- case MODEKEYCMD_NEXTPAGE:
+ case MODEKEYCHOICE_PAGEDOWN:
if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list))
data->top = ARRAY_LENGTH(&data->list);
else
diff --git a/window-scroll.c b/window-scroll.c
index ecc76306..c14d1ab0 100644
--- a/window-scroll.c
+++ b/window-scroll.c
@@ -63,6 +63,7 @@ window_scroll_init(struct window_pane *wp)
struct screen *s;
struct screen_write_ctx ctx;
u_int i;
+ int keys;
wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0;
@@ -72,8 +73,11 @@ window_scroll_init(struct window_pane *wp)
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
- mode_key_init(&data->mdata,
- options_get_number(&wp->window->options, "mode-keys"), 0);
+ keys = options_get_number(&wp->window->options, "mode-keys");
+ if (keys == MODEKEY_EMACS)
+ mode_key_init(&data->mdata, mode_key_emacs_copy);
+ else
+ mode_key_init(&data->mdata, mode_key_vi_copy);
screen_write_start(&ctx, NULL, s);
for (i = 0; i < screen_size_y(s); i++)
@@ -128,25 +132,25 @@ window_scroll_key(struct window_pane *wp, unused struct client *c, int key)
struct screen *s = &data->screen;
switch (mode_key_lookup(&data->mdata, key)) {
- case MODEKEYCMD_QUIT:
+ case MODEKEYCOPY_QUIT:
window_pane_reset_mode(wp);
break;
- case MODEKEYCMD_LEFT:
+ case MODEKEYCOPY_LEFT:
window_scroll_scroll_left(wp);
break;
- case MODEKEYCMD_RIGHT:
+ case MODEKEYCOPY_RIGHT:
window_scroll_scroll_right(wp);
break;
- case MODEKEYCMD_UP:
+ case MODEKEYCOPY_UP:
window_scroll_scroll_up(wp);
break;
- case MODEKEYCMD_DOWN:
+ case MODEKEYCOPY_DOWN:
window_scroll_scroll_down(wp);
break;
- case MODEKEYCMD_PREVIOUSPAGE:
+ case MODEKEYCOPY_PREVIOUSPAGE:
window_scroll_pageup(wp);
break;
- case MODEKEYCMD_NEXTPAGE:
+ case MODEKEYCOPY_NEXTPAGE:
if (data->oy < screen_size_y(s))
data->oy = 0;
else