Index: src/keymap.h =================================================================== RCS file: /sources/emacs/emacs/src/keymap.h,v retrieving revision 1.14 diff -u -r1.14 keymap.h *** src/keymap.h 6 Feb 2006 15:23:21 -0000 1.14 --- src/keymap.h 13 Sep 2006 08:02:42 -0000 *************** *** 29,36 **** EXFUN (Fkeymap_prompt, 1); EXFUN (Fdefine_key, 3); EXFUN (Flookup_key, 3); ! EXFUN (Fcommand_remapping, 1); ! EXFUN (Fkey_binding, 3); EXFUN (Fkey_description, 2); EXFUN (Fsingle_key_description, 2); EXFUN (Fwhere_is_internal, 5); --- 29,36 ---- EXFUN (Fkeymap_prompt, 1); EXFUN (Fdefine_key, 3); EXFUN (Flookup_key, 3); ! EXFUN (Fcommand_remapping, 2); ! EXFUN (Fkey_binding, 4); EXFUN (Fkey_description, 2); EXFUN (Fsingle_key_description, 2); EXFUN (Fwhere_is_internal, 5); Index: src/keymap.c =================================================================== RCS file: /sources/emacs/emacs/src/keymap.c,v retrieving revision 1.333 diff -u -r1.333 keymap.c *** src/keymap.c 11 Sep 2006 13:03:40 -0000 1.333 --- src/keymap.c 13 Sep 2006 08:02:44 -0000 *************** *** 28,33 **** --- 28,34 ---- #include "buffer.h" #include "charset.h" #include "keyboard.h" + #include "window.h" #include "termhooks.h" #include "blockinput.h" #include "puresize.h" *************** *** 1216,1232 **** /* This function may GC (it calls Fkey_binding). */ ! DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 1, 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; { if (!SYMBOLP (command)) return Qnil; ASET (command_remapping_vector, 1, command); ! return Fkey_binding (command_remapping_vector, Qnil, Qt); } /* Value is number if KEY is too long; nil if valid but has no definition. */ --- 1217,1236 ---- /* This function may GC (it calls Fkey_binding). */ ! 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). ! ! If optional argument LOCATION is a mouse event based key sequence, ! the remapping occurs in the keymaps corresponding to the click. */) ! (command, location) ! Lisp_Object command, location; { if (!SYMBOLP (command)) return Qnil; ASET (command_remapping_vector, 1, command); ! return Fkey_binding (command_remapping_vector, Qnil, Qt, location); } /* Value is number if KEY is too long; nil if valid but has no definition. */ *************** *** 1552,1558 **** /* GC is possible in this function if it autoloads a keymap. */ ! DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 3, 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. --- 1556,1562 ---- /* GC is possible in this function if it autoloads a keymap. */ ! 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,1620 **** 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; { ! Lisp_Object *maps, value; int nmaps, i; ! struct gcpro gcpro1; ! GCPRO1 (key); ! #ifdef HAVE_MOUSE ! if (VECTORP (key) && ASIZE (key) > 0) { ! 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; ! object = Fnth (make_number(4), pos); ! 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 (!NILP (Fkeymapp (map))) { ! value = Flookup_key (map, key, accept_default); ! if (! NILP (value) && !INTEGERP (value)) ! goto done; } } } ! #endif /* HAVE_MOUSE */ ! ! 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)) { value = Flookup_key (Voverriding_local_map, key, accept_default); if (! NILP (value) && !INTEGERP (value)) --- 1570,1663 ---- 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. ! ! 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 LOCATION is non-nil, it ! will used in place of KEY for determining mouse-dependent keymaps, but ! it will still be KEY that is looked up. ! */) ! (key, accept_default, no_remap, location) ! Lisp_Object key, accept_default, no_remap, location; { ! Lisp_Object *maps, value, event; int nmaps, i; ! struct gcpro gcpro1, gcpro2; ! int count = SPECPDL_INDEX (); ! ! GCPRO2 (key, location); ! if (NILP (location)) ! location = key; ! if (VECTORP(location) && ASIZE(location) > 0) { ! /* mouse events may have a symbolic prefix indicating the ! scrollbar or mode line */ ! if (SYMBOLP (AREF(location,0)) && ASIZE(location) > 1) ! event = AREF(location,1); ! else ! event = AREF(location,0); ! /* We are not interested in locations without event data */ ! if (! EVENT_HAS_PARAMETERS (event)) ! event = Qnil; ! } ! else ! event = Qnil; ! /* 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 (! NILP (event)) ! { ! Lisp_Object kind; ! Lisp_Object string; ! ! kind = EVENT_HEAD_KIND (EVENT_HEAD (event)); ! if (EQ (kind, Qmouse_click)) ! { ! Lisp_Object window, posn; ! ! window = POSN_WINDOW (EVENT_START (event)); ! posn = POSN_POSN (EVENT_START (event)); ! ! /* Key sequences beginning with mouse clicks are ! read using the keymaps in the buffer clicked on, ! not the current buffer. If we're at the ! beginning of a key sequence, switch buffers. */ ! 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 reading the key sequence. Note that we can't ! use save_excursion_{save,restore} here, because they ! save point as well as the current buffer; we don't ! want to save point, because redisplay may change it, ! to accommodate a Fset_window_start or something. ! */ ! ! 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)) { value = Flookup_key (Voverriding_local_map, key, accept_default); if (! NILP (value) && !INTEGERP (value)) *************** *** 1622,1633 **** } else { ! Lisp_Object local; ! local = get_local_map (PT, current_buffer, Qkeymap); ! if (! NILP (local)) { ! value = Flookup_key (local, key, accept_default); if (! NILP (value) && !INTEGERP (value)) goto done; } --- 1665,1744 ---- } else { ! Lisp_Object keymap, local_map; ! local_map = get_local_map (PT, current_buffer, Qlocal_map); ! keymap = get_local_map (PT, current_buffer, Qkeymap); ! ! if (! NILP(event)) ! { ! Lisp_Object kind; ! Lisp_Object string; ! ! kind = EVENT_HEAD_KIND (EVENT_HEAD (event)); ! if (EQ (kind, Qmouse_click)) ! { ! Lisp_Object window, posn; ! ! window = POSN_WINDOW (EVENT_START (event)); ! posn = POSN_POSN (EVENT_START (event)); ! ! /* For a mouse click, get the local text-property keymap ! of the place clicked on, rather than point. */ ! ! if (CONSP (XCDR (event))) ! { ! Lisp_Object start, pos; ! ! start = EVENT_START (event); ! ! if (CONSP (start) && POSN_INBUFFER_P (start)) ! { ! pos = POSN_BUFFER_POSN (start); ! 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 (EVENT_START (event)), ! (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,1653 **** goto done; } ! local = get_local_map (PT, current_buffer, Qlocal_map); ! if (! NILP (local)) { ! value = Flookup_key (local, key, accept_default); if (! NILP (value) && !INTEGERP (value)) goto done; } --- 1755,1763 ---- goto done; } ! if (! NILP (local_map)) { ! value = Flookup_key (local_map, key, accept_default); if (! NILP (value) && !INTEGERP (value)) goto done; } *************** *** 1656,1661 **** --- 1766,1773 ---- value = Flookup_key (current_global_map, key, accept_default); done: + unbind_to (count, Qnil); + UNGCPRO; if (NILP (value) || INTEGERP (value)) return Qnil; *************** *** 1666,1672 **** if (NILP (no_remap) && SYMBOLP (value)) { Lisp_Object value1; ! if (value1 = Fcommand_remapping (value), !NILP (value1)) value = value1; } --- 1778,1784 ---- if (NILP (no_remap) && SYMBOLP (value)) { Lisp_Object value1; ! if (value1 = Fcommand_remapping (value, location), !NILP (value1)) value = value1; } *************** *** 2467,2473 **** if (NILP (no_remap) && SYMBOLP (definition)) { Lisp_Object tem; ! if (tem = Fcommand_remapping (definition), !NILP (tem)) return Qnil; } --- 2579,2585 ---- if (NILP (no_remap) && SYMBOLP (definition)) { Lisp_Object tem; ! if (tem = Fcommand_remapping (definition, Qnil), !NILP (tem)) return Qnil; } Index: src/keyboard.c =================================================================== RCS file: /sources/emacs/emacs/src/keyboard.c,v retrieving revision 1.875 diff -u -r1.875 keyboard.c *** src/keyboard.c 10 Sep 2006 21:10:50 -0000 1.875 --- src/keyboard.c 13 Sep 2006 08:02:56 -0000 *************** *** 1674,1680 **** if (SYMBOLP (cmd)) { Lisp_Object cmd1; ! if (cmd1 = Fcommand_remapping (cmd), !NILP (cmd1)) cmd = cmd1; } --- 1674,1680 ---- if (SYMBOLP (cmd)) { Lisp_Object cmd1; ! if (cmd1 = Fcommand_remapping (cmd, Qnil), !NILP (cmd1)) cmd = cmd1; } *************** *** 7516,7522 **** Lisp_Object prefix; if (!NILP (tem)) ! tem = Fkey_binding (tem, Qnil, Qnil); prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ); if (CONSP (prefix)) --- 7516,7522 ---- Lisp_Object prefix; if (!NILP (tem)) ! tem = Fkey_binding (tem, Qnil, Qnil, Qnil); prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ); if (CONSP (prefix)) *************** *** 9125,9140 **** if (!EQ (map_here, orig_local_map)) { orig_local_map = map_here; ! keybuf[t] = key; ! mock_input = t + 1; ! ! goto replay_sequence; } map_here = get_local_map (XINT (pos), current_buffer, Qkeymap); if (!EQ (map_here, orig_keymap)) { orig_keymap = map_here; keybuf[t] = key; mock_input = t + 1; --- 9125,9143 ---- if (!EQ (map_here, orig_local_map)) { orig_local_map = map_here; ! ++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: src/ChangeLog =================================================================== RCS file: /sources/emacs/emacs/src/ChangeLog,v retrieving revision 1.5293 diff -u -r1.5293 ChangeLog *** src/ChangeLog 12 Sep 2006 16:47:50 -0000 1.5293 --- src/ChangeLog 13 Sep 2006 08:03:25 -0000 *************** *** 1,3 **** --- 1,22 ---- + 2006-09-13 David Kastrup + + * keymap.c: include "window.h". + (Fcommand_remapping): New optional LOCATION argument. + (Fkey_binding): New optional LOCATION argument. Completely rework + handling of mouse clicks to get the same order of keymaps as + `read-key-sequence' and heed LOCATION. 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 location, heed both. + + * keymap.h: Declare additional optional arguments of + `Fcommand_remapping and `Fkey_binding'. + 2006-09-12 Stefan Monnier * textprop.c (Fnext_property_change, Fnext_single_property_change)