From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Setting "echoing prefix" from Elisp (was: other-frame, other-window prefix keys) Date: Tue, 11 Aug 2015 13:37:54 -0400 Message-ID: References: <86vbcq2qgc.fsf@stephe-leake.org> <86k2t50ze5.fsf@stephe-leake.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1439314714 1952 80.91.229.3 (11 Aug 2015 17:38:34 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 11 Aug 2015 17:38:34 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stephen Leake Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Aug 11 19:38:24 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZPDVE-0003OQ-UN for ged-emacs-devel@m.gmane.org; Tue, 11 Aug 2015 19:38:21 +0200 Original-Received: from localhost ([::1]:35431 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPDVD-00086h-Vl for ged-emacs-devel@m.gmane.org; Tue, 11 Aug 2015 13:38:19 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56523) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPDUv-00085j-HK for emacs-devel@gnu.org; Tue, 11 Aug 2015 13:38:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZPDUq-00052o-Ai for emacs-devel@gnu.org; Tue, 11 Aug 2015 13:38:01 -0400 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.181]:37586) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZPDUq-00052f-1e for emacs-devel@gnu.org; Tue, 11 Aug 2015 13:37:56 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BCFgA731xV//gFNJ1cgxCEAoVVwD6CTQQCAoE8PRABAQEBAQEBgQpBBYNdAQEDAScvIxA/EhQYDSSINwjPIwEBAQcCAR+QPweELQWfF4Nrgn6PBCOCChyBbiKBNAQggSABAQE X-IPAS-Result: A0BCFgA731xV//gFNJ1cgxCEAoVVwD6CTQQCAoE8PRABAQEBAQEBgQpBBYNdAQEDAScvIxA/EhQYDSSINwjPIwEBAQcCAR+QPweELQWfF4Nrgn6PBCOCChyBbiKBNAQggSABAQE X-IronPort-AV: E=Sophos;i="5.13,465,1427774400"; d="scan'208";a="159495560" Original-Received: from 157-52-5-248.cpe.teksavvy.com (HELO pastel.home) ([157.52.5.248]) by ironport2-out.teksavvy.com with ESMTP; 11 Aug 2015 13:37:54 -0400 Original-Received: by pastel.home (Postfix, from userid 20848) id 36AC162224; Tue, 11 Aug 2015 13:37:54 -0400 (EDT) In-Reply-To: (Stefan Monnier's message of "Sun, 09 Aug 2015 12:17:46 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.181 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:188730 Archived-At: >>> One other thing: I'd be neat if the echo-area could display the "C-x 7" >>> prefix if you wait a couple seconds, like it does for C-u. I have some >>> experimental code around somewhere that moves some of that C-u code from >>> C so it could be used for C-x 7. >> Ok, please send the code; I have no idea how that works. > I don't really have a good idea how it works either, mind you. > I experimented with it specifically thinking of prefixes like C-x 4, but > there are some non-trivial issues. > I'll try and dig it up, OK, found it. Here's an updated version which should apply cleanly to "master". It's likely that this change will require adjustment in any code which uses reset-this-command-lengths (aka cua-base.el and kmacro.el). Stefan diff --git a/lisp/simple.el b/lisp/simple.el index 2636777..e216794 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3661,7 +3661,19 @@ see other processes running on the system, use `list-system-processes'." "Keymap used while processing \\[universal-argument].") (defun universal-argument--mode () - (set-transient-map universal-argument-map)) + (setq echo-keystrokes-prefix + (concat "C-u" + (pcase prefix-arg + (`(-) " -") + (`(,(and (pred integerp) n)) + (let ((str "")) + (while (and (> n 4) (= (mod n 4) 0)) + (setq str (concat str " C-u")) + (setq n (/ n 4))) + (if (= n 4) str (format " %s" prefix-arg)))) + (_ (format " %s" prefix-arg))))) + (set-transient-map universal-argument-map nil + (lambda () (setq echo-keystrokes-prefix nil)))) (defun universal-argument () "Begin a numeric argument for the following command. diff --git a/src/keyboard.c b/src/keyboard.c index f670da3..3c5ade2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -441,10 +441,12 @@ echo_add_key (Lisp_Object c) ptrdiff_t size = sizeof initbuf; char *buffer = initbuf; char *ptr = buffer; - Lisp_Object echo_string; + Lisp_Object echo_string = KVAR (current_kboard, echo_string); USE_SAFE_ALLOCA; - echo_string = KVAR (current_kboard, echo_string); + if (STRINGP (echo_string) && SCHARS (echo_string) > 0) + /* Add a space at the end as a separator between keys. */ + ptr++[0] = ' '; /* If someone has passed us a composite event, use its head symbol. */ c = EVENT_HEAD (c); @@ -475,6 +477,7 @@ echo_add_key (Lisp_Object c) int len = sizeof text - 1; if (size - (ptr - buffer) < len) + /* FIXME: I had "abort ();" here !?! */ { ptrdiff_t offset = ptr - buffer; size += len; @@ -486,48 +489,12 @@ echo_add_key (Lisp_Object c) ptr += len; } - /* Replace a dash from echo_dash with a space, otherwise add a space - at the end as a separator between keys. */ - AUTO_STRING (space, " "); - if (STRINGP (echo_string) && SCHARS (echo_string) > 1) - { - Lisp_Object last_char, prev_char, idx; - - idx = make_number (SCHARS (echo_string) - 2); - prev_char = Faref (echo_string, idx); - - idx = make_number (SCHARS (echo_string) - 1); - last_char = Faref (echo_string, idx); - - /* We test PREV_CHAR to make sure this isn't the echoing of a - minus-sign. */ - if (XINT (last_char) == '-' && XINT (prev_char) != ' ') - Faset (echo_string, idx, make_number (' ')); - else - echo_string = concat2 (echo_string, space); - } - else if (STRINGP (echo_string) && SCHARS (echo_string) > 0) - echo_string = concat2 (echo_string, space); - kset_echo_string (current_kboard, concat2 (echo_string, make_string (buffer, ptr - buffer))); SAFE_FREE (); } -/* Add C to the echo string, if echoing is going on. C can be a - character or a symbol. */ - -static void -echo_char (Lisp_Object c) -{ - if (current_kboard->immediate_echo) - { - echo_add_key (c); - echo_now (); - } -} - /* Temporarily add a dash to the end of the echo string if it's not empty, so that it serves as a mini-prompt for the very next character. */ @@ -539,9 +506,6 @@ echo_dash (void) if (NILP (KVAR (current_kboard, echo_string))) return; - if (this_command_key_count == 0) - return; - if (!current_kboard->immediate_echo && SCHARS (KVAR (current_kboard, echo_string)) == 0) return; @@ -574,16 +538,13 @@ echo_dash (void) echo_now (); } -/* Display the current echo string, and begin echoing if not already - doing so. */ - static void -echo_now (void) +echo_update (void) { - if (!current_kboard->immediate_echo) + if (current_kboard->immediate_echo) { ptrdiff_t i; - current_kboard->immediate_echo = 1; + kset_echo_string (current_kboard, Vecho_keystrokes_prefix); for (i = 0; i < this_command_key_count; i++) { @@ -598,7 +559,7 @@ echo_now (void) c = AREF (this_command_keys, i); if (! (EVENT_HAS_PARAMETERS (c) && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) - echo_char (c); + echo_add_key (c); } /* Set before_command_echo_length to the value that would @@ -607,10 +568,23 @@ echo_now (void) if (this_command_key_count == this_single_command_key_start) before_command_echo_length = echo_length (); + echo_now (); + } +} + +/* Display the current echo string, and begin echoing if not already + doing so. */ + +static void +echo_now (void) +{ + if (!current_kboard->immediate_echo) + { + current_kboard->immediate_echo = true; + echo_update (); /* Put a dash at the end to invite the user to type more. */ echo_dash (); } - echoing = 1; /* FIXME: Use call (Qmessage) so it can be advised (e.g. emacspeak). */ message3_nolog (KVAR (current_kboard, echo_string)); @@ -1550,9 +1524,6 @@ command_loop_1 (void) 2) we want to leave echoing on so that the prefix will be echoed as part of this key sequence, so don't call cancel_echoing, and - 3) we want to leave this_command_key_count non-zero, so that - read_char will realize that it is re-reading a character, and - not echo it a second time. If the command didn't actually create a prefix arg, but is merely a frame event that is transparent to prefix args, @@ -1565,9 +1536,17 @@ command_loop_1 (void) if (!CONSP (last_command_event)) kset_last_repeatable_command (current_kboard, Vreal_this_command); cancel_echoing (); - this_command_key_count = 0; - this_command_key_count_reset = 0; - this_single_command_key_start = 0; + } + + this_command_key_count = 0; + this_command_key_count_reset = false; + this_single_command_key_start = 0; + + if (current_kboard->immediate_echo && !NILP (Vecho_keystrokes_prefix)) + { + current_kboard->immediate_echo = false; + /* Refresh the echo message. */ + echo_now (); } if (!NILP (BVAR (current_buffer, mark_active)) @@ -2577,7 +2556,7 @@ read_char (int commandflag, Lisp_Object map, (3) There's only one place in 20.x where ok_to_echo_at_next_pause is set to a non-null value. This is done in read_char and it is - set to echo_area_glyphs after a call to echo_char. That means + set to echo_area_glyphs. That means ok_to_echo_at_next_pause is either null or current_kboard->echobuf with the appropriate current_kboard at that time. @@ -2684,7 +2663,7 @@ read_char (int commandflag, Lisp_Object map, if (minibuf_level == 0 && !end_time && !current_kboard->immediate_echo - && this_command_key_count > 0 + && (this_command_key_count > 0 || STRINGP (Vecho_keystrokes_prefix)) && ! noninteractive && echo_keystrokes_p () && (/* No message. */ @@ -3172,22 +3151,18 @@ read_char (int commandflag, Lisp_Object map, { /* Don't echo mouse motion events. */ - if (echo_keystrokes_p () - && ! (EVENT_HAS_PARAMETERS (c) - && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) - { - echo_char (c); - if (! NILP (also_record)) - echo_char (also_record); - /* Once we reread a character, echoing can happen - the next time we pause to read a new one. */ - ok_to_echo_at_next_pause = current_kboard; - } + if (! (EVENT_HAS_PARAMETERS (c) + && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) + /* Once we reread a character, echoing can happen + the next time we pause to read a new one. */ + ok_to_echo_at_next_pause = current_kboard; /* Record this character as part of the current key. */ add_command_key (c); if (! NILP (also_record)) add_command_key (also_record); + + echo_update (); } last_input_event = c; @@ -3248,18 +3223,13 @@ record_menu_key (Lisp_Object c) before_command_echo_length = echo_length (); #endif - /* Don't echo mouse motion events. */ - if (echo_keystrokes_p ()) - { - echo_char (c); - - /* Once we reread a character, echoing can happen - the next time we pause to read a new one. */ - ok_to_echo_at_next_pause = 0; - } + /* Once we reread a character, echoing can happen + the next time we pause to read a new one. */ + ok_to_echo_at_next_pause = NULL; /* Record this character as part of the current key. */ add_command_key (c); + echo_update (); /* Re-reading in the middle of a command. */ last_input_event = c; @@ -9157,11 +9127,12 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { key = keybuf[t]; add_command_key (key); - if (echo_keystrokes_p () - && current_kboard->immediate_echo) + if (current_kboard->immediate_echo) { - echo_add_key (key); - echo_dash (); + /* Set immediate_echo to false so as to force echo_now to + redisplay (it will set immediate_echo right back to true). */ + current_kboard->immediate_echo = false; + echo_now (); } } @@ -9833,11 +9804,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, Better ideas? */ for (; t < mock_input; t++) - { - if (echo_keystrokes_p ()) - echo_char (keybuf[t]); - add_command_key (keybuf[t]); - } + add_command_key (keybuf[t]); + echo_update (); UNGCPRO; return t; @@ -10129,6 +10097,7 @@ The value is always a vector. */) DEFUN ("reset-this-command-lengths", Freset_this_command_lengths, Sreset_this_command_lengths, 0, 0, 0, + /* FIXME: Bad&wrong docstring! */ doc: /* Make the unread events replace the last command and echo. Used in `universal-argument-other-key'. @@ -11439,6 +11408,10 @@ The value may be integer or floating point. If the value is zero, don't echo at all. */); Vecho_keystrokes = make_number (1); + DEFVAR_LISP ("echo-keystrokes-prefix", Vecho_keystrokes_prefix, + doc: /* String to prefix in front of unfinished key sequences. */); + Vecho_keystrokes_prefix = Qnil; + DEFVAR_INT ("polling-period", polling_period, doc: /* Interval between polling for input during Lisp execution. The reason for polling is to make C-g work to stop a running program.