>From b9881bf2e1b424d05041e4824a8690e36629731e Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Fri, 11 Aug 2017 15:23:56 +0300 Subject: [PATCH] bindings: hard-bind Alt+Left and Alt+Right to buffer switching This also fixes https://savannah.gnu.org/bugs/?51735. Reported-by: Urja Rannikko Signed-off-by: Urja Rannikko Signed-off-by: Benno Schulenberg --- src/global.c | 46 ++++++++++++++++++++++++++++++++++------------ src/help.c | 2 +- src/nano.c | 5 +++++ src/nano.h | 4 ++++ src/proto.h | 5 +++++ src/rcfile.c | 7 +------ src/winio.c | 16 ++++++++++++++++ 7 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/global.c b/src/global.c index dca4c653..01f72ca9 100644 --- a/src/global.c +++ b/src/global.c @@ -77,6 +77,7 @@ int controlleft, controlright, controlup, controldown, controlhome, controlend; #ifndef NANO_TINY int shiftcontrolleft, shiftcontrolright, shiftcontrolup, shiftcontroldown; int shiftcontrolhome, shiftcontrolend; +int altleft, altright, altup, altdown; int shiftaltleft, shiftaltright, shiftaltup, shiftaltdown; #endif @@ -423,28 +424,45 @@ functionptrtype func_from_key(int *kbinput) void assign_keyinfo(sc *s, const char *keystring, const int keycode) { s->keystr = keystring; - s->meta = (keystring[0] == 'M'); + s->meta = (keystring[0] == 'M' && keystring[2] != '\xE2'); assert(strlen(keystring) > 1 && (!s->meta || strlen(keystring) > 2)); if (keycode) s->keycode = keycode; - else if (keystring[0] == '^') { + else + s->keycode = keycode_from_string(keystring); +} + +/* Parse the given keystring and return the corresponding keycode, + * or return -1 when the string is invalid. */ +int keycode_from_string(const char *keystring) +{ + if (keystring[0] == '^') { if (strcasecmp(keystring, "^Space") == 0) - s->keycode = 0; + return 0; + if (strlen(keystring) == 2) + return keystring[1] - 64; else - s->keycode = keystring[1] - 64; - } else if (s->meta) { + return -1; + } else if (keystring[0] == 'M') { if (strcasecmp(keystring, "M-Space") == 0) - s->keycode = (int)' '; + return (int)' '; + if (keystring[1] == '-') + return tolower((unsigned char)keystring[2]); else - s->keycode = tolower((unsigned char)keystring[2]); - } else if (keystring[0] == 'F') - s->keycode = KEY_F0 + atoi(&keystring[1]); - else if (!strcasecmp(keystring, "Ins")) - s->keycode = KEY_IC; + return -1; + } else if (keystring[0] == 'F') { + int fn = atoi(&keystring[1]); + if ((fn < 0) || (fn > 63)) + return -1; + return KEY_F0 + fn; + } else if (!strcasecmp(keystring, "Ins")) + return KEY_IC; else if (!strcasecmp(keystring, "Del")) - s->keycode = KEY_DC; + return KEY_DC; + else + return -1; } #ifdef DEBUG @@ -1124,6 +1142,10 @@ void shortcut_init(void) add_to_sclist(MMOST, "\xE2\x86\x92", KEY_RIGHT, do_right, 0); add_to_sclist(MSOME, "^\xE2\x86\x90", CONTROL_LEFT, do_prev_word_void, 0); add_to_sclist(MSOME, "^\xE2\x86\x92", CONTROL_RIGHT, do_next_word_void, 0); +#ifdef ENABLE_MULTIBUFFER + add_to_sclist(MMAIN, "M-\xE2\x86\x90", ALT_LEFT, switch_to_prev_buffer_void, 0); + add_to_sclist(MMAIN, "M-\xE2\x86\x92", ALT_RIGHT, switch_to_next_buffer_void, 0); +#endif } else #endif { diff --git a/src/help.c b/src/help.c index 12b3efa5..46aff4e7 100644 --- a/src/help.c +++ b/src/help.c @@ -510,7 +510,7 @@ void help_init(void) if (scsfound == 1) { sprintf(ptr, "%s ", s->keystr); /* Unicode arrows take three bytes instead of one. */ - if (s->keystr[0] == '\xE2' || s->keystr[1] == '\xE2') + if (strstr(s->keystr, "\xE2") != NULL) ptr += 8; else ptr += 6; diff --git a/src/nano.c b/src/nano.c index 935e07c4..69d069dd 100644 --- a/src/nano.c +++ b/src/nano.c @@ -2516,6 +2516,11 @@ int main(int argc, char **argv) /* Ask for the codes for Shift+Control+Home/End. */ shiftcontrolhome = get_keycode("kHOM6", SHIFT_CONTROL_HOME); shiftcontrolend = get_keycode("kEND6", SHIFT_CONTROL_END); + /* Ask for the codes for Alt+Left/Right/Up/Down. */ + altleft = get_keycode("kLFT3", ALT_LEFT); + altright = get_keycode("kRIT3", ALT_RIGHT); + altup = get_keycode("kUP3", ALT_UP); + altdown = get_keycode("kDN3", ALT_DOWN); /* Ask for the codes for Shift+Alt+Left/Right/Up/Down. */ shiftaltleft = get_keycode("kLFT4", SHIFT_ALT_LEFT); shiftaltright = get_keycode("kRIT4", SHIFT_ALT_RIGHT); diff --git a/src/nano.h b/src/nano.h index 7c52da8b..58b66619 100644 --- a/src/nano.h +++ b/src/nano.h @@ -568,6 +568,10 @@ enum #define SHIFT_CONTROL_DOWN 0x408 #define SHIFT_CONTROL_HOME 0x413 #define SHIFT_CONTROL_END 0x414 +#define ALT_LEFT 0x415 +#define ALT_RIGHT 0x416 +#define ALT_UP 0x417 +#define ALT_DOWN 0x418 #define SHIFT_ALT_LEFT 0x409 #define SHIFT_ALT_RIGHT 0x40a #define SHIFT_ALT_UP 0x40b diff --git a/src/proto.h b/src/proto.h index 6c36c4ac..888bee80 100644 --- a/src/proto.h +++ b/src/proto.h @@ -71,6 +71,10 @@ extern int shiftcontrolup; extern int shiftcontroldown; extern int shiftcontrolhome; extern int shiftcontrolend; +extern int altleft; +extern int altright; +extern int altup; +extern int altdown; extern int shiftaltleft; extern int shiftaltright; extern int shiftaltup; @@ -328,6 +332,7 @@ size_t length_of_list(int menu); const sc *first_sc_for(int menu, void (*func)(void)); int the_code_for(void (*func)(void), int defaultval); functionptrtype func_from_key(int *kbinput); +int keycode_from_string(const char *keystring); void assign_keyinfo(sc *s, const char *keystring, const int keycode); void print_sclist(void); void shortcut_init(void); diff --git a/src/rcfile.c b/src/rcfile.c index db9f6fba..c4611bfd 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -410,12 +410,7 @@ void parse_binding(char *ptr, bool dobind) else if (keycopy[0] != '^' && keycopy[0] != 'M' && keycopy[0] != 'F') { rcfile_error(N_("Key name must begin with \"^\", \"M\", or \"F\"")); goto free_copy; - } else if ((keycopy[0] == 'M' && keycopy[1] != '-') || - (keycopy[0] == '^' && ((keycopy[1] < 'A' || keycopy[1] > 'z') || - keycopy[1] == '[' || keycopy[1] == '`' || - (strlen(keycopy) > 2 && strcmp(keycopy, "^Space") != 0))) || - (strlen(keycopy) > 3 && strcmp(keycopy, "^Space") != 0 && - strcmp(keycopy, "M-Space") != 0)) { + } else if (keycode_from_string(keycopy) < 0) { rcfile_error(N_("Key name %s is invalid"), keycopy); goto free_copy; } diff --git a/src/winio.c b/src/winio.c index a66a4a31..c2f79c73 100644 --- a/src/winio.c +++ b/src/winio.c @@ -523,6 +523,10 @@ int parse_kbinput(WINDOW *win) } else if (retval == shiftcontrolend) { shift_held = TRUE; return CONTROL_END; + } else if (retval == altleft) { + return ALT_LEFT; + } else if (retval == altright) { + return ALT_RIGHT; } else if (retval == shiftaltleft) { shift_held = TRUE; return KEY_HOME; @@ -954,6 +958,18 @@ int convert_sequence(const int *seq, size_t seq_len) } break; #ifndef NANO_TINY + case '3': + switch (seq[4]) { + case 'A': /* Esc [ 1 ; 3 A == Alt-Up on xterm. */ + return ALT_UP; + case 'B': /* Esc [ 1 ; 3 B == Alt-Down on xterm. */ + return ALT_DOWN; + case 'C': /* Esc [ 1 ; 3 C == Alt-Right on xterm. */ + return ALT_RIGHT; + case 'D': /* Esc [ 1 ; 3 D == Alt-Left on xterm. */ + return ALT_LEFT; + } + break; case '4': /* When the arrow keys are held together with Shift+Meta, * act as if they are Home/End/PgUp/PgDown with Shift. */ -- 2.14.1