all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: David Kastrup <dak@gnu.org>
Cc: cyd@stupidchicken.com, storm@cua.dk, emacs-devel@gnu.org
Subject: Re: local keymap patch for key-binding
Date: Tue, 12 Sep 2006 17:21:51 +0200	[thread overview]
Message-ID: <85mz959kkw.fsf@lola.goethe.zz> (raw)
In-Reply-To: <85hczdbdv2.fsf@lola.goethe.zz> (David Kastrup's message of "Tue\, 12 Sep 2006 12\:04\:01 +0200")

[-- Attachment #1: Type: text/plain, Size: 1308 bytes --]

David Kastrup <dak@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.

Ok, here is my current patch (incidentally: why doesn't it work to use
PCL-CVS to do a multi-file diff? It ignores the marked files, just
working on the current line).  I have added an additional argument to
key-binding and documented it (that required changes in keymap.h and
callers of key-binding from C in keyboard.c).

As far as I can tell, this works with all key sequences.  If people
agree that this is reasonable, I would install it.  I'd be glad if
someone looked it over with regard to the SPECDCL and garbage
collection protection: I don't feel comfortable about those.  I also
copied code from keyboard.c that aborts if the current frame is not
live and can't be returned to.  No idea whether this is required (I
assume it was put there to avoid a busy lockup when Emacs got its
frame killed or something) or even a good idea.

Anybody have an opinion about that?

If people think this is the right way to go, I can install it.  I have
verified it with quite a few tries.  However, I have not yet tested
the LOCATION argument.  It should come in handy for mouse.el and
follow-link.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 12305 bytes --]

Index: src/keyboard.c
===================================================================
RCS file: /sources/emacs/emacs/src/keyboard.c,v
retrieving revision 1.875
diff -c -r1.875 keyboard.c
*** src/keyboard.c	10 Sep 2006 21:10:50 -0000	1.875
--- src/keyboard.c	12 Sep 2006 15:08:14 -0000
***************
*** 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/keymap.c
===================================================================
RCS file: /sources/emacs/emacs/src/keymap.c,v
retrieving revision 1.333
diff -c -r1.333 keymap.c
*** src/keymap.c	11 Sep 2006 13:03:40 -0000	1.333
--- src/keymap.c	12 Sep 2006 15:08:18 -0000
***************
*** 28,33 ****
--- 28,35 ----
  #include "buffer.h"
  #include "charset.h"
  #include "keyboard.h"
+ #include "frame.h"
+ #include "window.h"
  #include "termhooks.h"
  #include "blockinput.h"
  #include "puresize.h"
***************
*** 1226,1232 ****
      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. */
--- 1228,1234 ----
      return Qnil;
  
    ASET (command_remapping_vector, 1, command);
!   return Fkey_binding (command_remapping_vector, Qnil, Qt, Qnil);
  }
  
  /* 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.
--- 1554,1560 ----
  
  /* 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))
--- 1568,1660 ----
  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;
    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)
      {
!       if (SYMBOLP (AREF(location,0)) && ASIZE(location) > 1)
! 	location = AREF(location,1);
!       else
! 	location = AREF(location,0);
!     }
  
!   /* We are not interested in locations without event data */
  
!   if (!EVENT_HAS_PARAMETERS (location))
!     location = 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 (location))
!     {
!       Lisp_Object kind;
!       Lisp_Object string;
!       
!       kind = EVENT_HEAD_KIND (EVENT_HEAD (location));
!       if (EQ (kind, Qmouse_click))
! 	{
! 	  Lisp_Object window, posn;
! 	  
! 	  window = POSN_WINDOW (EVENT_START (location));
! 	  posn   = POSN_POSN (EVENT_START (location));
! 	  
! 	  /* 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 ());
! 	      
! 	      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
! 		Fkill_emacs (Qnil);
! 	      
! 	      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;
  	}
--- 1662,1741 ----
      }
    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(location))
  	{
! 	  Lisp_Object kind;
! 	  Lisp_Object string;
! 
! 	  kind = EVENT_HEAD_KIND (EVENT_HEAD (location));
! 	  if (EQ (kind, Qmouse_click))
! 	    {
! 	      Lisp_Object window, posn;
! 
! 	      window = POSN_WINDOW      (EVENT_START (location));
! 	      posn   = POSN_POSN (EVENT_START (location));
! 
! 	      /* For a mouse click, get the local text-property keymap
! 		 of the place clicked on, rather than point.  */
! 
! 	      if (CONSP (XCDR (location)))
! 		{
! 		  Lisp_Object start, pos;
! 
! 		  start = EVENT_START (location);
! 
! 		  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 (location)),
! 		  (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;
  	}
--- 1752,1760 ----
  	      goto done;
  	  }
  
!       if (! NILP (local_map))
  	{
! 	  value = Flookup_key (local_map, key, accept_default);
  	  if (! NILP (value) && !INTEGERP (value))
  	    goto done;
  	}
***************
*** 1656,1661 ****
--- 1763,1770 ----
    value = Flookup_key (current_global_map, key, accept_default);
  
   done:
+   unbind_to (count, Qnil);
+ 
    UNGCPRO;
    if (NILP (value) || INTEGERP (value))
      return Qnil;
Index: src/keymap.h
===================================================================
RCS file: /sources/emacs/emacs/src/keymap.h,v
retrieving revision 1.14
diff -c -r1.14 keymap.h
*** src/keymap.h	6 Feb 2006 15:23:21 -0000	1.14
--- src/keymap.h	12 Sep 2006 15:08:18 -0000
***************
*** 30,36 ****
  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);
--- 30,36 ----
  EXFUN (Fdefine_key, 3);
  EXFUN (Flookup_key, 3);
  EXFUN (Fcommand_remapping, 1);
! EXFUN (Fkey_binding, 4);
  EXFUN (Fkey_description, 2);
  EXFUN (Fsingle_key_description, 2);
  EXFUN (Fwhere_is_internal, 5);

[-- 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 15:21 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 [this message]
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
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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=85mz959kkw.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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.