X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=keymap.c;h=e41d6d715e96e6a3539fe7b15eb7e5eefd5c894f;hp=665a5fcf07b3cc44f545d6dd8ff1c1684d63e261;hb=1bbedb2dcb610160fe7fd2b44bd098248bfd83a0;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/keymap.c b/keymap.c index 665a5fc..e41d6d7 100644 --- a/keymap.c +++ b/keymap.c @@ -16,6 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include "mutt.h" #include "mutt_menu.h" #include "mutt_curses.h" @@ -30,52 +34,58 @@ #include "functions.h" struct mapping_t Menus[] = { - { "alias", MENU_ALIAS }, - { "attach", MENU_ATTACH }, - { "browser", MENU_FOLDER }, - { "compose", MENU_COMPOSE }, - { "editor", MENU_EDITOR }, - { "index", MENU_MAIN }, - { "pager", MENU_PAGER }, - { "postpone", MENU_POST }, - { "pgp", MENU_PGP }, - { "smime", MENU_SMIME }, + { "alias", MENU_ALIAS }, + { "attach", MENU_ATTACH }, + { "browser", MENU_FOLDER }, + { "compose", MENU_COMPOSE }, + { "editor", MENU_EDITOR }, + { "index", MENU_MAIN }, + { "pager", MENU_PAGER }, + { "postpone", MENU_POST }, + { "pgp", MENU_PGP }, + { "smime", MENU_SMIME }, + +#ifdef HAVE_GPGME + { "key_select_pgp", MENU_KEY_SELECT_PGP }, + { "key_select_smime", MENU_KEY_SELECT_SMIME }, +#endif + #ifdef MIXMASTER - { "mix", MENU_MIX }, + { "mix", MENU_MIX }, #endif - { "query", MENU_QUERY }, - { "generic", MENU_GENERIC }, - { NULL, 0 } + { "query", MENU_QUERY }, + { "generic", MENU_GENERIC }, + { NULL, 0 } }; #define mutt_check_menu(s) mutt_getvaluebyname(s, Menus) static struct mapping_t KeyNames[] = { - { "", KEY_PPAGE }, - { "", KEY_NPAGE }, - { "", KEY_UP }, - { "", KEY_DOWN }, - { "", KEY_RIGHT }, - { "", KEY_LEFT }, - { "", KEY_DC }, + { "", KEY_PPAGE }, + { "", KEY_NPAGE }, + { "", KEY_UP }, + { "", KEY_DOWN }, + { "", KEY_RIGHT }, + { "", KEY_LEFT }, + { "", KEY_DC }, { "",KEY_BACKSPACE }, - { "", KEY_IC }, - { "", KEY_HOME }, - { "", KEY_END }, + { "", KEY_IC }, + { "", KEY_HOME }, + { "", KEY_END }, #ifdef KEY_ENTER - { "", KEY_ENTER }, + { "", KEY_ENTER }, #endif - { "", M_ENTER_C }, - { "", '\033' }, - { "", '\t' }, - { "", ' ' }, + { "", M_ENTER_C }, + { "", '\033' }, + { "", '\t' }, + { "", ' ' }, #ifdef KEY_BTAB { "", KEY_BTAB }, #endif - { NULL, 0 } + { NULL, 0 } }; /* contains the last key the user pressed */ @@ -149,18 +159,18 @@ static int parsekeys (char *str, keycode_t *d, int max) if ((n = mutt_getvaluebyname (s, KeyNames)) != -1) { - s = t; - *d = n; + s = t; + *d = n; } else if ((n = parse_fkey(s)) > 0) { - s = t; - *d = KEY_F (n); + s = t; + *d = KEY_F (n); } else if ((n = parse_keycode(s)) > 0) { - s = t; - *d = n; + s = t; + *d = n; } *t = c; @@ -203,13 +213,13 @@ void km_bind (char *s, int menu, int op, char *macro, char *descr) /* map and tmp match, but have different lengths, so overwrite */ do { - len = tmp->eq; - next = tmp->next; - FREE (&tmp->macro); - FREE (&tmp->keys); - FREE (&tmp->descr); - FREE (&tmp); - tmp = next; + len = tmp->eq; + next = tmp->next; + FREE (&tmp->macro); + FREE (&tmp->keys); + FREE (&tmp->descr); + FREE (&tmp); + tmp = next; } while (tmp && len >= pos); map->eq = len; @@ -228,7 +238,7 @@ void km_bind (char *s, int menu, int op, char *macro, char *descr) last = tmp; lastpos = pos; if (pos > tmp->eq) - pos = tmp->eq; + pos = tmp->eq; tmp = tmp->next; } } @@ -255,7 +265,7 @@ static int get_op (struct binding_t *bindings, const char *start, size_t len) for (i = 0; bindings[i].name; i++) { if (!ascii_strncasecmp (start, bindings[i].name, len) && - mutt_strlen (bindings[i].name) == len) + mutt_strlen (bindings[i].name) == len) return bindings[i].op; } @@ -268,8 +278,9 @@ static char *get_func (struct binding_t *bindings, int op) for (i = 0; bindings[i].name; i++) { - if (bindings[i].op == op) + if (bindings[i].op == op) { return bindings[i].name; + } } return NULL; @@ -288,49 +299,49 @@ static void push_string (char *s) if (*p == '>') { for (pp = p - 1; pp >= s && *pp != '<'; pp--) - ; + ; if (pp >= s) { - if ((i = parse_fkey (pp)) > 0) - { - mutt_ungetch (KEY_F (i), 0); - p = pp - 1; - continue; - } - - l = p - pp + 1; - for (i = 0; KeyNames[i].name; i++) - { - if (!ascii_strncasecmp (pp, KeyNames[i].name, l)) - break; - } - if (KeyNames[i].name) - { - /* found a match */ - mutt_ungetch (KeyNames[i].value, 0); - p = pp - 1; - continue; - } - - /* See if it is a valid command - * skip the '<' and the '>' when comparing */ - for (i = 0; Menus[i].name; i++) - { - struct binding_t *binding = km_get_table (Menus[i].value); - if (binding) - { - op = get_op (binding, pp + 1, l - 2); - if (op != OP_NULL) - break; - } - } - - if (op != OP_NULL) - { - mutt_ungetch (0, op); - p = pp - 1; - continue; - } + if ((i = parse_fkey (pp)) > 0) + { + mutt_ungetch (KEY_F (i), 0); + p = pp - 1; + continue; + } + + l = p - pp + 1; + for (i = 0; KeyNames[i].name; i++) + { + if (!ascii_strncasecmp (pp, KeyNames[i].name, l)) + break; + } + if (KeyNames[i].name) + { + /* found a match */ + mutt_ungetch (KeyNames[i].value, 0); + p = pp - 1; + continue; + } + + /* See if it is a valid command + * skip the '<' and the '>' when comparing */ + for (i = 0; Menus[i].name; i++) + { + struct binding_t *binding = km_get_table (Menus[i].value); + if (binding) + { + op = get_op (binding, pp + 1, l - 2); + if (op != OP_NULL) + break; + } + } + + if (op != OP_NULL) + { + mutt_ungetch (0, op); + p = pp - 1; + continue; + } } } mutt_ungetch (*p--, 0); @@ -356,9 +367,9 @@ static int retry_generic (int menu, keycode_t *keys, int keyslen, int lastkey) } /* return values: - * >0 function to execute - * OP_NULL no function bound to key sequence - * -1 error occured while reading input + * >0 function to execute + * OP_NULL no function bound to key sequence + * -1 error occured while reading input */ int km_dokey (int menu) { @@ -368,6 +379,7 @@ int km_dokey (int menu) int n = 0; int i; + if (!map) return (retry_generic (menu, NULL, 0, 0)); @@ -394,49 +406,49 @@ int km_dokey (int menu) /* is this a valid op for this menu? */ if ((bindings = km_get_table (menu)) && - (func = get_func (bindings, tmp.op))) - return tmp.op; + (func = get_func (bindings, tmp.op))) + return tmp.op; if (menu == MENU_EDITOR && get_func (OpEditor, tmp.op)) - return tmp.op; + return tmp.op; if (menu != MENU_EDITOR && menu != MENU_PAGER) { - /* check generic menu */ - bindings = OpGeneric; - if ((func = get_func (bindings, tmp.op))) - return tmp.op; + /* check generic menu */ + bindings = OpGeneric; + if ((func = get_func (bindings, tmp.op))) + return tmp.op; } /* Sigh. Valid function but not in this context. * Find the literal string and push it back */ for (i = 0; Menus[i].name; i++) { - bindings = km_get_table (Menus[i].value); - if (bindings) - { - func = get_func (bindings, tmp.op); - if (func) - { - /* careful not to feed the <..> as one token. otherwise - * push_string() will push the bogus op right back! */ - mutt_ungetch ('>', 0); - push_string (func); - mutt_ungetch ('<', 0); - break; - } - } + bindings = km_get_table (Menus[i].value); + if (bindings) + { + func = get_func (bindings, tmp.op); + if (func) + { + /* careful not to feed the <..> as one token. otherwise + * push_string() will push the bogus op right back! */ + mutt_ungetch ('>', 0); + push_string (func); + mutt_ungetch ('<', 0); + break; + } + } } /* continue to chew */ if (func) - continue; + continue; } /* Nope. Business as usual */ while (LastKey > map->keys[pos]) { if (pos > map->eq || !map->next) - return (retry_generic (menu, map->keys, pos, LastKey)); + return (retry_generic (menu, map->keys, pos, LastKey)); map = map->next; } @@ -447,13 +459,13 @@ int km_dokey (int menu) { if (map->op != OP_MACRO) - return map->op; + return map->op; if (n++ == 10) { - mutt_flushinp (); - mutt_error _("Macro loop detected."); - return -1; + mutt_flushinp (); + mutt_error _("Macro loop detected."); + return -1; } push_string (map->macro); @@ -557,6 +569,11 @@ void km_init (void) if ((WithCrypto & APPLICATION_SMIME)) create_bindings (OpSmime, MENU_SMIME); +#ifdef CRYPT_BACKEND_GPGME + create_bindings (OpPgp, MENU_KEY_SELECT_PGP); + create_bindings (OpSmime, MENU_KEY_SELECT_SMIME); +#endif + #ifdef MIXMASTER create_bindings (OpMix, MENU_MIX); @@ -687,38 +704,53 @@ int mutt_parse_push (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) return (r); } -/* expects to see: */ -char *parse_keymap (int *menu, BUFFER *s, BUFFER *err) +/* expects to see: ,,... */ +static char *parse_keymap (int *menu, BUFFER *s, int maxmenus, int *nummenus, BUFFER *err) { BUFFER buf; + int i=0; + char *p, *q; memset (&buf, 0, sizeof (buf)); /* menu name */ mutt_extract_token (&buf, s, 0); + p = buf.data; if (MoreArgs (s)) { - if ((*menu = mutt_check_menu (buf.data)) == -1) - { - snprintf (err->data, err->dsize, _("%s: no such menu"), buf.data); - } - else + while (i < maxmenus) { - /* key sequence */ - mutt_extract_token (&buf, s, 0); + q = strchr(p,','); + if (q) + *q = '\0'; - if (!*buf.data) + if ((menu[i] = mutt_check_menu (p)) == -1) { - strfcpy (err->data, _("null key sequence"), err->dsize); + snprintf (err->data, err->dsize, _("%s: no such menu"), p); + goto error; } - else if (MoreArgs (s)) - return (buf.data); + ++i; + if (q) + p = q+1; + else + break; } + *nummenus=i; + /* key sequence */ + mutt_extract_token (&buf, s, 0); + + if (!*buf.data) + { + strfcpy (err->data, _("null key sequence"), err->dsize); + } + else if (MoreArgs (s)) + return (buf.data); } else { strfcpy (err->data, _("too few arguments"), err->dsize); } +error: FREE (&buf.data); return (NULL); } @@ -765,6 +797,13 @@ struct binding_t *km_get_table (int menu) case MENU_PGP: return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL; +#ifdef CRYPT_BACKEND_GPGME + case MENU_KEY_SELECT_PGP: + return OpPgp; + case MENU_KEY_SELECT_SMIME: + return OpSmime; +#endif + #ifdef MIXMASTER case MENU_MIX: return OpMix; @@ -779,9 +818,10 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { struct binding_t *bindings = NULL; char *key; - int menu, r = 0; + int menu[sizeof(Menus)/sizeof(struct mapping_t)-1], r = 0, nummenus, i; - if ((key = parse_keymap (&menu, s, err)) == NULL) + if ((key = parse_keymap (menu, s, sizeof (menu)/sizeof (menu[0]), + &nummenus, err)) == NULL) return (-1); /* function to execute */ @@ -792,19 +832,28 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) r = -1; } else if (ascii_strcasecmp ("noop", buf->data) == 0) - km_bindkey (key, menu, OP_NULL); /* the `unbind' command */ + { + for (i = 0; i < nummenus; ++i) + { + km_bindkey (key, menu[i], OP_NULL); /* the `unbind' command */ + } + } else { - /* First check the "generic" list of commands */ - if (menu == MENU_PAGER || menu == MENU_EDITOR || menu == MENU_GENERIC || - try_bind (key, menu, buf->data, OpGeneric) != 0) + for (i = 0; i < nummenus; ++i) { - /* Now check the menu-specific list of commands (if they exist) */ - bindings = km_get_table (menu); - if (bindings && try_bind (key, menu, buf->data, bindings) != 0) + /* First check the "generic" list of commands */ + if (menu[i] == MENU_PAGER || menu[i] == MENU_EDITOR || + menu[i] == MENU_GENERIC || + try_bind (key, menu[i], buf->data, OpGeneric) != 0) { - snprintf (err->data, err->dsize, _("%s: no such function in map"), buf->data); - r = -1; + /* Now check the menu-specific list of commands (if they exist) */ + bindings = km_get_table (menu[i]); + if (bindings && try_bind (key, menu[i], buf->data, bindings) != 0) + { + snprintf (err->data, err->dsize, _("%s: no such function in map"), buf->data); + r = -1; + } } } } @@ -815,11 +864,11 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) /* macro */ int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { - int menu, r = -1; + int menu[sizeof(Menus)/sizeof(struct mapping_t)-1], r = -1, nummenus, i; char *seq = NULL; char *key; - if ((key = parse_keymap (&menu, s, err)) == NULL) + if ((key = parse_keymap (menu, s, sizeof (menu) / sizeof (menu[0]), &nummenus, err)) == NULL) return (-1); mutt_extract_token (buf, s, M_TOKEN_CONDENSE); @@ -837,20 +886,26 @@ int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) if (MoreArgs (s)) { - strfcpy (err->data, _("macro: too many arguments"), err->dsize); + strfcpy (err->data, _("macro: too many arguments"), err->dsize); } else { - km_bind (key, menu, OP_MACRO, seq, buf->data); - r = 0; + for (i = 0; i < nummenus; ++i) + { + km_bind (key, menu[i], OP_MACRO, seq, buf->data); + r = 0; + } } FREE (&seq); } else { - km_bind (key, menu, OP_MACRO, buf->data, NULL); - r = 0; + for (i = 0; i < nummenus; ++i) + { + km_bind (key, menu[i], OP_MACRO, buf->data, NULL); + r = 0; + } } } FREE (&key); @@ -877,7 +932,7 @@ int mutt_parse_exec (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) function = buf->data; if ((bindings = km_get_table (CurrentMenu)) == NULL - && CurrentMenu != MENU_PAGER) + && CurrentMenu != MENU_PAGER) bindings = OpGeneric; ops[nops] = get_op (bindings, function, mutt_strlen(function)); @@ -914,7 +969,7 @@ void mutt_what_key (void) if (ch != ERR && ch != ctrl ('G')) { mutt_message(_("Char = %s, Octal = %o, Decimal = %d"), - km_keyname(ch), ch, ch); + km_keyname(ch), ch, ch); } } while (ch != ERR && ch != ctrl ('G'));