1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-12 16:23:57 +00:00

* 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'.
This commit is contained in:
David Kastrup 2006-09-15 07:19:15 +00:00
parent 6266eb4a51
commit b74e16a384
9 changed files with 242 additions and 79 deletions

View 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
@ -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.

View File

@ -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

View 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.
@ -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.

View 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

View 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.

View 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)

View 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;

View 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 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);
/* We are not interested in locations without event data */
if (EVENT_HAS_PARAMETERS (event)) {
Lisp_Object kind;
kind = EVENT_HEAD_KIND (EVENT_HEAD (event));
if (EQ (kind, Qmouse_click))
position = EVENT_START (event);
}
}
/* 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)
{
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;
}
/* 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));
}
}
#endif /* HAVE_MOUSE */
if (!NILP (current_kboard->Voverriding_terminal_local_map))
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;
}

View 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);