]> code.delx.au - gnu-emacs/blobdiff - src/minibuf.c
(re_max_failures): Reduce to 8000.
[gnu-emacs] / src / minibuf.c
index 7d1721fa4bf721add7003222e744c3274c2d3ee4..9a65e2c9df54f6559e6757e5e62eadd301495991 100644 (file)
@@ -1,5 +1,5 @@
 /* Minibuffer input and completion.
-   Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 93, 94, 95, 1996 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 #include <config.h>
@@ -26,6 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "frame.h"
 #include "window.h"
 #include "syntax.h"
+#include "keyboard.h"
 
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
@@ -98,6 +100,51 @@ Lisp_Object Quser_variable_p;
 /* Non-nil means it is the window for C-M-v to scroll
    when the minibuffer is selected.  */
 extern Lisp_Object Vminibuf_scroll_window;
+
+extern Lisp_Object Voverriding_local_map;
+\f
+/* Put minibuf on currently selected frame's minibuffer.
+   We do this whenever the user starts a new minibuffer
+   or when a minibuffer exits.  */
+
+void
+choose_minibuf_frame ()
+{
+  if (selected_frame != 0
+      && !EQ (minibuf_window, selected_frame->minibuffer_window))
+    {
+#if defined(MSDOS) && !defined(HAVE_X_WINDOWS)
+      selected_frame->minibuffer_window = minibuf_window;
+#else
+      /* I don't think that any frames may validly have a null minibuffer
+        window anymore.  */
+      if (NILP (selected_frame->minibuffer_window))
+       abort ();
+
+      Fset_window_buffer (selected_frame->minibuffer_window,
+                         XWINDOW (minibuf_window)->buffer);
+      minibuf_window = selected_frame->minibuffer_window;
+#endif
+    }
+}
+
+DEFUN ("set-minibuffer-window", Fset_minibuffer_window,
+       Sset_minibuffer_window, 1, 1, 0,
+  "Specify which minibuffer window to use for the minibuffer.\n\
+This effects where the minibuffer is displayed if you put text in it\n\
+without invoking the usual minibuffer commands.")
+  (window)
+     Lisp_Object window;
+{
+  CHECK_WINDOW (window, 1);
+  if (! MINI_WINDOW_P (XWINDOW (window)))
+    error ("Window is not a minibuffer window");
+
+  minibuf_window = window;
+
+  return window;
+}
+
 \f
 /* Actual minibuffer invocation. */
 
@@ -111,11 +158,10 @@ Lisp_Object read_minibuf ();
    with initial position HISTPOS.  (BACKUP_N should be <= 0.)
 
    Normally return the result as a string (the text that was read),
-   but if EXPFLAG is non-nil, read it and return the object read.
+   but if EXPFLAG is nonzero, read it and return the object read.
    If HISTVAR is given, save the value read on that history only if it doesn't
    match the front of that history list exactly.  The value is pushed onto
-   the list as the string that was read, or as the object that resulted iff
-   EXPFLAG is non-nil.  */
+   the list as the string that was read.  */
 
 Lisp_Object
 read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
@@ -127,35 +173,32 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
      Lisp_Object histvar;
      Lisp_Object histpos;
 {
-  register Lisp_Object val;
+  Lisp_Object val;
   int count = specpdl_ptr - specpdl;
-  Lisp_Object mini_frame;
+  Lisp_Object mini_frame, ambient_dir;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+  single_kboard_state ();
+
+  val = Qnil;
+  ambient_dir = current_buffer->directory;
+
+  /* Don't need to protect PROMPT, HISTVAR, and HISTPOS because we
+     store them away before we can GC.  Don't need to protect
+     BACKUP_N because we use the value only if it is an integer.  */
+  GCPRO4 (map, initial, val, ambient_dir);
 
   if (!STRINGP (prompt))
     prompt = build_string ("");
 
-  /* Emacs in -batch mode calls minibuffer: print the prompt.  */
-  if (noninteractive && STRINGP (prompt))
-    printf ("%s", XSTRING (prompt)->data);
-
   if (!enable_recursive_minibuffers
       && minibuf_level > 0
       && (EQ (selected_window, minibuf_window)))
-#if 0
-         || selected_frame != XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)))
-#endif
     error ("Command attempted to use minibuffer while in minibuffer");
 
-  /* Could we simply bind these variables instead?  */
-  minibuf_save_list
-    = Fcons (minibuf_prompt,
-            Fcons (make_number (minibuf_prompt_width),
-                   Fcons (Vhelp_form,
-                          Fcons (Vcurrent_prefix_arg,
-                                 Fcons (Vminibuffer_history_position,
-                                        Fcons (Vminibuffer_history_variable,
-                                               minibuf_save_list))))));
-  minibuf_prompt_width = 0;
+  /* Choose the minibuffer window and frame, and take action on them.  */
+
+  choose_minibuf_frame ();
 
   record_unwind_protect (Fset_window_configuration,
                         Fcurrent_window_configuration (Qnil));
@@ -176,7 +219,37 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
     Fraise_frame (mini_frame);
 #endif
 
-  val = current_buffer->directory;
+  /* We have to do this after saving the window configuration
+     since that is what restores the current buffer.  */
+
+  /* Arrange to restore a number of minibuffer-related variables.
+     We could bind each variable separately, but that would use lots of
+     specpdl slots.  */
+  minibuf_save_list
+    = Fcons (Voverriding_local_map,
+            Fcons (minibuf_window, minibuf_save_list));
+  minibuf_save_list
+    = Fcons (minibuf_prompt,
+            Fcons (make_number (minibuf_prompt_width),
+                   Fcons (Vhelp_form,
+                          Fcons (Vcurrent_prefix_arg,
+                                 Fcons (Vminibuffer_history_position,
+                                        Fcons (Vminibuffer_history_variable,
+                                               minibuf_save_list))))));
+
+  record_unwind_protect (read_minibuf_unwind, Qnil);
+  minibuf_level++;
+
+  /* Now that we can restore all those variables, start changing them.  */
+
+  minibuf_prompt_width = 0;    /* xdisp.c puts in the right value.  */
+  minibuf_prompt = Fcopy_sequence (prompt);
+  Vminibuffer_history_position = histpos;
+  Vminibuffer_history_variable = histvar;
+  Vhelp_form = Vminibuffer_help_form;
+
+  /* Switch to the minibuffer.  */
+
   Fset_buffer (get_minibuffer (minibuf_level));
 
   /* The current buffer's default directory is usually the right thing
@@ -187,8 +260,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
      up Emacs and buf's default directory is Qnil.  Here's a hack; can
      you think of something better to do?  Find another buffer with a
      better directory, and use that one instead.  */
-  if (STRINGP (val))
-    current_buffer->directory = val;
+  if (STRINGP (ambient_dir))
+    current_buffer->directory = ambient_dir;
   else
     {
       Lisp_Object buf_list;
@@ -212,19 +285,24 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
   if (XFRAME (mini_frame) != selected_frame)
     Fredirect_frame_focus (Fselected_frame (), mini_frame);
 #endif
-  Fmake_local_variable (Qprint_escape_newlines);
-  print_escape_newlines = 1;
-
-  record_unwind_protect (read_minibuf_unwind, Qnil);
 
   Vminibuf_scroll_window = selected_window;
   Fset_window_buffer (minibuf_window, Fcurrent_buffer ());
   Fselect_window (minibuf_window);
   XSETFASTINT (XWINDOW (minibuf_window)->hscroll, 0);
 
-  Ferase_buffer ();
-  minibuf_level++;
+  Fmake_local_variable (Qprint_escape_newlines);
+  print_escape_newlines = 1;
 
+  /* Erase the buffer.  */
+  {
+    int count1 = specpdl_ptr - specpdl;
+    specbind (Qinhibit_read_only, Qt);
+    Ferase_buffer ();
+    unbind_to (count1, Qnil);
+  }
+
+  /* Put in the initial input.  */
   if (!NILP (initial))
     {
       Finsert (1, &initial);
@@ -232,19 +310,15 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
        Fforward_char (backup_n);
     }
 
-  minibuf_prompt = Fcopy_sequence (prompt);
   echo_area_glyphs = 0;
   /* This is in case the minibuffer-setup-hook calls Fsit_for.  */
   previous_echo_glyphs = 0;
 
-  Vhelp_form = Vminibuffer_help_form;
   current_buffer->keymap = map;
-  Vminibuffer_history_position = histpos;
-  Vminibuffer_history_variable = histvar;
 
   /* Run our hook, but not if it is empty.
      (run-hooks would do nothing if it is empty,
-     but it's important to save time here in the usual case.  */
+     but it's important to save time here in the usual case).  */
   if (!NILP (Vminibuffer_setup_hook) && !EQ (Vminibuffer_setup_hook, Qunbound)
       && !NILP (Vrun_hooks))
     call1 (Vrun_hooks, Qminibuffer_setup_hook);
@@ -263,8 +337,10 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
     }
 
   /* Make minibuffer contents into a string */
-  val = make_buffer_string (1, Z);
+  val = make_buffer_string (1, Z, 1);
+#if 0  /* make_buffer_string should handle the gap.  */
   bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT);
+#endif
 
   /* VAL is the string of minibuffer text.  */
   last_minibuf_string = val;
@@ -302,8 +378,9 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
       val = Fcar (expr_and_pos);
     }
 
-  return unbind_to (count, val); /* The appropriate frame will get selected
-                                   in set-window-configuration.  */
+  /* The appropriate frame will get selected
+     in set-window-configuration.  */
+  RETURN_UNGCPRO (unbind_to (count, val));
 }
 
 /* Return a buffer to be used as the minibuffer at depth `depth'.
@@ -359,31 +436,24 @@ read_minibuf_unwind (data)
      Lisp_Object data;
 {
   Lisp_Object old_deactivate_mark;
+  Lisp_Object window;
 
   /* We are exiting the minibuffer one way or the other,
      so run the hook.  */
   if (!NILP (Vminibuffer_exit_hook) && !EQ (Vminibuffer_exit_hook, Qunbound)
       && !NILP (Vrun_hooks))
-    call1 (Vrun_hooks, Qminibuffer_exit_hook);
-
-  /* Erase the minibuffer we were using at this level.  */
-  Fset_buffer (XWINDOW (minibuf_window)->buffer);
-
-  /* Prevent error in erase-buffer.  */
-  current_buffer->read_only = Qnil;
-
-  old_deactivate_mark = Vdeactivate_mark;
-  Ferase_buffer ();
-  Vdeactivate_mark = old_deactivate_mark;
+    safe_run_hooks (Qminibuffer_exit_hook);
 
   /* If this was a recursive minibuffer,
-     tie the minibuffer window back to the outer level minibuffer buffer */
+     tie the minibuffer window back to the outer level minibuffer buffer */
   minibuf_level--;
-  /* Make sure minibuffer window is erased, not ignored */
-  windows_or_buffers_changed++;
-  XSETFASTINT (XWINDOW (minibuf_window)->last_modified, 0);
 
-  /* Restore prompt, etc from outer minibuffer */
+  window = minibuf_window;
+  /* To keep things predictable, in case it matters, let's be in the minibuffer
+     when we reset the relevant variables.  */
+  Fset_buffer (XWINDOW (window)->buffer);
+
+  /* Restore prompt, etc, from outer minibuffer level.  */
   minibuf_prompt = Fcar (minibuf_save_list);
   minibuf_save_list = Fcdr (minibuf_save_list);
   minibuf_prompt_width = XFASTINT (Fcar (minibuf_save_list));
@@ -396,6 +466,25 @@ read_minibuf_unwind (data)
   minibuf_save_list = Fcdr (minibuf_save_list);
   Vminibuffer_history_variable = Fcar (minibuf_save_list);
   minibuf_save_list = Fcdr (minibuf_save_list);
+  Voverriding_local_map = Fcar (minibuf_save_list);
+  minibuf_save_list = Fcdr (minibuf_save_list);
+  minibuf_window = Fcar (minibuf_save_list);
+  minibuf_save_list = Fcdr (minibuf_save_list);
+
+  /* Erase the minibuffer we were using at this level.  */
+  {
+    int count = specpdl_ptr - specpdl;
+    /* Prevent error in erase-buffer.  */
+    specbind (Qinhibit_read_only, Qt);
+    old_deactivate_mark = Vdeactivate_mark;
+    Ferase_buffer ();
+    Vdeactivate_mark = old_deactivate_mark;
+    unbind_to (count, Qnil);
+  }
+
+  /* Make sure minibuffer window is erased, not ignored.  */
+  windows_or_buffers_changed++;
+  XSETFASTINT (XWINDOW (window)->last_modified, 0);
 }
 \f
 
@@ -500,13 +589,16 @@ is a string to insert in the minibuffer before reading.")
 
 /* Functions that use the minibuffer to read various things. */
 
-DEFUN ("read-string", Fread_string, Sread_string, 1, 2, 0,
+DEFUN ("read-string", Fread_string, Sread_string, 1, 3, 0,
   "Read a string from the minibuffer, prompting with string PROMPT.\n\
-If non-nil second arg INITIAL-INPUT is a string to insert before reading.")
-  (prompt, initial_input)
-     Lisp_Object prompt, initial_input;
+If non-nil, second arg INITIAL-INPUT is a string to insert before reading.\n\
+The third arg HISTORY, if non-nil, specifies a history list\n\
+  and optionally the initial position in the list.\n\
+See `read-from-minibuffer' for details of HISTORY argument.")
+  (prompt, initial_input, history)
+     Lisp_Object prompt, initial_input, history;
 {
-  return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, Qnil);
+  return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, history);
 }
 
 DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 2, 0,
@@ -604,9 +696,10 @@ Whatever it returns becomes the value of `try-completion'.\n\
 If optional third argument PREDICATE is non-nil,\n\
 it is used to test each possible match.\n\
 The match is a candidate only if PREDICATE returns non-nil.\n\
-The argument given to PREDICATE is the alist element or the symbol from the obarray.")
-  (string, alist, pred)
-     Lisp_Object string, alist, pred;
+The argument given to PREDICATE is the alist element\n\
+or the symbol from the obarray.")
+  (string, alist, predicate)
+     Lisp_Object string, alist, predicate;
 {
   Lisp_Object bestmatch, tail, elt, eltstring;
   int bestmatchsize;
@@ -619,7 +712,7 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
 
   CHECK_STRING (string, 0);
   if (!list && !VECTORP (alist))
-    return call3 (alist, string, pred, Qnil);
+    return call3 (alist, string, predicate, Qnil);
 
   bestmatch = Qnil;
 
@@ -693,14 +786,14 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
          /* Ignore this element if there is a predicate
             and the predicate doesn't like it. */
 
-         if (!NILP (pred))
+         if (!NILP (predicate))
            {
-             if (EQ (pred, Qcommandp))
+             if (EQ (predicate, Qcommandp))
                tem = Fcommandp (elt);
              else
                {
                  GCPRO4 (tail, string, eltstring, bestmatch);
-                 tem = call1 (pred, elt);
+                 tem = call1 (predicate, elt);
                  UNGCPRO;
                }
              if (NILP (tem)) continue;
@@ -797,10 +890,11 @@ scmp (s1, s2, len)
     return len - l;
 }
 \f
-DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 3, 0,
+DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 4, 0,
   "Search for partial matches to STRING in ALIST.\n\
 Each car of each element of ALIST is tested to see if it begins with STRING.\n\
 The value is a list of all the strings from ALIST that match.\n\
+\n\
 ALIST can be an obarray instead of an alist.\n\
 Then the print names of all symbols in the obarray are the possible matches.\n\
 \n\
@@ -811,9 +905,14 @@ Whatever it returns becomes the value of `all-completion'.\n\
 If optional third argument PREDICATE is non-nil,\n\
 it is used to test each possible match.\n\
 The match is a candidate only if PREDICATE returns non-nil.\n\
-The argument given to PREDICATE is the alist element or the symbol from the obarray.")
-  (string, alist, pred)
-     Lisp_Object string, alist, pred;
+The argument given to PREDICATE is the alist element\n\
+or the symbol from the obarray.\n\
+\n\
+If the optional fourth argument HIDE-SPACES is non-nil,\n\
+strings in ALIST that start with a space\n\
+are ignored unless STRING itself starts with a space.")
+  (string, alist, predicate, hide_spaces)
+     Lisp_Object string, alist, predicate, hide_spaces;
 {
   Lisp_Object tail, elt, eltstring;
   Lisp_Object allmatches;
@@ -825,7 +924,7 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
   CHECK_STRING (string, 0);
   if (!list && !VECTORP (alist))
     {
-      return call3 (alist, string, pred, Qt);
+      return call3 (alist, string, predicate, Qt);
     }
   allmatches = Qnil;
 
@@ -877,10 +976,11 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
 
       if (STRINGP (eltstring)
          && XSTRING (string)->size <= XSTRING (eltstring)->size
-         /* Reject alternatives that start with space
+         /* If HIDE_SPACES, reject alternatives that start with space
             unless the input starts with space.  */
          && ((XSTRING (string)->size > 0 && XSTRING (string)->data[0] == ' ')
-             || XSTRING (eltstring)->data[0] != ' ')
+             || XSTRING (eltstring)->data[0] != ' '
+             || NILP (hide_spaces))
          && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
                       XSTRING (string)->size))
        {
@@ -903,14 +1003,14 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
          /* Ignore this element if there is a predicate
             and the predicate doesn't like it. */
 
-         if (!NILP (pred))
+         if (!NILP (predicate))
            {
-             if (EQ (pred, Qcommandp))
+             if (EQ (predicate, Qcommandp))
                tem = Fcommandp (elt);
              else
                {
                  GCPRO4 (tail, eltstring, allmatches, string);
-                 tem = call1 (pred, elt);
+                 tem = call1 (predicate, elt);
                  UNGCPRO;
                }
              if (NILP (tem)) continue;
@@ -933,7 +1033,6 @@ Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;
 
 DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 6, 0,
   "Read a string in the minibuffer, with completion.\n\
-Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST.\n\
 PROMPT is a string to prompt with; normally it ends in a colon and a space.\n\
 TABLE is an alist whose elements' cars are strings, or an obarray.\n\
 PREDICATE limits completion to a subset of TABLE.\n\
@@ -962,14 +1061,14 @@ Completion ignores case if the ambient value of\n\
 */
 DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 6, 0,
   0 /* See immediately above */)
-  (prompt, table, pred, require_match, init, hist)
-     Lisp_Object prompt, table, pred, require_match, init, hist;
+  (prompt, table, predicate, require_match, init, hist)
+     Lisp_Object prompt, table, predicate, require_match, init, hist;
 {
   Lisp_Object val, histvar, histpos, position;
   int pos = 0;
   int count = specpdl_ptr - specpdl;
   specbind (Qminibuffer_completion_table, table);
-  specbind (Qminibuffer_completion_predicate, pred);
+  specbind (Qminibuffer_completion_predicate, predicate);
   specbind (Qminibuffer_completion_confirm,
            EQ (require_match, Qt) ? Qnil : Qt);
   last_exact_completion = Qnil;
@@ -1024,6 +1123,7 @@ temp_echo_area_glyphs (m)
      char *m;
 {
   int osize = ZV;
+  int opoint = PT;
   Lisp_Object oinhibit;
   oinhibit = Vinhibit_quit;
 
@@ -1032,10 +1132,11 @@ temp_echo_area_glyphs (m)
 
   SET_PT (osize);
   insert_string (m);
-  SET_PT (osize);
+  SET_PT (opoint);
   Vinhibit_quit = Qt;
   Fsit_for (make_number (2), Qnil, Qnil);
-  del_range (PT, ZV);
+  del_range (osize, ZV);
+  SET_PT (opoint);
   if (!NILP (Vquit_flag))
     {
       Vquit_flag = Qnil;
@@ -1197,7 +1298,7 @@ scroll the window of possible completions.")
 
   /* If the previous command was not this, then mark the completion
      buffer obsolete.  */
-  if (! EQ (last_command, this_command))
+  if (! EQ (current_kboard->Vlast_command, this_command))
     Vminibuf_scroll_window = Qnil;
 
   window = Vminibuf_scroll_window;
@@ -1238,6 +1339,26 @@ scroll the window of possible completions.")
 
   return Qt;
 }
+\f
+/* Subroutines of Fminibuffer_complete_and_exit.  */
+
+/* This one is called by internal_condition_case to do the real work.  */
+
+Lisp_Object
+complete_and_exit_1 ()
+{
+  return make_number (do_completion ());
+}
+
+/* This one is called by internal_condition_case if an error happens.
+   Pretend the current value is an exact match.  */
+
+Lisp_Object
+complete_and_exit_2 (ignore)
+     Lisp_Object ignore;
+{
+  return make_number (1);
+}
 
 DEFUN ("minibuffer-complete-and-exit", Fminibuffer_complete_and_exit,
         Sminibuffer_complete_and_exit, 0, 0, "",
@@ -1247,6 +1368,7 @@ a repetition of this command will exit.")
   ()
 {
   register int i;
+  Lisp_Object val;
 
   /* Allow user to specify null string */
   if (BEGV == ZV)
@@ -1255,7 +1377,11 @@ a repetition of this command will exit.")
   if (!NILP (test_completion (Fbuffer_string ())))
     goto exit;
 
-  i = do_completion ();
+  /* Call do_completion, but ignore errors.  */
+  val = internal_condition_case (complete_and_exit_1, Qerror,
+                                complete_and_exit_2);
+
+  i = XFASTINT (val);
   switch (i)
     {
     case 1:
@@ -1428,15 +1554,19 @@ It can find the completion buffer in `standard-output'.")
   (completions)
      Lisp_Object completions;
 {
-  register Lisp_Object tail, elt;
+  Lisp_Object tail, elt;
   register int i;
   int column = 0;
-  struct gcpro gcpro1;
+  struct gcpro gcpro1, gcpro2;
   struct buffer *old = current_buffer;
+  int first = 1;
 
   /* Note that (when it matters) every variable
-     points to a non-string that is pointed to by COMPLETIONS.  */
-  GCPRO1 (completions);
+     points to a non-string that is pointed to by COMPLETIONS,
+     except for ELT.  ELT can be pointing to a string
+     when terpri or Findent_to calls a change hook.  */
+  elt = Qnil;
+  GCPRO2 (completions, elt);
 
   if (BUFFERP (Vstandard_output))
     set_buffer_internal (XBUFFER (Vstandard_output));
@@ -1449,14 +1579,54 @@ It can find the completion buffer in `standard-output'.")
       write_string ("Possible completions are:", -1);
       for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++)
        {
-         /* this needs fixing for the case of long completions
-            and/or narrow windows */
-         /* Sadly, the window it will appear in is not known
-            until after the text has been made. */
-         if (i & 1)
+         Lisp_Object tem;
+         int length;
+         Lisp_Object startpos, endpos;
+
+         elt = Fcar (tail);
+         /* Compute the length of this element.  */
+         if (CONSP (elt))
+           {
+             tem = Fcar (elt);
+             CHECK_STRING (tem, 0);
+             length = XINT (XSTRING (tem)->size);
+
+             tem = Fcar (Fcdr (elt));
+             CHECK_STRING (tem, 0);
+             length += XINT (XSTRING (tem)->size);
+           }
+         else
+           {
+             CHECK_STRING (elt, 0);
+             length = XINT (XSTRING (elt)->size);
+           }
+
+         /* This does a bad job for narrower than usual windows.
+            Sadly, the window it will appear in is not known
+            until after the text has been made.  */
+
+         if (BUFFERP (Vstandard_output))
+           XSETINT (startpos, BUF_PT (XBUFFER (Vstandard_output)));
+
+         /* If the previous completion was very wide,
+            or we have two on this line already,
+            don't put another on the same line.  */
+         if (column > 33 || first
+             /* If this is really wide, don't put it second on a line.  */
+             || column > 0 && length > 45)
+           {
+             Fterpri (Qnil);
+             column = 0;
+           }
+         /* Otherwise advance to column 35.  */
+         else
            {
              if (BUFFERP (Vstandard_output))
-               Findent_to (make_number (35), make_number (2));
+               {
+                 tem = Findent_to (make_number (35), make_number (2));
+                 
+                 column = XINT (tem);
+               }
              else
                {
                  do
@@ -1467,35 +1637,34 @@ It can find the completion buffer in `standard-output'.")
                  while (column < 35);
                }
            }
-         else
+
+         if (BUFFERP (Vstandard_output))
            {
-             Fterpri (Qnil);
-             column = 0;
+             XSETINT (endpos, BUF_PT (XBUFFER (Vstandard_output)));
+             Fset_text_properties (startpos, endpos,
+                                   Qnil, Vstandard_output);
            }
-         elt = Fcar (tail);
+
+         /* Output this element and update COLUMN.  */
          if (CONSP (elt))
            {
-             if (!BUFFERP (Vstandard_output))
-               {
-                 Lisp_Object tem;
-                 tem = Flength (Fcar (elt));
-                 column += XINT (tem);
-                 tem = Flength (Fcar (Fcdr (elt)));
-                 column += XINT (tem);
-               }
              Fprinc (Fcar (elt), Qnil);
              Fprinc (Fcar (Fcdr (elt)), Qnil);
            }
          else
+           Fprinc (elt, Qnil);
+
+         column += length;
+
+         /* If output is to a buffer, recompute COLUMN in a way
+            that takes account of character widths.  */
+         if (BUFFERP (Vstandard_output))
            {
-             if (!BUFFERP (Vstandard_output))
-               {
-                 Lisp_Object tem;
-                 tem = Flength (elt);
-                 column += XINT (tem);
-               }
-             Fprinc (elt, Qnil);
+             tem = Fcurrent_column ();
+             column = XINT (tem);
            }
+
+         first = 0;
        }
     }
 
@@ -1520,7 +1689,8 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co
   message ("Making completion list...");
   completions = Fall_completions (Fbuffer_string (),
                                  Vminibuffer_completion_table,
-                                 Vminibuffer_completion_predicate);
+                                 Vminibuffer_completion_predicate,
+                                 Qt);
   echo_area_glyphs = 0;
 
   if (NILP (completions))
@@ -1675,7 +1845,8 @@ t means to return a list of all possible completions of STRING.\n\
 
   DEFVAR_LISP ("minibuffer-history-variable", &Vminibuffer_history_variable,
     "History list symbol to add minibuffer values to.\n\
-Each minibuffer output is added with\n\
+Each string of minibuffer input, as it appears on exit from the minibuffer,\n\
+is added with\n\
   (set minibuffer-history-variable\n\
        (cons STRING (symbol-value minibuffer-history-variable)))");
   XSETFASTINT (Vminibuffer_history_variable, 0);
@@ -1692,6 +1863,7 @@ Each minibuffer output is added with\n\
     "List of regexps that should restrict possible completions.");
   Vcompletion_regexp_list = Qnil;
 
+  defsubr (&Sset_minibuffer_window);
   defsubr (&Sread_from_minibuffer);
   defsubr (&Seval_minibuffer);
   defsubr (&Sread_minibuffer);