unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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

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