* keymap.c: Remove all NS-specific code.
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 16 Jul 2008 19:23:49 +0000 (19:23 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Wed, 16 Jul 2008 19:23:49 +0000 (19:23 +0000)
(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.

etc/NEWS
src/ChangeLog
src/keyboard.c
src/keyboard.h
src/keymap.c

index fcaa7e2..da7f823 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -83,6 +83,8 @@ The Emacs 22 icon is available as `emacs22.png' in the same location.
 \f
 * 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.
index 0eb8fc0..8dffef4 100644 (file)
@@ -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
index 0ae24b7..219b42c 100644 (file)
@@ -637,8 +637,6 @@ static Lisp_Object modify_event_symbol P_ ((int, unsigned, Lisp_Object,
                                            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 @@ has the same base event type and all the specified modifiers.  */)
 /* 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);
 
index e217662..afdcd9d 100644 (file)
@@ -438,6 +438,7 @@ extern Lisp_Object parse_modifiers P_ ((Lisp_Object));
 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.  */
index 545ab3d..4b8c5cc 100644 (file)
@@ -111,10 +111,6 @@ extern Lisp_Object meta_prefix_char;
 
 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 @@ See Info node `(elisp)Describing Characters' for examples.  */)
   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 @@ ascii_sequence_p (seq)
       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;
-}
-
-#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 result;
 }
 
-/* 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
-
 \f
 /* where-is - finding a command in a set of keymaps.                   */
 
@@ -2751,7 +2723,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
       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 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
             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 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
   /* 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 KEYMAP is a list of keymaps, search only those keymaps.
 
 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 @@ remapped command in the returned list.  */)
   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 @@ remapped command in the returned list.  */)
   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 @@ remapped command in the returned list.  */)
         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 @@ You type        Translation\n\
          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 @@ the same way.  The "active" keymaps in each alist are used before
 `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 @@ void
 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