version 1.7, 2009/07/27 18:51:46 |
version 1.8, 2009/07/27 19:29:35 |
|
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
enum mode_key_cmd mode_key_lookup_vi(struct mode_key_data *, int); |
/* vi editing keys. */ |
enum mode_key_cmd mode_key_lookup_emacs(struct mode_key_data *, int); |
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 |
{ '$', 1, MODEKEYEDIT_ENDOFLINE }, |
mode_key_init(struct mode_key_data *mdata, int type, int flags) |
{ '0', 1, MODEKEYEDIT_STARTOFLINE }, |
{ |
{ 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, |
mdata->type = type; |
{ '\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) |
{ 0, -1, 0 } |
flags |= MODEKEY_EDITMODE; |
}; |
mdata->flags = flags; |
|
} |
|
|
|
enum mode_key_cmd |
/* vi choice selection keys. */ |
mode_key_lookup(struct mode_key_data *mdata, int key) |
const struct mode_key_entry mode_key_vi_choice[] = { |
{ |
{ '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, |
switch (mdata->type) { |
{ '\r', 0, MODEKEYCHOICE_CHOOSE }, |
case MODEKEY_VI: |
{ 'j', 0, MODEKEYCHOICE_DOWN }, |
return (mode_key_lookup_vi(mdata, key)); |
{ 'k', 0, MODEKEYCHOICE_UP }, |
case MODEKEY_EMACS: |
{ 'q', 0, MODEKEYCHOICE_CANCEL }, |
return (mode_key_lookup_emacs(mdata, key)); |
{ KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, |
default: |
{ KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, |
fatalx("unknown mode key type"); |
{ KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, |
} |
{ KEYC_UP, 0, MODEKEYCHOICE_UP }, |
} |
|
|
|
enum mode_key_cmd |
{ 0, -1, 0 } |
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; |
|
} |
|
|
|
|
/* 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) { |
{ 0, -1, 0 } |
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); |
|
} |
|
|
|
switch (key) { |
/* emacs editing keys. */ |
case '\010': |
const struct mode_key_entry mode_key_emacs_edit[] = { |
case KEYC_BSPACE: |
{ '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE }, |
return (MODEKEYCMD_LEFT); |
{ '\002' /* C-p */, 0, MODEKEYEDIT_CURSORLEFT }, |
case KEYC_DC: |
{ '\004' /* C-d */, 0, MODEKEYEDIT_DELETE }, |
return (MODEKEYCMD_DELETE); |
{ '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE }, |
case '\011': |
{ '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT }, |
return (MODEKEYCMD_COMPLETE); |
{ '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE }, |
case 'i': |
{ '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, |
if (mdata->flags & MODEKEY_CANEDIT) |
{ '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE }, |
mdata->flags |= MODEKEY_EDITMODE; |
{ '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN }, |
break; |
{ '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP }, |
case 'a': |
{ '\031' /* C-y */, 0, MODEKEYEDIT_PASTE }, |
if (mdata->flags & MODEKEY_CANEDIT) { |
{ '\r', 0, MODEKEYEDIT_ENTER }, |
mdata->flags |= MODEKEY_EDITMODE; |
{ 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE }, |
return (MODEKEYCMD_RIGHT); |
{ KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, |
} |
{ KEYC_DC, 0, MODEKEYEDIT_DELETE }, |
break; |
{ KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, |
case '\r': |
{ KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, |
if (mdata->flags & (MODEKEY_CANEDIT|MODEKEY_CHOOSEMODE)) |
{ KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, |
return (MODEKEYCMD_CHOOSE); |
{ KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, |
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); |
|
} |
|
|
|
return (MODEKEYCMD_NONE); |
{ 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 } |
|
}; |
|
|
|
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 |
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) { |
const struct mode_key_entry *ment; |
case '\010': |
int mode; |
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); |
|
} |
|
|
|
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); |
} |
} |