* systty.h: Remove code for Aix on 386, unsupported platform.
[bpt/emacs.git] / src / keymap.c
index 94d2ab5..545ab3d 100644 (file)
@@ -5,10 +5,10 @@
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
@@ -76,7 +74,7 @@ Lisp_Object Vminibuffer_local_filename_completion_map;
 
 /* keymap used for minibuffers when doing completion in filenames
    with require-match*/
-Lisp_Object Vminibuffer_local_must_match_filename_map;
+Lisp_Object Vminibuffer_local_filename_must_match_map;
 
 /* keymap used for minibuffers when doing completion and require a match */
 /* was MinibufLocalMustMatchMap */
@@ -113,6 +111,10 @@ 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.  */
@@ -563,9 +565,6 @@ access_keymap (map, idx, t_ok, noinherit, autoload)
 
     GCPRO4 (map, tail, idx, t_binding);
 
-    /* If `t_ok' is 2, both `t' is accepted.  */
-    t_ok = t_ok ? 2 : 0;
-
     for (tail = XCDR (map);
         (CONSP (tail)
          || (tail = get_keymap (tail, 0, autoload), CONSP (tail)));
@@ -587,10 +586,10 @@ access_keymap (map, idx, t_ok, noinherit, autoload)
 
            if (EQ (key, idx))
              val = XCDR (binding);
-           else if (t_ok > 1 && EQ (key, Qt))
+           else if (t_ok && EQ (key, Qt))
              {
                t_binding = XCDR (binding);
-               t_ok = 1;
+               t_ok = 0;
              }
          }
        else if (VECTORP (binding))
@@ -2626,6 +2625,41 @@ ascii_sequence_p (seq)
   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 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.                   */
 
@@ -2808,6 +2842,14 @@ 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))
            RETURN_UNGCPRO (sequence);
 
@@ -2841,6 +2883,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
@@ -2914,10 +2960,19 @@ remapped command in the returned list.  */)
       for (i = n - 1; i >= 0; --i)
        if (EQ (shadow_lookup (keymaps, defns[i], Qnil), definition))
          {
-           if (ascii_sequence_p (defns[i]))
-             break;
-           else if (j < 0)
-             j = 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;
          }
 
       result = i >= 0 ? defns[i] : (j >= 0 ? defns[j] : Qnil);
@@ -3941,11 +3996,11 @@ don't alter it yourself.  */);
   Fset_keymap_parent (Vminibuffer_local_must_match_map,
                      Vminibuffer_local_completion_map);
 
-  DEFVAR_LISP ("minibuffer-local-must-match-filename-map",
-              &Vminibuffer_local_must_match_filename_map,
+  DEFVAR_LISP ("minibuffer-local-filename-must-match-map",
+              &Vminibuffer_local_filename_must_match_map,
               doc: /* Local keymap for minibuffer input with completion for filenames with exact match.  */);
-  Vminibuffer_local_must_match_filename_map = Fmake_sparse_keymap (Qnil);
-  Fset_keymap_parent (Vminibuffer_local_must_match_filename_map,
+  Vminibuffer_local_filename_must_match_map = Fmake_sparse_keymap (Qnil);
+  Fset_keymap_parent (Vminibuffer_local_filename_must_match_map,
                      Vminibuffer_local_must_match_map);
 
   DEFVAR_LISP ("minor-mode-map-alist", &Vminor_mode_map_alist,