]> granicus.if.org Git - neomutt/commitdiff
#1550: bind for multiple menus.
authorAaron Lehmann <aaronl@vitelus.com>
Mon, 12 Apr 2004 20:02:49 +0000 (20:02 +0000)
committerAaron Lehmann <aaronl@vitelus.com>
Mon, 12 Apr 2004 20:02:49 +0000 (20:02 +0000)
doc/manual.sgml.head
doc/muttrc.man.head
keymap.c

index 76be516c3aae4fdefc14522d08a32a16a209846d..0ced0e5088c79e2d61e2a5904f64c1c25064f4e1 100644 (file)
@@ -881,9 +881,11 @@ Usage: <tt/bind/ <em/map/ <em/key/ <em/function/
 This command allows you to change the default key bindings (operation
 invoked when pressing a key).
 
-<em/map/ specifies in which menu the binding belongs.  The currently
-defined maps are:
+<em/map/ specifies in which menu the binding belongs.  Multiple maps may
+be specified by separating them with commas (no additional whitespace is
+allowed). The currently defined maps are:
 
+<label id="maps">
 <descrip>
 <tag/generic/
 This is not a real menu, but is used as a fallback for all of the other
@@ -1019,6 +1021,11 @@ you had typed <em/sequence/.  So if you have a common sequence of commands
 you type, you can create a macro to execute those commands with a single
 key.
 
+<em/menu/ is the <ref id="maps" name="map"> which the macro will be bound.
+Multiple maps may be specified by separating multiple menu arguments by
+commas. Whitespace may not be used in between the menu arguments and the
+commas separating them.
+
 <em/key/ and <em/sequence/ are expanded by the same rules as the <ref
 id="bind" name="key bindings">.  There are some additions however.  The
 first is that control characters in <em/sequence/ can also be specified
index d75484e04c32181f3db1cde265d3070f668edd7c..b52b81b824e7cfc2ad3a7eb312761e4cfca109a4 100644 (file)
@@ -125,9 +125,10 @@ the file name, and not use a
 entry given for the original MIME type.  For instance, you may add
 the \fBapplication/octet-stream\fP MIME type to this list.
 .TP
-\fBbind\fP \fImap\fP \fIkey\fP \fIfunction\fP
-This command binds the given \fIkey\fP for the given \fImap\fP to
-the given \fIfunction\fP.
+\fBbind\fP \fImap1,map2,...\fP \fIkey\fP \fIfunction\fP
+This command binds the given \fIkey\fP for the given \fImap\fP or maps
+to the given \fIfunction\fP. Multiple maps may be specified by
+separating them with commas (no whitespace is allowed).
 .IP
 Valid maps are:
 .BR generic ", " alias ", " attach ", " 
@@ -179,7 +180,8 @@ executed in the order given in the configuration file.
 .TP
 \fBmacro\fP \fImap\fP \fIkey\fP \fIsequence\fP [ \fIdescription\fP ]
 This command binds the given \fIsequence\fP of keys to the given
-\fIkey\fP in the given \fImap\fP.  For valid maps, see \fBbind\fP.
+\fIkey\fP in the given \fImap\fP or maps.  For valid maps, see \fBbind\fP. To
+specify multipe maps, put only a comma between the maps.
 .PP
 .nf
 \fBcolor\fP \fIobject\fP \fIforeground\fP \fIbackground\fP [ \fI regexp\fP ]
index 5a5d9142b0a1d94702e1ea4194bde76ccd8ca073..828aa5ef64d398731e37e134230673e8807a296b 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -688,38 +688,53 @@ int mutt_parse_push (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   return (r);
 }
 
-/* expects to see: <menu-string> <key-string> */
-char *parse_keymap (int *menu, BUFFER *s, BUFFER *err)
+/* expects to see: <menu-string>,<menu-string>,... <key-string> */
+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)
+    while (i < maxmenus)
     {
-      snprintf (err->data, err->dsize, _("%s: no such menu"), buf.data);
-    }
-    else
-    {
-      /* 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);
 }
@@ -780,9 +795,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 */
@@ -793,19 +809,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;
+        }
       }
     }
   }
@@ -816,11 +841,11 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 /* macro <menu> <key> <macro> <description> */
 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);
@@ -842,16 +867,22 @@ int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
       }
       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);