* NEWS: explain new behavior and arguments of `key-binding' and
authorDavid Kastrup <dak@gnu.org>
Fri, 15 Sep 2006 07:19:15 +0000 (07:19 +0000)
committerDavid Kastrup <dak@gnu.org>
Fri, 15 Sep 2006 07:19:15 +0000 (07:19 +0000)
`command-remapping'.

* keymaps.texi (Active Keymaps): Adapt description to use
`get-char-property' instead `get-text-property'.  Explain how
mouse events change this.  Explain the new optional argument of
`key-binding' and its mouse-dependent lookup.
(Searching Keymaps): Adapt description similarly.  Explain the new
optional argument of `command-remapping'.

* Makefile.in (keymap.o): Add "keymap.h" and "window.h"
dependencies.

* keymap.c: include "window.h".
(Fcommand_remapping): New optional POSITION argument.
(Fkey_binding): New optional POSITION argument.  Completely rework
handling of mouse clicks to get the same order of keymaps as
`read-key-sequence' and heed POSITION.  Also temporarily switch
buffers to location of mouse click and back.

* keyboard.c (command_loop_1): Adjust call of `Fcommand_remapping'
for additional argument.
(parse_menu_item): Adjust call of `Fkey_binding' for additional
argument.
(read_key_sequence): If there are both `local-map' and `keymap'
text properties at some buffer position, heed both.

* keymap.h: Declare additional optional arguments of
`Fcommand_remapping' and `Fkey_binding'.

etc/ChangeLog
etc/NEWS
lispref/ChangeLog
lispref/keymaps.texi
src/ChangeLog
src/Makefile.in
src/keyboard.c
src/keymap.c
src/keymap.h

index e236643..e1daf63 100644 (file)
@@ -1,3 +1,8 @@
+2006-09-15  David Kastrup  <dak@gnu.org>
+
+       * NEWS: explain new behavior and arguments of `key-binding' and
+       `command-remapping'.
+
 2006-09-11  Paul Eggert  <eggert@cs.ucla.edu>
 
        * NEWS: In terminal-oriented subshells, the EMACS environment
 
        * PROBLEMS: Emacs now requires ws2_32.dll on Windows.
 
-2006-07-14  K\e,Aa\e(Broly L\e,Bu\e(Brentey  <lorentey@elte.hu>
+2006-07-14  K\e,Aa\e(Broly L\e$,1 q\e(Brentey  <lorentey@elte.hu>
 
        * HELLO: Update Hungarian sample.
 
index 0e19f64..59048b8 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -4681,6 +4681,12 @@ over minor mode keymaps.
 text properties, according to their stickiness.  This also means that it
 works with empty overlays.  The same hold for the `local-map' property.
 
+*** `key-binding' will now look up mouse-specific bindings.  The
+keymaps consulted by `key-binding' will get adapted if the key
+sequence is started with a mouse event.  Instead of letting the click
+position be determined from the key sequence itself, it is also
+possible to specify it with an optional argument explicitly.
+
 *** Dense keymaps now handle inheritance correctly.
 
 Previously a dense keymap would hide all of the simple-char key
index c6c968b..7b32595 100644 (file)
@@ -1,3 +1,12 @@
+2006-09-15  David Kastrup  <dak@gnu.org>
+
+       * keymaps.texi (Active Keymaps): Adapt description to use
+       `get-char-property' instead `get-text-property'.  Explain how
+       mouse events change this.  Explain the new optional argument of
+       `key-binding' and its mouse-dependent lookup.
+       (Searching Keymaps): Adapt description similarly.  Explain the new
+       optional argument of `command-remapping'.
+
 2006-09-14  Richard Stallman  <rms@gnu.org>
 
        * keymaps.texi (Searching Keymaps): Clarification.
@@ -10,6 +19,7 @@
        (Basic Char Syntax, General Escape Syntax)
        (Ctl-Char Syntax, Meta-Char Syntax): New subnodes.
 
+>>>>>>> 1.751
 2006-09-11  Richard Stallman  <rms@gnu.org>
 
        * display.texi (Display Table Format): Wording clarification.
        (info): Add target.
        (installall): Target removed.
 
-2001-10-31  Pavel Jan\e,Bm\e(Bk  <Pavel@Janik.cz>
+2001-10-31  Pavel Jan\e,Am\e(Bk  <Pavel@Janik.cz>
 
        * tips.texi (Coding Conventions): Fix typo.
 
index 2e38514..309664c 100644 (file)
@@ -576,6 +576,16 @@ keymap, and the global keymap, in that order.  Emacs searches for each
 input key sequence in all these keymaps.  @xref{Searching Keymaps},
 for more details of this procedure.
 
+This process is somewhat modified for mouse events: the local modes and
+keymaps of the buffer corresponding to the mouse click position are
+searched instead, text properties are taken from the mouse click
+position in the buffer rather than point, and if the click happens on a
+string embedded with a @code{display}, @code{before-string}, or
+@code{after-string} text property (@pxref{Special Properties}) or
+overlay property (@pxref{Overlay Properties}), any non-@code{nil} maps
+specified with text properties of this string are searched instead of
+those of the buffer.
+
   The @dfn{global keymap} holds the bindings of keys that are defined
 regardless of the current buffer, such as @kbd{C-f}.  The variable
 @code{global-map} holds this keymap, which is always active.
@@ -632,25 +642,27 @@ Normally it ignores @code{overriding-local-map} and
 non-@code{nil} then it pays attention to them.
 @end defun
 
-@defun key-binding key &optional accept-defaults no-remap
-This function returns the binding for @var{key} according to the
-current active keymaps.  The result is @code{nil} if @var{key} is
-undefined in the keymaps.
+@defun key-binding key &optional accept-defaults no-remap position
+This function returns the binding for @var{key} according to the current
+active keymaps.  The result is @code{nil} if @var{key} is undefined in
+the keymaps.  If @var{key} is a key sequence started with the mouse, the
+consulted maps will be changed accordingly.
 
 @c Emacs 19 feature
 The argument @var{accept-defaults} controls checking for default
 bindings, as in @code{lookup-key} (above).
 
-When @var{key} is a vector containing an input event, such as a mouse
-click, @code{key-binding} first looks for the binding in the keymaps
-that would be active at the position where the click was done.
-
 When commands are remapped (@pxref{Remapping Commands}),
 @code{key-binding} normally processes command remappings so as to
 returns the remapped command that will actually be executed.  However,
 if @var{no-remap} is non-@code{nil}, @code{key-binding} ignores
 remappings and returns the binding directly specified for @var{key}.
 
+If @var{position} is non-@code{nil}, it specifies either a buffer
+position or a position like those returned from @code{event-start}.  In
+this case, @var{position} instead of @var{key} determines the
+click-specific maps.
+
 An error is signaled if @var{key} is not a string or a vector.
 
 @example
@@ -674,21 +686,24 @@ them:
         (@var{find-in} overriding-terminal-local-map)
       (if overriding-local-map
           (@var{find-in} overriding-local-map)
-        (or (@var{find-in} (get-text-property (point) 'keymap))
+        (or (@var{find-in} (get-char-property (point) 'keymap))
             (@var{find-in-any} emulation-mode-map-alists)
             (@var{find-in-any} minor-mode-overriding-map-alist)
             (@var{find-in-any} minor-mode-map-alist)
             (if (get-text-property (point) 'local-map)
-                (@var{find-in} (get-text-property (point) 'local-map))
+                (@var{find-in} (get-char-property (point) 'local-map))
               (@var{find-in} (current-local-map))))))
     (@var{find-in} (current-global-map)))
 @end lisp
 
 @noindent
-The @var{find-in} and @var{find-in-any} are pseudo functions that
-search in one keymap and in an alist of keymaps, respectively.
-(Searching a single keymap for a binding is called @dfn{key lookup};
-see @ref{Key Lookup}.)
+The @var{find-in} and @var{find-in-any} are pseudo functions that search
+in one keymap and in an alist of keymaps, respectively.  (Searching a
+single keymap for a binding is called @dfn{key lookup}; see @ref{Key
+Lookup}.)  Mouse events on strings will use text properties from the
+string if non-@code{nil} instead of the buffer.  Also, point and current
+buffer for mouse-based events are switched to correspond to the position
+of the event start while performing the lookup.
 
 @enumerate
 @item
@@ -1450,11 +1465,13 @@ does not have the effect of remapping @code{kill-line} into
 if an ordinary binding specifies @code{my-kill-line}, this keymap will
 remap it to @code{my-other-kill-line}.
 
-@defun command-remapping command
-This function returns the remapping for @var{command} (a symbol),
-given the current active keymaps.  If @var{command} is not remapped
-(which is the usual situation), or not a symbol, the function returns
-@code{nil}.
+@defun command-remapping command &optional position
+This function returns the remapping for @var{command} (a symbol), given
+the current active keymaps.  If @var{command} is not remapped (which is
+the usual situation), or not a symbol, the function returns @code{nil}.
+@code{position} can optionally specify a buffer position or a position
+like those returned from @code{event-start}: in that case, the active
+maps are changed like they are in @code{key-binding}.
 @end defun
 
 @node Translation Keymaps
index fbd2e8e..b6bbcb8 100644 (file)
@@ -1,3 +1,25 @@
+2006-09-15  David Kastrup  <dak@gnu.org>
+
+       * Makefile.in (keymap.o): Add "keymap.h" and "window.h"
+       dependencies.
+
+       * keymap.c: include "window.h".
+       (Fcommand_remapping): New optional POSITION argument.
+       (Fkey_binding): New optional POSITION argument.  Completely rework
+       handling of mouse clicks to get the same order of keymaps as
+       `read-key-sequence' and heed POSITION.  Also temporarily switch
+       buffers to location of mouse click and back.
+
+       * keyboard.c (command_loop_1): Adjust call of `Fcommand_remapping'
+       for additional argument.
+       (parse_menu_item): Adjust call of `Fkey_binding' for additional
+       argument.
+       (read_key_sequence): If there are both `local-map' and `keymap'
+       text properties at some buffer position, heed both.
+
+       * keymap.h: Declare additional optional arguments of
+       `Fcommand_remapping' and `Fkey_binding'.
+
 2006-09-15  Juanma Barranquero  <lekktu@gmail.com>
 
        * indent.c (Fcurrent_column, Findent_to): Fix typos in docstring.
index 0924e9d..af4cb81 100644 (file)
@@ -1146,7 +1146,8 @@ keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \
    systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
    atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
 keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
-   atimer.h systime.h puresize.h charset.h intervals.h $(config_h)
+   atimer.h systime.h puresize.h charset.h intervals.h keymap.h window.h \
+   $(config_h)
 lastfile.o: lastfile.c  $(config_h)
 macros.o: macros.c window.h buffer.h commands.h macros.h keyboard.h \
        dispextern.h $(config_h)
index d6a74cf..8518bcb 100644 (file)
@@ -1674,7 +1674,7 @@ command_loop_1 ()
       if (SYMBOLP (cmd))
        {
          Lisp_Object cmd1;
-         if (cmd1 = Fcommand_remapping (cmd), !NILP (cmd1))
+         if (cmd1 = Fcommand_remapping (cmd, Qnil), !NILP (cmd1))
            cmd = cmd1;
        }
 
@@ -7517,7 +7517,7 @@ parse_menu_item (item, notreal, inmenubar)
       Lisp_Object prefix;
 
       if (!NILP (tem))
-       tem = Fkey_binding (tem, Qnil, Qnil);
+       tem = Fkey_binding (tem, Qnil, Qnil, Qnil);
 
       prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
       if (CONSP (prefix))
@@ -9134,16 +9134,19 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
                          if (!EQ (map_here, orig_local_map))
                            {
                              orig_local_map = map_here;
-                             keybuf[t] = key;
-                             mock_input = t + 1;
-
-                             goto replay_sequence;
+                             ++localized_local_map;
                            }
+
                          map_here = get_local_map (XINT (pos),
                                                     current_buffer, Qkeymap);
                          if (!EQ (map_here, orig_keymap))
                            {
                              orig_keymap = map_here;
+                             ++localized_local_map;
+                           }
+
+                         if (localized_local_map > 1)
+                           {
                              keybuf[t] = key;
                              mock_input = t + 1;
 
index 8b99231..45bcba9 100644 (file)
@@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA.  */
 #include "puresize.h"
 #include "intervals.h"
 #include "keymap.h"
+#include "window.h"
 
 /* The number of elements in keymap vectors.  */
 #define DENSE_TABLE_SIZE (0200)
@@ -1216,17 +1217,23 @@ binding KEY to DEF is added at the front of KEYMAP.  */)
 
 /* This function may GC (it calls Fkey_binding).  */
 
-DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 1, 0,
+DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 2, 0,
        doc: /* Return the remapping for command COMMAND in current keymaps.
-Returns nil if COMMAND is not remapped (or not a symbol).  */)
-     (command)
-     Lisp_Object command;
+Returns nil if COMMAND is not remapped (or not a symbol).
+
+If the optional argument POSITION is non-nil, it specifies a mouse
+position as returned by `event-start' and `event-end', and the
+remapping occurs in the keymaps associated with it.  It can also be a
+number or marker, in which case the keymap properties at the specified
+buffer position instead of point are used. */)
+     (command, position)
+     Lisp_Object command, position;
 {
   if (!SYMBOLP (command))
     return Qnil;
 
   ASET (command_remapping_vector, 1, command);
-  return Fkey_binding (command_remapping_vector, Qnil, Qt);
+  return Fkey_binding (command_remapping_vector, Qnil, Qt, position);
 }
 
 /* Value is number if KEY is too long; nil if valid but has no definition. */
@@ -1552,7 +1559,7 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
 
 /* GC is possible in this function if it autoloads a keymap.  */
 
-DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 0,
+DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 4, 0,
        doc: /* Return the binding for command KEY in current keymaps.
 KEY is a string or vector, a sequence of keystrokes.
 The binding is probably a symbol with a function definition.
@@ -1566,55 +1573,86 @@ recognize the default bindings, just as `read-key-sequence' does.
 Like the normal command loop, `key-binding' will remap the command
 resulting from looking up KEY by looking up the command in the
 current keymaps.  However, if the optional third argument NO-REMAP
-is non-nil, `key-binding' returns the unmapped command.  */)
-     (key, accept_default, no_remap)
-     Lisp_Object key, accept_default, no_remap;
+is non-nil, `key-binding' returns the unmapped command.
+
+If KEY is a key sequence initiated with the mouse, the used keymaps
+will depend on the clicked mouse position with regard to the buffer
+and possible local keymaps on strings.
+
+If the optional argument POSITION is non-nil, it specifies a mouse
+position as returned by `event-start' and `event-end', and the lookup
+occurs in the keymaps associated with it instead of KEY.  It can also
+be a number or marker, in which case the keymap properties at the
+specified buffer position instead of point are used.
+  */)
+    (key, accept_default, no_remap, position)
+    Lisp_Object key, accept_default, no_remap, position;
 {
   Lisp_Object *maps, value;
   int nmaps, i;
-  struct gcpro gcpro1;
+  struct gcpro gcpro1, gcpro2;
+  int count = SPECPDL_INDEX ();
 
-  GCPRO1 (key);
+  GCPRO2 (key, position);
 
-#ifdef HAVE_MOUSE
-  if (VECTORP (key) && ASIZE (key) > 0)
+  if (NILP (position))
     {
-      Lisp_Object ev, pos;
-      if ((ev = AREF (key, 0), CONSP (ev))
-         && SYMBOLP (XCAR (ev))
-         && CONSP (XCDR (ev))
-         && (pos = XCAR (XCDR (ev)), CONSP (pos))
-         && XINT (Flength (pos)) == 10
-         && INTEGERP (XCAR (XCDR (pos))))
-       {
-         Lisp_Object map, object;
+      Lisp_Object event;
+      /* mouse events may have a symbolic prefix indicating the
+        scrollbar or mode line */
+      if (SYMBOLP (AREF (key, 0)) && ASIZE (key) > 1)
+       event = AREF (key, 1);
+      else
+       event = AREF (key, 0);
 
-         object = Fnth (make_number(4), pos);
+      /* We are not interested in locations without event data */
 
-         if (CONSP (object))
-           map = Fget_char_property (XCDR (object), Qkeymap, XCAR (object));
-         else
-           map = Fget_char_property (XCAR (XCDR (pos)), Qkeymap,
-                                     Fwindow_buffer (XCAR (pos)));
+      if (EVENT_HAS_PARAMETERS (event)) {
+       Lisp_Object kind;
 
-         if (!NILP (Fkeymapp (map)))
-           {
-             value = Flookup_key (map, key, accept_default);
-             if (! NILP (value) && !INTEGERP (value))
-               goto done;
-           }
-       }
+       kind = EVENT_HEAD_KIND (EVENT_HEAD (event));
+       if (EQ (kind, Qmouse_click))
+         position = EVENT_START (event);
+      }
     }
-#endif /* HAVE_MOUSE  */
 
-  if (!NILP (current_kboard->Voverriding_terminal_local_map))
+  /* Key sequences beginning with mouse clicks
+     are read using the keymaps of the buffer clicked on, not
+     the current buffer.  So we may have to switch the buffer
+     here. */
+  
+  if (CONSP (position))
+    {
+      Lisp_Object window;
+      
+      window = POSN_WINDOW (position);
+         
+      if (WINDOWP (window)
+         && BUFFERP (XWINDOW (window)->buffer)
+         && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+       {
+         /* Arrange to go back to the original buffer once we're done
+            processing the key sequence.  We don't use
+            save_excursion_{save,restore} here, in analogy to
+            `read-key-sequence' to avoid saving point.  Maybe this
+            would not be a problem here, but it is easier to keep
+            things the same.
+         */
+             
+         record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+         
+         set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+       }
+    }
+  
+  if (! NILP (current_kboard->Voverriding_terminal_local_map))
     {
       value = Flookup_key (current_kboard->Voverriding_terminal_local_map,
                           key, accept_default);
       if (! NILP (value) && !INTEGERP (value))
        goto done;
     }
-  else if (!NILP (Voverriding_local_map))
+  else if (! NILP (Voverriding_local_map))
     {
       value = Flookup_key (Voverriding_local_map, key, accept_default);
       if (! NILP (value) && !INTEGERP (value))
@@ -1622,12 +1660,72 @@ is non-nil, `key-binding' returns the unmapped command.  */)
     }
   else
     {
-      Lisp_Object local;
+      Lisp_Object keymap, local_map;
+      EMACS_INT pt;
 
-      local = get_local_map (PT, current_buffer, Qkeymap);
-      if (! NILP (local))
+      pt = INTEGERP (position) ? XINT (position)
+       : MARKERP (position) ? marker_position (position)
+       : PT;
+
+      local_map = get_local_map (pt, current_buffer, Qlocal_map); 
+      keymap = get_local_map (pt, current_buffer, Qkeymap); 
+
+      if (CONSP (position))
        {
-         value = Flookup_key (local, key, accept_default);
+         Lisp_Object string, window;
+
+         window = POSN_WINDOW (position);
+
+         /* For a mouse click, get the local text-property keymap
+            of the place clicked on, rather than point.  */
+         
+         if (POSN_INBUFFER_P (position))
+           {
+             Lisp_Object pos;
+
+             pos = POSN_BUFFER_POSN (position);
+             if (INTEGERP (pos)
+                 && XINT (pos) >= BEG && XINT (pos) <= Z)
+               {
+                 local_map = get_local_map (XINT (pos),
+                                            current_buffer, Qlocal_map);
+                 
+                 keymap = get_local_map (XINT (pos),
+                                         current_buffer, Qkeymap);
+               }
+           }
+
+         /* If on a mode line string with a local keymap,
+            or for a click on a string, i.e. overlay string or a
+            string displayed via the `display' property,
+            consider `local-map' and `keymap' properties of
+            that string.  */
+         
+         if (string = POSN_STRING (position),
+             (CONSP (string) && STRINGP (XCAR (string))))
+           {
+             Lisp_Object pos, map;
+             
+             pos = XCDR (string);
+             string = XCAR (string);
+             if (XINT (pos) >= 0
+                 && XINT (pos) < SCHARS (string))
+               {
+                 map = Fget_text_property (pos, Qlocal_map, string);
+                 if (!NILP (map))
+                   local_map = map;
+
+                 map = Fget_text_property (pos, Qkeymap, string);
+                 if (!NILP (map))
+                   keymap = map;
+               }
+           }
+         
+       }
+
+      if (! NILP (keymap))
+       {
+         value = Flookup_key (keymap, key, accept_default);
          if (! NILP (value) && !INTEGERP (value))
            goto done;
        }
@@ -1644,10 +1742,9 @@ is non-nil, `key-binding' returns the unmapped command.  */)
              goto done;
          }
 
-      local = get_local_map (PT, current_buffer, Qlocal_map);
-      if (! NILP (local))
+      if (! NILP (local_map))
        {
-         value = Flookup_key (local, key, accept_default);
+         value = Flookup_key (local_map, key, accept_default);
          if (! NILP (value) && !INTEGERP (value))
            goto done;
        }
@@ -1656,6 +1753,8 @@ is non-nil, `key-binding' returns the unmapped command.  */)
   value = Flookup_key (current_global_map, key, accept_default);
 
  done:
+  unbind_to (count, Qnil);
+
   UNGCPRO;
   if (NILP (value) || INTEGERP (value))
     return Qnil;
@@ -1666,7 +1765,7 @@ is non-nil, `key-binding' returns the unmapped command.  */)
   if (NILP (no_remap) && SYMBOLP (value))
     {
       Lisp_Object value1;
-      if (value1 = Fcommand_remapping (value), !NILP (value1))
+      if (value1 = Fcommand_remapping (value, position), !NILP (value1))
        value = value1;
     }
 
@@ -2467,7 +2566,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
   if (NILP (no_remap) && SYMBOLP (definition))
     {
       Lisp_Object tem;
-      if (tem = Fcommand_remapping (definition), !NILP (tem))
+      if (tem = Fcommand_remapping (definition, Qnil), !NILP (tem))
        return Qnil;
     }
 
index cbd14cf..b11f630 100644 (file)
@@ -29,8 +29,8 @@ EXFUN (Fmake_sparse_keymap, 1);
 EXFUN (Fkeymap_prompt, 1);
 EXFUN (Fdefine_key, 3);
 EXFUN (Flookup_key, 3);
-EXFUN (Fcommand_remapping, 1);
-EXFUN (Fkey_binding, 3);
+EXFUN (Fcommand_remapping, 2);
+EXFUN (Fkey_binding, 4);
 EXFUN (Fkey_description, 2);
 EXFUN (Fsingle_key_description, 2);
 EXFUN (Fwhere_is_internal, 5);