changeset 5565:8b688d642fc1

(read_char_x_menu_prompt, read_char_minibuf_menu_prompt): New functions made by dividing up read_char_menu_prompt. (read_char): Call read_char_minibuffer_menu_prompt before the sit_for if X menus are not going to be used. (read_char_minibuf_menu_prompt): Correct access to keymaps for menus when not using X menus. Only store character read in a keyboard macro if it is not the menu help character.
author Richard M. Stallman <rms@gnu.org>
date Tue, 11 Jan 1994 18:52:33 +0000
parents 99143cd57345
children e2925466c923
files src/keyboard.c
diffstat 1 files changed, 88 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/keyboard.c	Tue Jan 11 15:56:29 1994 +0000
+++ b/src/keyboard.c	Tue Jan 11 18:52:33 1994 +0000
@@ -450,7 +450,8 @@
 static int read_avail_input ();
 static void get_input_pending ();
 static int readable_events ();
-static Lisp_Object read_char_menu_prompt ();
+static Lisp_Object read_char_x_menu_prompt ();
+static Lisp_Object read_char_minibuf_menu_prompt ();
 static Lisp_Object make_lispy_event ();
 static Lisp_Object make_lispy_movement ();
 static Lisp_Object modify_event_symbol ();
@@ -1460,6 +1461,19 @@
     /* If already echoing, continue.  */
     echo_dash ();
 
+  /* Try reading a character via menu prompting in the minibuf.
+     Try this before the sit-for, because the sit-for
+     would do the wrong thing if we are supposed to do
+     menu prompting. If EVENT_HAS_PARAMETERS then we are reading
+     after a mouse event so don't try a minibuf menu. */
+  c = Qnil;
+  if (nmaps > 0 && INTERACTIVE && 
+      !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event))
+    {
+      c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
+      if ( ! NILP(c) ) return c ;
+    }
+
   /* If in middle of key sequence and minibuffer not active,
      start echoing if enough time elapses.  */
   if (minibuf_level == 0 && !immediate_echo && this_command_key_count > 0
@@ -1495,13 +1509,13 @@
       restore_getcjmp (temp);
     }
 
-  /* Try reading a character via menu prompting.
-     Try this before the sit-for, because the sit-for
-     would do the wrong thing if we are supposed to do
-     menu prompting.  */
-  c = Qnil;
-  if (INTERACTIVE && !NILP (prev_event))
-    c = read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+  /* Try reading using an X menu.
+     This is never confused with reading using the minibuf because the recursive
+     call of read_char in read_char_minibuf_menu_prompt does not pass on
+     any keys maps */
+  if (nmaps > 0 && INTERACTIVE &&
+      !NILP (prev_event) && EVENT_HAS_PARAMETERS (prev_event))
+    c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
 
   /* Slow down auto saves logarithmically in size of current buffer,
      and garbage collect while we're at it.  */
@@ -3573,10 +3587,16 @@
    USED_MOUSE_MENU is zero, *USED_MOUSE_MENU is left alone.
 
    The prompting is done based on the prompt-string of the map
-   and the strings associated with various map elements.  */
+   and the strings associated with various map elements.  
+
+   This can be done with X menus or with menus put in the minibuf.
+   These are done in different ways, depending on how the input will be read.
+   Menus using X are done after auto-saving in read-char, getting the input
+   event from Fx_popup_menu; menus using the minibuf use read_char recursively
+   and do auto-saving in the inner call of read_char. */
 
 static Lisp_Object
-read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
+read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
      int nmaps;
      Lisp_Object *maps;
      Lisp_Object prev_event;
@@ -3584,10 +3604,6 @@
 {
   int mapno;
   register Lisp_Object name;
-  int nlength;
-  int width = FRAME_WIDTH (selected_frame) - 4;
-  char *menu = (char *) alloca (width + 4);
-  int idx = -1;
   Lisp_Object rest, vector;
 
   if (used_mouse_menu)
@@ -3645,6 +3661,38 @@
     }
 #endif /* HAVE_X_MENU */
 #endif /* HAVE_X_WINDOWS */
+  return Qnil ;
+}
+
+static Lisp_Object
+read_char_minibuf_menu_prompt(commandflag, nmaps, maps)
+     int commandflag ;
+     int nmaps;
+     Lisp_Object *maps;
+{
+  int mapno;
+  register Lisp_Object name;
+  int nlength;
+  int width = FRAME_WIDTH (selected_frame) - 4;
+  char *menu = (char *) alloca (width + 4);
+  int idx = -1;
+  int nobindings ;
+  Lisp_Object rest, vector;
+
+  if (! menu_prompting)
+    return Qnil;
+
+  /* Get the menu name from the first map that has one (a prompt string).  */
+  for (mapno = 0; mapno < nmaps; mapno++)
+    {
+      name = map_prompt (maps[mapno]);
+      if (!NILP (name))
+	break;
+    }
+
+  /* If we don't have any menus, just read a character normally.  */
+  if (mapno >= nmaps)
+    return Qnil;
 
   /* Prompt string always starts with map's prompt, and a space.  */
   strcpy (menu, XSTRING (name)->data);
@@ -3664,6 +3712,7 @@
       int i = nlength;
       Lisp_Object obj;
       int ch;
+      int orig_defn_macro ;
 
       /* Loop over elements of map.  */
       while (i < width)
@@ -3678,10 +3727,8 @@
 		 or end this line if already have something on it.  */
 	      if (mapno == nmaps)
 		{
-		  if (notfirst)
-		    break;
-		  else
-		    mapno = 0;
+		  mapno = 0;
+		  if ( notfirst || nobindings ) break;
 		}
 	      rest = maps[mapno];
 	    }
@@ -3703,13 +3750,16 @@
 	  else
 	    {
 	      /* An ordinary element.  */
-	      s = Fcar_safe (Fcdr_safe (elt));
+	      if ( idx < 0 )
+		s = Fcar_safe (Fcdr_safe (elt));	/* alist */
+	      else
+		s = Fcar_safe(elt);			/* vector */
 	      if (XTYPE (s) != Lisp_String)
 		/* Ignore the element if it has no prompt string.  */
 		;
 	      /* If we have room for the prompt string, add it to this line.
 		 If this is the first on the line, always add it.  */
-	      else if (XSTRING (s)->size + i < width
+	      else if (XSTRING (s)->size + i + 2 < width
 		       || !notfirst)
 		{
 		  int thiswidth;
@@ -3721,6 +3771,7 @@
 		      i += 2;
 		    }
 		  notfirst = 1;
+		  nobindings = 0 ;
 
 		  /* Add as much of string as fits.  */
 		  thiswidth = XSTRING (s)->size;
@@ -3728,6 +3779,7 @@
 		    thiswidth = width - i;
 		  bcopy (XSTRING (s)->data, menu + i, thiswidth);
 		  i += thiswidth;
+		  menu[i] = 0;
 		}
 	      else
 		{
@@ -3738,7 +3790,7 @@
 		}
 
 	      /* Move past this element.  */
-	      if (idx >= 0 && idx + 1 >= XVECTOR (rest)->size)
+	      if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size)
 		/* Handle reaching end of dense table.  */
 		idx = -1;
 	      if (idx >= 0)
@@ -3750,7 +3802,15 @@
 
       /* Prompt with that and read response.  */
       message1 (menu);
-      obj = read_char (1, 0, 0, Qnil, 0);
+
+      /* Make believe its not a keyboard macro in case the help char 
+	 is pressed.  Help characters are not recorded because menu prompting
+	 is not used on replay.
+	 */
+      orig_defn_macro = defining_kbd_macro ;
+      defining_kbd_macro = 0 ;
+      obj = read_char (commandflag, 0, 0, Qnil, 0);
+      defining_kbd_macro = orig_defn_macro ;
 
       if (XTYPE (obj) != Lisp_Int)
 	return obj;
@@ -3760,7 +3820,12 @@
       if (! EQ (obj, menu_prompt_more_char)
 	  && (XTYPE (menu_prompt_more_char) != Lisp_Int
 	      || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char))))))
-	return obj;
+	{
+	  if ( defining_kbd_macro )
+	    store_kbd_macro_char(obj) ;
+	  return obj;
+	}
+      /* Help char - go round again */
     }
 }