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. */
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++)
{
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. */
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)))
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))
/* 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.
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
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;
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. */
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
char *title, *p;
if (!SYMBOLP (modes[i]))
- abort();
+ abort ();
p = title = (char *) alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
*p++ = '\f';
`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"),
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