changeset 50798:2d72cdb7e9f8

(map_keymap_item, map_keymap_char_table_item, map_keymap) (map_keymap_call, Fmap_keymap): New functions. (syms_of_keymap): Defsubr map-keymap.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 04 May 2003 00:13:06 +0000
parents 5b0873c0b734
children 80f5ff945c90
files src/keymap.c
diffstat 1 files changed, 97 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/keymap.c	Sun May 04 00:10:01 2003 +0000
+++ b/src/keymap.c	Sun May 04 00:13:06 2003 +0000
@@ -640,6 +640,102 @@
   }
 }
 
+static void
+map_keymap_item (fun, args, key, val, data)
+     map_keymap_function_t fun;
+     Lisp_Object args, key, val;
+     void *data;
+{
+  /* We should maybe try to detect bindings shadowed by previous
+     ones and things like that.  */
+  if (EQ (val, Qt))
+    val = Qnil;
+  (*fun) (key, val, args, data);
+}
+
+static void
+map_keymap_char_table_item (args, key, val)
+     Lisp_Object args, key, val;
+{
+  if (!NILP (val))
+    {
+      map_keymap_function_t fun = XSAVE_VALUE (XCAR (args))->pointer;
+      args = XCDR (args);
+      map_keymap_item (fun, XCDR (args), key, val,
+		       XSAVE_VALUE (XCAR (args))->pointer);
+    }
+}
+
+/* Call FUN for every binding in MAP.
+   FUN is called with 4 arguments: FUN (KEY, BINDING, ARGS, DATA).  */
+void
+map_keymap (map, fun, args, data, autoload)
+     map_keymap_function_t fun;
+     Lisp_Object map, args;
+     void *data;
+     int autoload;
+{
+  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object tail;
+
+  GCPRO3 (map, args, tail);
+  map = get_keymap (map, 1, autoload);
+  for (tail = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map;
+       CONSP (tail) || (tail = get_keymap (tail, 0, autoload), CONSP (tail));
+       tail = XCDR (tail))
+    {
+      Lisp_Object binding = XCAR (tail);
+      
+      if (CONSP (binding))
+	map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data);
+      else if (VECTORP (binding))
+	{
+	  /* Loop over the char values represented in the vector.  */
+	  int len = ASIZE (binding);
+	  int c;
+	  abort();
+	  for (c = 0; c < len; c++)
+	    {
+	      Lisp_Object character;
+	      XSETFASTINT (character, c);
+	      map_keymap_item (fun, args, character, AREF (binding, c), data);
+	    }
+	}
+      else if (CHAR_TABLE_P (binding))
+	{
+	  Lisp_Object indices[3];
+	  map_char_table (map_keymap_char_table_item, Qnil, binding,
+			  Fcons (make_save_value (fun, 0),
+				 Fcons (make_save_value (data, 0),
+					args)),
+			  0, indices);
+	}
+    }
+  UNGCPRO;
+}
+
+static void
+map_keymap_call (key, val, fun, dummy)
+     Lisp_Object key, val, fun;
+     void *dummy;
+{
+  call2 (fun, key, val);
+}
+
+DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 2, 0,
+       doc: /* Call FUNCTION for every binding in KEYMAP.
+FUNCTION is called with two arguments: the event and its binding.  */)
+     (function, keymap)
+     Lisp_Object function, keymap;
+{
+  if (INTEGERP (function))
+    /* We have to stop integers early since map_keymap gives them special
+       significance.  */
+    Fsignal (Qinvalid_function, Fcons (function, Qnil));
+  map_keymap (keymap, map_keymap_call, function, NULL, 1);
+  return Qnil;
+}
+
 /* Given OBJECT which was found in a slot in a keymap,
    trace indirect definitions to get the actual definition of that slot.
    An indirect definition is a list of the form
@@ -3653,6 +3749,7 @@
   defsubr (&Sset_keymap_parent);
   defsubr (&Smake_keymap);
   defsubr (&Smake_sparse_keymap);
+  defsubr (&Smap_keymap);
   defsubr (&Scopy_keymap);
   defsubr (&Scommand_remapping);
   defsubr (&Skey_binding);