changeset 96747:ebf3bd5f0017

* keymap.c: Remove all NS-specific code. (where_is_preferred_modifier, Vwhere_is_preferred_modifier): New vars. (preferred_sequence_p): Rename from ascii_sequence_p; pay attention to where_is_preferred_modifier, return a different value depending on how preferred is the binding. (where_is_internal): Adjust accordingly. (Fwhere_is_internal): Refresh where_is_preferred_modifier. Adjust to new preferred_sequence_p. (syms_of_keymap): Declare `where-is-preferred-modifier'. * keyboard.c (parse_solitary_modifier): Not static any more. * keyboard.h (parse_solitary_modifier): Declare.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 16 Jul 2008 19:23:49 +0000
parents 7fa6fba9e51b
children 92f7bbffcb45
files etc/NEWS src/ChangeLog src/keyboard.c src/keyboard.h src/keymap.c
diffstat 5 files changed, 87 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Wed Jul 16 19:14:01 2008 +0000
+++ b/etc/NEWS	Wed Jul 16 19:23:49 2008 +0000
@@ -83,6 +83,8 @@
 
 * Changes in Emacs 23.1
 
+** `where-is-preferred-modifier' can specify your favorite modifier.
+
 ** Improved X Window System support
 
 *** Emacs now supports using both X displays and ttys in one session.
--- a/src/ChangeLog	Wed Jul 16 19:14:01 2008 +0000
+++ b/src/ChangeLog	Wed Jul 16 19:23:49 2008 +0000
@@ -1,3 +1,17 @@
+2008-07-16  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* keymap.c: Remove all NS-specific code.
+	(where_is_preferred_modifier, Vwhere_is_preferred_modifier): New vars.
+	(preferred_sequence_p): Rename from ascii_sequence_p; pay attention to
+	where_is_preferred_modifier, return a different value depending on how
+	preferred is the binding.
+	(where_is_internal): Adjust accordingly.
+	(Fwhere_is_internal): Refresh where_is_preferred_modifier.
+	Adjust to new preferred_sequence_p.
+	(syms_of_keymap): Declare `where-is-preferred-modifier'.
+	* keyboard.c (parse_solitary_modifier): Not static any more.
+	* keyboard.h (parse_solitary_modifier): Declare.
+
 2008-07-16  Andreas Schwab  <schwab@suse.de>
 
 	* Makefile.in (SOME_MACHINE_LISP): Remove easy-mmode, fix spelling
--- a/src/keyboard.c	Wed Jul 16 19:14:01 2008 +0000
+++ b/src/keyboard.c	Wed Jul 16 19:23:49 2008 +0000
@@ -637,8 +637,6 @@
 					    Lisp_Object, char **,
 					    Lisp_Object *, unsigned));
 static Lisp_Object make_lispy_switch_frame P_ ((Lisp_Object));
-static int parse_solitary_modifier P_ ((Lisp_Object));
-static int parse_solitary_modifier ();
 static void save_getcjmp P_ ((jmp_buf));
 static void save_getcjmp ();
 static void restore_getcjmp P_ ((jmp_buf));
@@ -6828,9 +6826,8 @@
 /* Try to recognize SYMBOL as a modifier name.
    Return the modifier flag bit, or 0 if not recognized.  */
 
-static int
-parse_solitary_modifier (symbol)
-     Lisp_Object symbol;
+int
+parse_solitary_modifier (Lisp_Object symbol)
 {
   Lisp_Object name = SYMBOL_NAME (symbol);
 
--- a/src/keyboard.h	Wed Jul 16 19:14:01 2008 +0000
+++ b/src/keyboard.h	Wed Jul 16 19:23:49 2008 +0000
@@ -438,6 +438,7 @@
 extern Lisp_Object reorder_modifiers P_ ((Lisp_Object));
 extern Lisp_Object read_char P_ ((int, int, Lisp_Object *, Lisp_Object,
 				  int *, EMACS_TIME *));
+extern int parse_solitary_modifier (Lisp_Object symbol);
 
 
 /* Parent keymap of terminal-local function-key-map instances.  */
--- a/src/keymap.c	Wed Jul 16 19:14:01 2008 +0000
+++ b/src/keymap.c	Wed Jul 16 19:23:49 2008 +0000
@@ -111,10 +111,6 @@
 
 extern Lisp_Object Voverriding_local_map;
 
-#ifdef HAVE_NS
-extern Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
-#endif
-
 /* Hash table used to cache a reverse-map to speed up calls to where-is.  */
 static Lisp_Object where_is_cache;
 /* Which keymaps are reverse-stored in the cache.  */
@@ -2601,14 +2597,18 @@
   return build_string (str);
 }
 
-/* Return non-zero if SEQ contains only ASCII characters, perhaps with
-   a meta bit.  */
+static int where_is_preferred_modifier;
+
+/* Return 0 if SEQ uses non-preferred modifiers or non-char events.
+   Else, return 2 if SEQ uses the where_is_preferred_modifier,
+   and 1 otherwise.  */
 static int
-ascii_sequence_p (seq)
+preferred_sequence_p (seq)
      Lisp_Object seq;
 {
   int i;
   int len = XINT (Flength (seq));
+  int result = 1;
 
   for (i = 0; i < len; i++)
     {
@@ -2617,49 +2617,21 @@
       XSETFASTINT (ii, i);
       elt = Faref (seq, ii);
 
-      if (!INTEGERP (elt)
-	  || (XUINT (elt) & ~CHAR_META) >= 0x80)
+      if (!INTEGERP (elt))
 	return 0;
+      else
+	{
+	  int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
+	  if (modifiers == where_is_preferred_modifier)
+	    result = 2;
+	  else if (modifiers)
+	    return 0;
+	}
     }
 
-  return 1;
+  return result;
 }
 
-#ifdef HAVE_NS
-int lisp_to_mod(Lisp_Object lmod)
-/* -------------------------------------------------------------------------
-     Convert lisp symbol to emacs modifier code.
-   ------------------------------------------------------------------------- */
-{
-  if (EQ(lmod, Qmeta))
-    return meta_modifier;
-  else if (EQ(lmod, Qsuper))
-    return super_modifier;
-  else if (EQ(lmod, Qcontrol))
-    return ctrl_modifier;
-  else if (EQ(lmod, Qalt))
-    return alt_modifier;
-  else if (EQ(lmod, Qhyper))
-    return hyper_modifier;
-  return 0;
-}
-
-/* Return non-zero if SEQ starts w/a char modified by given modifier only. */
-static int
-modifier_sequence_p (Lisp_Object seq, Lisp_Object modifier)
-{
-  Lisp_Object idx, elt;
-
-  if (XINT (Flength (seq)) == 0)
-    return 0;
-  XSETFASTINT(idx, 0);
-  elt = Faref(seq, idx);
-
-  return  (XUINT(elt) & (CHAR_MODIFIER_MASK ^ shift_modifier))
-    == lisp_to_mod(modifier);
-}
-#endif
-
 
 /* where-is - finding a command in a set of keymaps.			*/
 
@@ -2751,7 +2723,7 @@
       last_is_meta = (XINT (last) >= 0
 		      && EQ (Faref (this, last), meta_prefix_char));
 
-      /* if (nomenus && !ascii_sequence_p (this)) */
+      /* if (nomenus && !preferred_sequence_p (this)) */
       if (nomenus && XINT (last) >= 0
 	  && SYMBOLP (tem = Faref (this, make_number (0)))
 	  && !NILP (Fmemq (XCAR (parse_modifiers (tem)), Vmouse_events)))
@@ -2842,15 +2814,7 @@
 	     we find.  */
 	  if (EQ (firstonly, Qnon_ascii))
 	    RETURN_UNGCPRO (sequence);
-#ifdef HAVE_NS
-          /* respond to modifier preference */
-          else if ((EQ (firstonly, Qalt) || EQ (firstonly, Qcontrol)
-                    || EQ (firstonly, Qhyper) || EQ (firstonly, Qmeta)
-                    || EQ (firstonly, Qsuper)))
-            if (modifier_sequence_p(sequence, firstonly))
-              RETURN_UNGCPRO (sequence);
-#endif
-	  else if (!NILP (firstonly) && ascii_sequence_p (sequence))
+	  else if (!NILP (firstonly) && 2 == preferred_sequence_p (sequence))
 	    RETURN_UNGCPRO (sequence);
 
 	  if (CONSP (remapped))
@@ -2869,12 +2833,25 @@
   /* firstonly may have been t, but we may have gone all the way through
      the keymaps without finding an all-ASCII key sequence.  So just
      return the best we could find.  */
-  if (!NILP (firstonly))
+  if (NILP (firstonly))
+    return found;
+  else if (where_is_preferred_modifier == 0)
     return Fcar (found);
-
-  return found;
+  else
+    { /* Maybe we did not find a preferred_modifier binding, but we did find
+	 some ASCII binding.  */
+      Lisp_Object bindings = found;
+      while (CONSP (bindings))
+	if (preferred_sequence_p (XCAR (bindings)))
+	  return XCAR (bindings);
+	else
+	  bindings = XCDR (bindings);
+      return Fcar (found);
+    }
 }
 
+static Lisp_Object Vwhere_is_preferred_modifier;
+
 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
        doc: /* Return list of keys that invoke DEFINITION.
 If KEYMAP is a keymap, search only KEYMAP and the global keymap.
@@ -2883,13 +2860,10 @@
 
 If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,
 rather than a list of all possible key sequences.
-#ifdef HAVE_NS
-If FIRSTONLY is the symbol for a modifier key, return the first binding found,
-that is modified by that modifier only.
-#endif
 If FIRSTONLY is the symbol `non-ascii', return the first binding found,
 no matter what it is.
-If FIRSTONLY has another non-nil value, prefer sequences of ASCII characters
+If FIRSTONLY has another non-nil value, prefer bindings
+that use the modifier key specified in `where-is-preferred-modifier'
 \(or their meta variants) and entirely reject menu bindings.
 
 If optional 4th arg NOINDIRECT is non-nil, don't follow indirections
@@ -2908,6 +2882,10 @@
   int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii);
   Lisp_Object result;
 
+  /* Refresh the C version of the modifier preference.  */
+  where_is_preferred_modifier
+    = parse_solitary_modifier (Vwhere_is_preferred_modifier);
+
   /* Find the relevant keymaps.  */
   if (CONSP (keymap) && KEYMAPP (XCAR (keymap)))
     keymaps = keymap;
@@ -2921,7 +2899,7 @@
   if (nomenus && NILP (noindirect) && NILP (keymap))
     {
       Lisp_Object *defns;
-      int i, j, n;
+      int i, n;
       struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
       /* Check heuristic-consistency of the cache.  */
@@ -2956,26 +2934,23 @@
 	 the following can GC.  */
       GCPRO2 (definition, keymaps);
       result = Qnil;
-      j = -1;
-      for (i = n - 1; i >= 0; --i)
-	if (EQ (shadow_lookup (keymaps, defns[i], Qnil), definition))
+      {
+	int best_pref = -1;
+	int j = -1;
+	for (i = n - 1; i >= 0; --i)
 	  {
-#ifdef HAVE_NS
-            if ((EQ (firstonly, Qalt) || EQ (firstonly, Qcontrol)
-                 || EQ (firstonly, Qhyper) || EQ (firstonly, Qmeta)
-                 || EQ (firstonly, Qsuper))
-                && modifier_sequence_p(defns[i], firstonly))
-              break;
-            else if (EQ (firstonly, Qt) && ascii_sequence_p (defns[i]))
-#else
-              if (ascii_sequence_p (defns[i]))
-#endif
-                break;
-              else if (j < 0)
-                j = i;
+	    int pref = preferred_sequence_p (defns[i]);
+	    if (pref > best_pref
+		&& EQ (shadow_lookup (keymaps, defns[i], Qnil), definition))
+	      {
+		j = i;
+		best_pref = pref;
+		if (best_pref == 2)
+		  break;
+	      }
 	  }
-
-      result = i >= 0 ? defns[i] : (j >= 0 ? defns[j] : Qnil);
+	result = j >= 0 ? defns[j] : Qnil;
+      }
       UNGCPRO;
     }
   else
@@ -3155,7 +3130,7 @@
 	  char *title, *p;
 
 	  if (!SYMBOLP (modes[i]))
-	    abort();
+	    abort ();
 
 	  p = title = (char *) alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
 	  *p++ = '\f';
@@ -4027,6 +4002,15 @@
 `minor-mode-map-alist' and `minor-mode-overriding-map-alist'.  */);
   Vemulation_mode_map_alists = Qnil;
 
+  DEFVAR_LISP ("where-is-preferred-modifier", &Vwhere_is_preferred_modifier,
+	       doc: /* Preferred modifier to use for `where-is'.
+When a single binding is requested, `where-is' will return one that
+uses this modifier if possible.  If nil, or if no such binding exists,
+bindings using keys without modifiers (or only with meta) will be
+preferred.  */);
+  Vwhere_is_preferred_modifier = Qnil;
+  where_is_preferred_modifier = 0;
+
   staticpro (&Vmouse_events);
   Vmouse_events = Fcons (intern ("menu-bar"),
 		  Fcons (intern ("tool-bar"),
@@ -4103,7 +4087,7 @@
 keys_of_keymap ()
 {
   initial_define_key (global_map, 033, "ESC-prefix");
-  initial_define_key (global_map, Ctl('X'), "Control-X-prefix");
+  initial_define_key (global_map, Ctl ('X'), "Control-X-prefix");
 }
 
 /* arch-tag: 6dd15c26-7cf1-41c4-b904-f42f7ddda463