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: Tue, 12 Sep 2006 17:21:51 +0200 Message-ID: <85mz959kkw.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> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1158074557 25732 80.91.229.2 (12 Sep 2006 15:22:37 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 12 Sep 2006 15:22:37 +0000 (UTC) Cc: cyd@stupidchicken.com, storm@cua.dk, emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Sep 12 17:22:28 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 1GNA5e-0006qF-9F for ged-emacs-devel@m.gmane.org; Tue, 12 Sep 2006 17:22:22 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GNA5d-0004fI-DA for ged-emacs-devel@m.gmane.org; Tue, 12 Sep 2006 11:22:21 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1GNA5Q-0004f9-AZ for emacs-devel@gnu.org; Tue, 12 Sep 2006 11:22:08 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1GNA5P-0004eo-Av for emacs-devel@gnu.org; Tue, 12 Sep 2006 11:22:07 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GNA5P-0004eh-6R for emacs-devel@gnu.org; Tue, 12 Sep 2006 11:22:07 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.52) id 1GNA6v-0007ZQ-EP for emacs-devel@gnu.org; Tue, 12 Sep 2006 11:23:41 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1GNA5G-0002Zg-MB; Tue, 12 Sep 2006 11:21:59 -0400 Original-Received: by lola.goethe.zz (Postfix, from userid 1002) id 92ADE1C40B5C; Tue, 12 Sep 2006 17:21:51 +0200 (CEST) Original-To: rms@gnu.org In-Reply-To: <85hczdbdv2.fsf@lola.goethe.zz> (David Kastrup's message of "Tue\, 12 Sep 2006 12\:04\:01 +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:59726 Archived-At: --=-=-= David Kastrup 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. --=-=-= Content-Type: text/x-patch Content-Disposition: inline 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); --=-=-= -- 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 --=-=-=--