summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kastrup <dak@gnu.org>2006-09-15 07:19:15 +0000
committerDavid Kastrup <dak@gnu.org>2006-09-15 07:19:15 +0000
commitb74e16a384ddbded12eb7e8c7250253614554641 (patch)
tree287d09b973259b6101ae03baec0e0c91c848232a
parent6266eb4a51f75b4e31895cd8d8be1ddd5a18e076 (diff)
downloademacs-b74e16a384ddbded12eb7e8c7250253614554641.tar.gz
* NEWS: explain new behavior and arguments of `key-binding' and
`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'.
-rw-r--r--etc/ChangeLog7
-rw-r--r--etc/NEWS6
-rw-r--r--lispref/ChangeLog12
-rw-r--r--lispref/keymaps.texi55
-rw-r--r--src/ChangeLog22
-rw-r--r--src/Makefile.in3
-rw-r--r--src/keyboard.c15
-rw-r--r--src/keymap.c193
-rw-r--r--src/keymap.h4
9 files changed, 240 insertions, 77 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog
index e236643da10..e1daf63475b 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -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
@@ -102,7 +107,7 @@
* PROBLEMS: Emacs now requires ws2_32.dll on Windows.
-2006-07-14 K,Aa(Broly L,Bu(Brentey <lorentey@elte.hu>
+2006-07-14 K,Aa(Broly L$,1 q(Brentey <lorentey@elte.hu>
* HELLO: Update Hungarian sample.
diff --git a/etc/NEWS b/etc/NEWS
index 0e19f64720f..59048b8ff8a 100644
--- 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
diff --git a/lispref/ChangeLog b/lispref/ChangeLog
index c6c968bdb34..7b32595083f 100644
--- a/lispref/ChangeLog
+++ b/lispref/ChangeLog
@@ -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.
@@ -4871,7 +4881,7 @@
(info): Add target.
(installall): Target removed.
-2001-10-31 Pavel Jan,Bm(Bk <Pavel@Janik.cz>
+2001-10-31 Pavel Jan,Am(Bk <Pavel@Janik.cz>
* tips.texi (Coding Conventions): Fix typo.
diff --git a/lispref/keymaps.texi b/lispref/keymaps.texi
index 2e38514c00d..309664c38dd 100644
--- a/lispref/keymaps.texi
+++ b/lispref/keymaps.texi
@@ -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
diff --git a/src/ChangeLog b/src/ChangeLog
index fbd2e8e38be..b6bbcb8401b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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.
diff --git a/src/Makefile.in b/src/Makefile.in
index 0924e9df52b..af4cb816e18 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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)
diff --git a/src/keyboard.c b/src/keyboard.c
index d6a74cf2196..8518bcb98c1 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -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;
diff --git a/src/keymap.c b/src/keymap.c
index 8b99231a91d..45bcba9a5fc 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -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;
}
diff --git a/src/keymap.h b/src/keymap.h
index cbd14cf9ba4..b11f630a1fb 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -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);