changeset 109957:083f3bd6ac6e

Move reading an extended command to Elisp (bug#5364, bug#5214). * lisp/simple.el (read-extended-command): New function with the logic for `completing-read' moved to Elisp from `execute-extended-command'. Use `function-called-at-point' in `minibuffer-default-add-function' to get a command name for M-n (bug#5364, bug#5214). * src/keyboard.c (Fexecute_extended_command): Move reading a command name with `completing-read' to a new Elisp function `read-extended-command'. Call it to read a command to `function' (bug#5364, bug#5214).
author Juri Linkov <juri@jurta.org>
date Mon, 23 Aug 2010 00:27:59 +0100
parents ce960720ed3f
children 73a3403135d5
files lisp/ChangeLog lisp/simple.el src/ChangeLog src/keyboard.c
diffstat 4 files changed, 49 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sun Aug 22 17:15:20 2010 -0400
+++ b/lisp/ChangeLog	Mon Aug 23 00:27:59 2010 +0100
@@ -1,3 +1,10 @@
+2010-08-22  Juri Linkov  <juri@jurta.org>
+
+	* simple.el (read-extended-command): New function with the logic
+	for `completing-read' moved to Elisp from `execute-extended-command'.
+	Use `function-called-at-point' in `minibuffer-default-add-function'
+	to get a command name for M-n (bug#5364, bug#5214).
+
 2010-08-22  Chong Yidong  <cyd@stupidchicken.com>
 
 	* startup.el (command-line-1): Issue warning for ignored arguments
--- a/lisp/simple.el	Sun Aug 22 17:15:20 2010 -0400
+++ b/lisp/simple.el	Mon Aug 23 00:27:59 2010 +0100
@@ -1301,6 +1301,40 @@
       (if command-history
 	  (error "Argument %d is beyond length of command history" arg)
 	(error "There are no previous complex commands to repeat")))))
+
+(defun read-extended-command ()
+  "Read command name to invoke in `execute-extended-command'."
+  (minibuffer-with-setup-hook
+      (lambda ()
+	(set (make-local-variable 'minibuffer-default-add-function)
+	     (lambda ()
+	       ;; Get a command name at point in the original buffer
+	       ;; to propose it after M-n.
+	       (with-current-buffer (window-buffer (minibuffer-selected-window))
+		 (and (commandp (function-called-at-point))
+		      (format "%S" (function-called-at-point)))))))
+    ;; Read a string, completing from and restricting to the set of
+    ;; all defined commands.  Don't provide any initial input.
+    ;; Save the command read on the extended-command history list.
+    (completing-read
+     (concat (cond
+	      ((eq current-prefix-arg '-) "- ")
+	      ((and (consp current-prefix-arg)
+		    (eq (car current-prefix-arg) 4)) "C-u ")
+	      ((and (consp current-prefix-arg)
+		    (integerp (car current-prefix-arg)))
+	       (format "%d " (car current-prefix-arg)))
+	      ((integerp current-prefix-arg)
+	       (format "%d " current-prefix-arg)))
+	     ;; This isn't strictly correct if `execute-extended-command'
+	     ;; is bound to anything else (e.g. [menu]).
+	     ;; It could use (key-description (this-single-command-keys)),
+	     ;; but actually a prompt other than "M-x" would be confusing,
+	     ;; because "M-x" is a well-known prompt to read a command
+	     ;; and it serves as a shorthand for "Extended command: ".
+	     "M-x ")
+     obarray 'commandp t nil 'extended-command-history)))
+
 
 (defvar minibuffer-history nil
   "Default minibuffer history list.
--- a/src/ChangeLog	Sun Aug 22 17:15:20 2010 -0400
+++ b/src/ChangeLog	Mon Aug 23 00:27:59 2010 +0100
@@ -1,3 +1,9 @@
+2010-08-22  Juri Linkov  <juri@jurta.org>
+
+	* keyboard.c (Fexecute_extended_command): Move reading a command name
+	with `completing-read' to a new Elisp function `read-extended-command'.
+	Call it to read a command to `function'  (bug#5364, bug#5214).
+
 2010-08-22  Chong Yidong  <cyd@stupidchicken.com>
 
 	* emacs.c (main): Remove handling of --unibyte arg (Bug#6886).
--- a/src/keyboard.c	Sun Aug 22 17:15:20 2010 -0400
+++ b/src/keyboard.c	Mon Aug 23 00:27:59 2010 +0100
@@ -10345,13 +10345,12 @@
   (Lisp_Object prefixarg)
 {
   Lisp_Object function;
-  char buf[40];
   int saved_last_point_position;
   Lisp_Object saved_keys, saved_last_point_position_buffer;
   Lisp_Object bindings, value;
   struct gcpro gcpro1, gcpro2, gcpro3;
 #ifdef HAVE_WINDOW_SYSTEM
-  /* The call to Fcompleting_read wil start and cancel the hourglass,
+  /* The call to Fcompleting_read will start and cancel the hourglass,
      but if the hourglass was already scheduled, this means that no
      hourglass will be shown for the actual M-x command itself.
      So we restart it if it is already scheduled.  Note that checking
@@ -10364,31 +10363,9 @@
 			XVECTOR (this_command_keys)->contents);
   saved_last_point_position_buffer = last_point_position_buffer;
   saved_last_point_position = last_point_position;
-  buf[0] = 0;
   GCPRO3 (saved_keys, prefixarg, saved_last_point_position_buffer);
 
-  if (EQ (prefixarg, Qminus))
-    strcpy (buf, "- ");
-  else if (CONSP (prefixarg) && XINT (XCAR (prefixarg)) == 4)
-    strcpy (buf, "C-u ");
-  else if (CONSP (prefixarg) && INTEGERP (XCAR (prefixarg)))
-    sprintf (buf, "%ld ", (long) XINT (XCAR (prefixarg)));
-  else if (INTEGERP (prefixarg))
-    sprintf (buf, "%ld ", (long) XINT (prefixarg));
-
-  /* This isn't strictly correct if execute-extended-command
-     is bound to anything else.  Perhaps it should use
-     this_command_keys?  */
-  strcat (buf, "M-x ");
-
-  /* Prompt with buf, and then read a string, completing from and
-     restricting to the set of all defined commands.  Don't provide
-     any initial input.  Save the command read on the extended-command
-     history list. */
-  function = Fcompleting_read (build_string (buf),
-			       Vobarray, Qcommandp,
-			       Qt, Qnil, Qextended_command_history, Qnil,
-			       Qnil);
+  function = call0 (intern ("read-extended-command"));
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (hstarted) start_hourglass ();