From: David Kastrup <dak@gnu.org>
Cc: cyd@stupidchicken.com, emacs-devel@gnu.org, storm@cua.dk
Subject: Re: local keymap patch for key-binding
Date: Wed, 13 Sep 2006 01:44:55 +0200 [thread overview]
Message-ID: <85ejug4pl4.fsf@lola.goethe.zz> (raw)
In-Reply-To: <85irjs4tda.fsf@lola.goethe.zz> (David Kastrup's message of "Wed\, 13 Sep 2006 00\:23\:13 +0200")
[-- Attachment #1: Type: text/plain, Size: 1317 bytes --]
David Kastrup <dak@gnu.org> writes:
> Richard Stallman <rms@gnu.org> writes:
>
>> > If you thing it reasonable that key-binding should also react to
>> > bona-fide events _not_ wrapped in an array, I can do this easily
>> > enough in the change I am working on.
>>
>> Please don't make that change. key-binding is supposed to look up a
>> sequence of events; it expects that sequence to be in a vector or
>> string. There is nothing wrong with that, and no need to change it.
>>
>> I think we simply had a misunderstanding about what it means to say
>> that key-binding can "look up events". In my way of looking at
>> things, you give key-binding a vector of events, and what it does is
>> "look up events."
>
> Ok, I'll rework my patch.
Ok, here is the complete patch. I also added an optional argument to
`command-remapping' (this was required to let `key-binding' do the
right thing in the case of mouse events).
I removed the `kill-emacs' call if the current frame not live: I can't
think of it making much sense in `key-binding'.
I also added a changelog entry and tested this with a number of
events. Looks clean to me.
I would like to check this in soon so that one can make the mouse
remapping stuff use it. That should make the `follow-link' property
work the same as any remapping.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 9356 bytes --]
Index: keymap.c
===================================================================
RCS file: /sources/emacs/emacs/src/keymap.c,v
retrieving revision 1.333
diff -u -r1.333 keymap.c
--- keymap.c 11 Sep 2006 13:03:40 -0000 1.333
+++ keymap.c 12 Sep 2006 23:19:16 -0000
@@ -28,6 +28,7 @@
#include "buffer.h"
#include "charset.h"
#include "keyboard.h"
+#include "window.h"
#include "termhooks.h"
#include "blockinput.h"
#include "puresize.h"
@@ -1216,17 +1217,20 @@
/* 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 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);
+ 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,7 +1556,7 @@
/* 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 +1570,94 @@
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 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;
+ Lisp_Object *maps, value, event;
int nmaps, i;
- struct gcpro gcpro1;
+ struct gcpro gcpro1, gcpro2;
+ int count = SPECPDL_INDEX ();
+
+ GCPRO2 (key, location);
- GCPRO1 (key);
+ if (NILP (location))
+ location = key;
-#ifdef HAVE_MOUSE
- if (VECTORP (key) && ASIZE (key) > 0)
+ if (VECTORP(location) && ASIZE(location) > 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;
+ /* 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);
- 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))
+ event = Qnil;
+ }
+ else
+ event = Qnil;
- if (!NILP (Fkeymapp (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 (! 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)
{
- 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 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));
+
}
}
}
-#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 +1665,80 @@
}
else
{
- Lisp_Object local;
+ Lisp_Object keymap, local_map;
- local = get_local_map (PT, current_buffer, Qkeymap);
- if (! NILP (local))
+ 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 (local, key, accept_default);
+ value = Flookup_key (keymap, key, accept_default);
if (! NILP (value) && !INTEGERP (value))
goto done;
}
@@ -1644,10 +1755,9 @@
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 +1766,8 @@
value = Flookup_key (current_global_map, key, accept_default);
done:
+ unbind_to (count, Qnil);
+
UNGCPRO;
if (NILP (value) || INTEGERP (value))
return Qnil;
@@ -1666,7 +1778,7 @@
if (NILP (no_remap) && SYMBOLP (value))
{
Lisp_Object value1;
- if (value1 = Fcommand_remapping (value), !NILP (value1))
+ if (value1 = Fcommand_remapping (value, location), !NILP (value1))
value = value1;
}
@@ -2467,7 +2579,7 @@
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;
}
[-- Attachment #3: Type: text/plain, Size: 52 bytes --]
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
[-- Attachment #4: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2006-09-12 23:44 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-10 9:34 longlines-mode doesn't seem to work with some non-english text Miles Bader
2006-02-11 4:35 ` Chong Yidong
2006-02-13 0:32 ` Kevin Ryde
2006-09-09 15:08 ` local keymap patch for key-binding Chong Yidong
2006-09-09 15:15 ` David Kastrup
2006-09-09 15:26 ` Chong Yidong
2006-09-10 12:44 ` Chong Yidong
2006-09-10 13:25 ` David Kastrup
2006-09-11 2:36 ` Chong Yidong
2006-09-11 6:25 ` David Kastrup
2006-09-11 7:05 ` David Kastrup
2006-09-11 8:52 ` Kim F. Storm
2006-09-11 9:48 ` David Kastrup
2006-09-11 10:11 ` David Kastrup
2006-09-11 12:53 ` Kim F. Storm
2006-09-11 13:04 ` David Kastrup
2006-09-11 13:07 ` Chong Yidong
2006-09-11 19:58 ` Richard Stallman
2006-09-12 10:04 ` David Kastrup
2006-09-12 15:21 ` David Kastrup
2006-09-12 15:39 ` PCL-CVS's diff and marks (was: local keymap patch for key-binding) Stefan Monnier
2006-09-12 15:42 ` PCL-CVS's diff and marks David Kastrup
2006-09-12 15:54 ` Stefan Monnier
2006-09-12 21:45 ` local keymap patch for key-binding Richard Stallman
2006-09-12 22:23 ` David Kastrup
2006-09-12 23:44 ` David Kastrup [this message]
2006-09-13 7:45 ` Kim F. Storm
2006-09-13 8:11 ` David Kastrup
2006-09-13 11:05 ` Kim F. Storm
2006-09-13 11:38 ` David Kastrup
2006-09-13 12:23 ` Kim F. Storm
2006-09-13 12:32 ` David Kastrup
2006-09-13 13:45 ` Kim F. Storm
2006-09-13 19:25 ` Richard Stallman
2006-09-13 19:49 ` David Kastrup
2006-09-13 19:25 ` Richard Stallman
2006-09-13 20:02 ` David Kastrup
2006-09-13 19:24 ` Richard Stallman
2006-09-13 15:10 ` Richard Stallman
2006-09-13 15:25 ` David Kastrup
2006-09-14 2:34 ` Richard Stallman
2006-09-14 11:57 ` David Kastrup
2006-09-14 22:34 ` David Kastrup
2006-09-14 22:36 ` David Kastrup
2006-09-15 3:14 ` Richard Stallman
2006-09-15 8:20 ` David Kastrup
2006-09-15 23:47 ` David Kastrup
2006-09-16 0:14 ` Kim F. Storm
2006-09-16 19:05 ` Richard Stallman
2006-09-18 15:43 ` David Kastrup
2006-09-18 20:34 ` Kim F. Storm
2006-09-18 23:39 ` Richard Stallman
2006-09-16 16:41 ` Stefan Monnier
2006-09-10 18:52 ` Richard Stallman
2006-09-11 2:39 ` Chong Yidong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=85ejug4pl4.fsf@lola.goethe.zz \
--to=dak@gnu.org \
--cc=cyd@stupidchicken.com \
--cc=emacs-devel@gnu.org \
--cc=storm@cua.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).