diff --git a/src/nano.h b/src/nano.h index 4fd186a1..e4ffa990 100644 --- a/src/nano.h +++ b/src/nano.h @@ -239,6 +239,8 @@ typedef struct syntaxtype { /* The colors and their regexes used in this syntax. */ int nmultis; /* How many multiline regex strings this syntax has. */ + struct sc *sclist; + /* List of language-specific shortcuts */ struct syntaxtype *next; /* Next syntax. */ } syntaxtype; diff --git a/src/rcfile.c b/src/rcfile.c index 2e7c2ab6..4b456573 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -308,6 +308,7 @@ void parse_syntax(char *ptr) live_syntax->color = NULL; lastcolor = NULL; live_syntax->nmultis = 0; + live_syntax->sclist = NULL; /* Hook the new syntax in at the top of the list. */ live_syntax->next = syntaxes; @@ -345,7 +346,7 @@ bool is_universal(void (*func)(void)) } /* Bind or unbind a key combo, to or from a function. */ -void parse_binding(char *ptr, bool dobind) +void parse_binding(char *ptr, bool dobind, sc **list) { char *keyptr = NULL, *keycopy = NULL, *funcptr = NULL, *menuptr = NULL; sc *s, *newsc = NULL; @@ -422,8 +423,12 @@ void parse_binding(char *ptr, bool dobind) #ifndef NANO_TINY newsc->toggle = 0; #endif - } else + } else if (!opensyntax) newsc = strtosc(funcptr); + else { + rcfile_error(N_("Mapping \"%s\" is not allowed for syntax-specific"), funcptr); + goto free_things; + } if (newsc == NULL) { rcfile_error(N_("Cannot map name \"%s\" to a function"), funcptr); @@ -475,8 +480,9 @@ void parse_binding(char *ptr, bool dobind) } /* Now find and delete any existing same shortcut in the menu(s). */ - for (s = sclist; s != NULL; s = s->next) { - if ((s->menus & menu) && !strcmp(s->keystr, keycopy)) + for (s = *list; s != NULL; s = s->next) { + if ((s->menus & menu) && !strcmp(s->keystr, keycopy) && + !opensyntax ) s->menus &= ~menu; } @@ -484,15 +490,15 @@ void parse_binding(char *ptr, bool dobind) #ifndef NANO_TINY /* If this is a toggle, copy its sequence number. */ if (newsc->func == do_toggle_void) { - for (s = sclist; s != NULL; s = s->next) + for (s = *list; s != NULL; s = s->next) if (s->func == do_toggle_void && s->toggle == newsc->toggle) newsc->ordinal = s->ordinal; } else newsc->ordinal = 0; #endif /* Add the new shortcut at the start of the list. */ - newsc->next = sclist; - sclist = newsc; + newsc->next = *list; + *list = newsc; return; } @@ -997,6 +1003,8 @@ void parse_rcfile(FILE *rcstream, bool syntax_only) parse_colors(ptr, NANO_REG_EXTENDED | REG_ICASE); else if (strcasecmp(keyword, "linter") == 0) pick_up_name("linter", ptr, &live_syntax->linter); + else if (strcasecmp(keyword, "bind") == 0) + parse_binding(ptr, TRUE, &(live_syntax->sclist)); else if (strcasecmp(keyword, "formatter") == 0) #ifdef ENABLE_SPELLER pick_up_name("formatter", ptr, &live_syntax->formatter); @@ -1015,9 +1023,9 @@ void parse_rcfile(FILE *rcstream, bool syntax_only) else if (strcasecmp(keyword, "unset") == 0) set = -1; else if (strcasecmp(keyword, "bind") == 0) - parse_binding(ptr, TRUE); + parse_binding(ptr, TRUE, &sclist); else if (strcasecmp(keyword, "unbind") == 0) - parse_binding(ptr, FALSE); + parse_binding(ptr, FALSE, &sclist); else rcfile_error(N_("Command \"%s\" not understood"), keyword); diff --git a/src/winio.c b/src/winio.c index 2b4a3281..fd4f452f 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1722,6 +1722,24 @@ int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts) } #endif /* ENABLE_MOUSE */ +sc *get_shortcut_in_list(int *kbinput, sc *sclist) +{ + sc *s; + for (s = sclist; s != NULL; s = s->next) { + if ((s->menus & currmenu) && *kbinput == s->keycode && + meta_key == s->meta) { +#ifdef DEBUG + fprintf (stderr, "matched seq '%s' (menu is %x from %x)\n", + s->keystr, currmenu, s->menus); +#endif + return s; + } + } + + return NULL; +} + + /* Return the shortcut that corresponds to the values of kbinput (the * key itself) and meta_key (whether the key is a meta sequence). The * returned shortcut will be the first in the list that corresponds to @@ -1739,21 +1757,14 @@ const sc *get_shortcut(int *kbinput) if (!meta_key && (*kbinput & 0x7F) >= 0x20 && *kbinput <= 0xFF) return NULL; - for (s = sclist; s != NULL; s = s->next) { - if ((s->menus & currmenu) && *kbinput == s->keycode && - meta_key == s->meta) { -#ifdef DEBUG - fprintf (stderr, "matched seq '%s' (menu is %x from %x)\n", - s->keystr, currmenu, s->menus); -#endif - return s; - } - } + s = get_shortcut_in_list(kbinput, openfile->syntax->sclist); + if (s == NULL) + s = get_shortcut_in_list(kbinput, sclist); #ifdef DEBUG - fprintf (stderr, "matched nothing\n"); + if (s == NULL) fprintf (stderr, "matched nothing\n"); #endif - return NULL; + return s; } /* Move to (x, y) in win, and display a line of n spaces with the