From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.emacs.devel Subject: Re: local keymap patch for key-binding Date: Wed, 13 Sep 2006 01:44:55 +0200 Message-ID: <85ejug4pl4.fsf@lola.goethe.zz> References: <87slj1hybl.fsf@stupidchicken.com> <85pse5cbqw.fsf@lola.goethe.zz> <87zmd7yjq4.fsf@furball.mit.edu> <85pse3n99c.fsf@lola.goethe.zz> <87r6yjxh7k.fsf@furball.mit.edu> <85venuc27c.fsf@lola.goethe.zz> <85r6yiivi7.fsf@lola.goethe.zz> <85hczdbdv2.fsf@lola.goethe.zz> <85mz959kkw.fsf@lola.goethe.zz> <85irjs4tda.fsf@lola.goethe.zz> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1158104734 31256 80.91.229.2 (12 Sep 2006 23:45:34 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 12 Sep 2006 23:45:34 +0000 (UTC) Cc: cyd@stupidchicken.com, emacs-devel@gnu.org, storm@cua.dk Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Sep 13 01:45:33 2006 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1GNHwV-00024h-Ka for ged-emacs-devel@m.gmane.org; Wed, 13 Sep 2006 01:45:28 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GNHwV-0002F8-1i for ged-emacs-devel@m.gmane.org; Tue, 12 Sep 2006 19:45:27 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1GNHwH-0002Er-3y for emacs-devel@gnu.org; Tue, 12 Sep 2006 19:45:13 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1GNHwF-0002ET-UU for emacs-devel@gnu.org; Tue, 12 Sep 2006 19:45:12 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GNHwF-0002EJ-M6 for emacs-devel@gnu.org; Tue, 12 Sep 2006 19:45:11 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.52) id 1GNHxq-0003CA-Kv for emacs-devel@gnu.org; Tue, 12 Sep 2006 19:46:50 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1GNHw7-0005PA-7I; Tue, 12 Sep 2006 19:45:03 -0400 Original-Received: by lola.goethe.zz (Postfix, from userid 1002) id 0CDC41C40B5C; Wed, 13 Sep 2006 01:44:55 +0200 (CEST) Original-To: rms@gnu.org In-Reply-To: <85irjs4tda.fsf@lola.goethe.zz> (David Kastrup's message of "Wed\, 13 Sep 2006 00\:23\:13 +0200") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:59749 Archived-At: --=-=-= David Kastrup writes: > Richard Stallman 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. --=-=-= Content-Type: text/x-patch Content-Disposition: inline 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; } --=-=-= -- David Kastrup, Kriemhildstr. 15, 44793 Bochum --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--