(LD_SWITCH_SYSTEM): Undo previous change.
[bpt/emacs.git] / src / minibuf.c
index 93c9f26..c3209e6 100644 (file)
@@ -1,11 +1,11 @@
 /* Minibuffer input and completion.
-   Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -18,17 +18,19 @@ along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
-#include "config.h"
+#include <config.h>
 #include "lisp.h"
 #include "commands.h"
 #include "buffer.h"
 #include "dispextern.h"
-#include "screen.h"
+#include "frame.h"
 #include "window.h"
 #include "syntax.h"
 
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
+extern int quit_char;
+
 /* List of buffers for use as minibuffers.
   The first element of the list is used for the outermost minibuffer invocation,
   the next element is used for a recursive minibuffer invocation, etc.
@@ -41,6 +43,8 @@ struct minibuf_save_data
     int prompt_width;
     Lisp_Object help_form;
     Lisp_Object current_prefix_arg;
+    Lisp_Object history_position;
+    Lisp_Object history_variable;
   };
 
 int minibuf_save_vector_size;
@@ -52,7 +56,7 @@ int minibuf_level;
 /* Nonzero means display completion help for invalid input */
 int auto_help;
 
-/* Fread_minibuffer leaves the input, as a string, here */
+/* Fread_minibuffer leaves the input here as a string. */
 Lisp_Object last_minibuf_string;
 
 /* Nonzero means let functions called when within a minibuffer 
@@ -63,17 +67,37 @@ int enable_recursive_minibuffers;
 
 Lisp_Object Vminibuffer_help_form;
 
+/* Variable which is the history list to add minibuffer values to.  */
+
+Lisp_Object Vminibuffer_history_variable;
+
+/* Current position in the history list (adjusted by M-n and M-p).  */
+
+Lisp_Object Vminibuffer_history_position;
+
+Lisp_Object Qminibuffer_history;
+
+Lisp_Object Qread_file_name_internal;
+
+/* Normal hook for entry to minibuffer.  */
+
+Lisp_Object Qminibuffer_setup_hook, Vminibuffer_setup_hook;
+
 /* Nonzero means completion ignores case.  */
 
 int completion_ignore_case;
 
+/* Nonzero means raise the minibuffer frame when the minibuffer
+   is entered.  */
+
+int minibuffer_auto_raise;
+
 /* If last completion attempt reported "Complete but not unique"
    then this is the string completed then; otherwise this is nil.  */
 
 static Lisp_Object last_exact_completion;
 
 Lisp_Object Quser_variable_p;
-
 \f
 /* Actual minibuffer invocation. */
 
@@ -81,17 +105,31 @@ void read_minibuf_unwind ();
 Lisp_Object get_minibuffer ();
 Lisp_Object read_minibuf ();
 
+/* Read from the minibuffer using keymap MAP, initial contents INITIAL
+   (a string), putting point minus BACKUP_N chars from the end of INITIAL,
+   prompting with PROMPT (a string), using history list HISTVAR
+   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.
+   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.  */
+
 Lisp_Object
-read_minibuf (map, initial, prompt, backup_n, expflag)
+read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
      Lisp_Object map;
      Lisp_Object initial;
      Lisp_Object prompt;
      Lisp_Object backup_n;
      int expflag;
+     Lisp_Object histvar;
+     Lisp_Object histpos;
 {
   register Lisp_Object val;
   int count = specpdl_ptr - specpdl;
-  Lisp_Object mini_screen = WINDOW_SCREEN (XWINDOW (minibuf_window));
+  Lisp_Object mini_frame;
   struct gcpro gcpro1, gcpro2;
 
   if (XTYPE (prompt) != Lisp_String)
@@ -105,7 +143,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag)
       && minibuf_level > 0
       && (EQ (selected_window, minibuf_window)))
 #if 0
-         || selected_screen != XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)))
+         || selected_frame != XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)))
 #endif
     error ("Command attempted to use minibuffer while in minibuffer");
 
@@ -121,43 +159,68 @@ read_minibuf (map, initial, prompt, backup_n, expflag)
   /* >> Why is this done this way rather than binding these variables? */
   minibuf_save_vector[minibuf_level].help_form = Vhelp_form;
   minibuf_save_vector[minibuf_level].current_prefix_arg = Vcurrent_prefix_arg;
+  minibuf_save_vector[minibuf_level].history_position = Vminibuffer_history_position;
+  minibuf_save_vector[minibuf_level].history_variable = Vminibuffer_history_variable;
   GCPRO2 (minibuf_save_vector[minibuf_level].help_form,
          minibuf_save_vector[minibuf_level].current_prefix_arg);
 
   record_unwind_protect (Fset_window_configuration,
                         Fcurrent_window_configuration (Qnil));
 
-  /* If the minibuffer window is on a different screen, save that
-     screen's configuration too.  */
-  if (XSCREEN (mini_screen) != selected_screen)
-    {
-      record_unwind_protect (Fset_window_configuration,
-                            Fcurrent_window_configuration (mini_screen));
-    }
+  /* If the minibuffer window is on a different frame, save that
+     frame's configuration too.  */
+#ifdef MULTI_FRAME
+  XSET (mini_frame, Lisp_Frame, WINDOW_FRAME (XWINDOW (minibuf_window)));
+  if (XFRAME (mini_frame) != selected_frame)
+    record_unwind_protect (Fset_window_configuration,
+                          Fcurrent_window_configuration (mini_frame));
+
+  /* If the minibuffer is on an iconified or invisible frame,
+     make it visible now.  */
+  Fmake_frame_visible (mini_frame);
+
+  if (minibuffer_auto_raise)
+    Fraise_frame (mini_frame);
+#endif
 
   val = current_buffer->directory;
   Fset_buffer (get_minibuffer (minibuf_level));
-  current_buffer->directory = val;
-  Fmake_local_variable (Qprint_escape_newlines);
-  print_escape_newlines = 1;
 
-#ifdef MULTI_SCREEN
-  /* If the minibuffer window is on another screen, shift this screen's
-     focus to that window, and arrange to put it back later.  */
-  if (XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)))
-      != selected_screen)
+  /* The current buffer's default directory is usually the right thing
+     for our minibuffer here.  However, if you're typing a command at
+     a minibuffer-only frame when minibuf_level is zero, then buf IS
+     the current_buffer, so reset_buffer leaves buf's default
+     directory unchanged.  This is a bummer when you've just started
+     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 (XTYPE (val) == Lisp_String)
+    current_buffer->directory = val;
+  else
     {
-      record_unwind_protect (read_minibuf_unwind,
-                            Fcons (Fselected_screen (),
-                                   SCREEN_FOCUS_SCREEN (selected_screen)));
+      Lisp_Object buf_list;
+
+      for (buf_list = Vbuffer_alist;
+          CONSP (buf_list);
+          buf_list = XCONS (buf_list)->cdr)
+       {
+         Lisp_Object other_buf = XCONS (XCONS (buf_list)->car)->cdr;
 
-      Fredirect_screen_focus (Fselected_screen (), mini_screen);
+         if (XTYPE (XBUFFER (other_buf)->directory) == Lisp_String)
+           {
+             current_buffer->directory = XBUFFER (other_buf)->directory;
+             break;
+           }
+       }
     }
-  else
-    record_unwind_protect (read_minibuf_unwind, Qnil);
-#else
-  record_unwind_protect (read_minibuf_unwind, Qnil);
+
+#ifdef MULTI_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 ());
@@ -180,35 +243,72 @@ read_minibuf (map, initial, prompt, backup_n, expflag)
 
   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.  */
+  if (!NILP (Vminibuffer_setup_hook) && !EQ (Vminibuffer_setup_hook, Qunbound)
+      && !NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qminibuffer_setup_hook);
 
 /* ??? MCC did redraw_screen here if switching screens.  */
   recursive_edit_1 ();
 
   /* If cursor is on the minibuffer line,
      show the user we have exited by putting it in column 0.  */
-  if ((SCREEN_CURSOR_Y (selected_screen)
+  if ((FRAME_CURSOR_Y (selected_frame)
        >= XFASTINT (XWINDOW (minibuf_window)->top))
       && !noninteractive)
     {
-      SCREEN_CURSOR_X (selected_screen) = 0;
-      update_screen (selected_screen, 1, 1);
+      FRAME_CURSOR_X (selected_frame) = 0;
+      update_frame (selected_frame, 1, 1);
     }
 
   /* Make minibuffer contents into a string */
-  val = make_string (BEG_ADDR, Z - BEG);
+  val = make_buffer_string (1, Z);
   bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT);
-  unbind_to (count, Qnil);     /* The appropriate screen will get selected
-                                  in set-window-configuration.  */
-
-  UNGCPRO;
 
   /* VAL is the string of minibuffer text.  */
-
   last_minibuf_string = val;
 
-  /* If Lisp form desired instead of string, parse it */
+  /* Add the value to the appropriate history list.  */
+  if (XTYPE (Vminibuffer_history_variable) == Lisp_Symbol
+      && ! EQ (XSYMBOL (Vminibuffer_history_variable)->value, Qunbound))
+    {
+      /* If the caller wanted to save the value read on a history list,
+        then do so if the value is not already the front of the list.  */
+      Lisp_Object histval;
+      histval = Fsymbol_value (Vminibuffer_history_variable);
+
+      /* The value of the history variable must be a cons or nil.  Other
+        values are unacceptable.  We silently ignore these values.  */
+      if (NILP (histval)
+         || (CONSP (histval)
+             && NILP (Fequal (last_minibuf_string, Fcar (histval)))))
+       Fset (Vminibuffer_history_variable,
+             Fcons (last_minibuf_string, histval));
+    }
+
+  /* If Lisp form desired instead of string, parse it. */
   if (expflag)
-    val = Fread (val);
+    {
+      Lisp_Object expr_and_pos;
+      unsigned char *p;
+
+      expr_and_pos = Fread_from_string (val, Qnil, Qnil);
+      /* Ignore trailing whitespace; any other trailing junk is an error.  */
+      for (p = XSTRING (val)->data + XINT (Fcdr (expr_and_pos)); *p; p++)
+       if (*p != ' ' && *p != '\t' && *p != '\n')
+         error ("Trailing garbage following expression");
+      val = Fcar (expr_and_pos);
+    }
+
+  unbind_to (count, Qnil);     /* The appropriate frame will get selected
+                                  in set-window-configuration.  */
+
+  UNGCPRO;
 
   return val;
 }
@@ -222,7 +322,7 @@ get_minibuffer (depth)
      int depth;
 {
   Lisp_Object tail, num, buf;
-  char name[14];
+  char name[24];
   extern Lisp_Object nconc2 ();
 
   XFASTINT (num) = depth;
@@ -237,10 +337,16 @@ get_minibuffer (depth)
     {
       sprintf (name, " *Minibuf-%d*", depth);
       buf = Fget_buffer_create (build_string (name));
+
+      /* Although the buffer's name starts with a space, undo should be
+        enabled in it.  */
+      Fbuffer_enable_undo (buf);
+
       XCONS (tail)->car = buf;
     }
   else
     reset_buffer (XBUFFER (buf));
+
   return buf;
 }
 
@@ -270,39 +376,61 @@ read_minibuf_unwind (data)
   minibuf_prompt_width = minibuf_save_vector[minibuf_level].prompt_width;
   Vhelp_form = minibuf_save_vector[minibuf_level].help_form;
   Vcurrent_prefix_arg = minibuf_save_vector[minibuf_level].current_prefix_arg;
-
-#ifdef MULTI_SCREEN
-  /* Redirect the focus of the screen that called the minibuffer.  */
-  if (CONSP (data))
-    Fredirect_screen_focus (XCONS (data)->car, XCONS (data)->cdr);
-#endif
+  Vminibuffer_history_position
+    = minibuf_save_vector[minibuf_level].history_position;
+  Vminibuffer_history_variable
+    = minibuf_save_vector[minibuf_level].history_variable;
 }
 \f
+
+/* This comment supplies the doc string for read-from-minibuffer, 
+   for make-docfile to see.  We cannot put this in the real DEFUN
+   due to limits in the Unix cpp.
+
 DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 5, 0,
   "Read a string from the minibuffer, prompting with string PROMPT.\n\
 If optional second arg INITIAL-CONTENTS is non-nil, it is a string\n\
   to be inserted into the minibuffer before reading input.\n\
+  If INITIAL-CONTENTS is (STRING . POSITION), the initial input\n\
+  is STRING, but point is placed POSITION characters into the string.\n\
 Third arg KEYMAP is a keymap to use whilst reading;\n\
   if omitted or nil, the default is `minibuffer-local-map'.\n\
 If fourth arg READ is non-nil, then interpret the result as a lisp object\n\
   and return that object:\n\
   in other words, do `(car (read-from-string INPUT-STRING))'\n\
-Fifth arg POSITION, if non-nil, is where to put point\n\
-  in the minibuffer after inserting INITIAL-CONTENTS.")
-  (prompt, initial_input, keymap, read, position)
-     Lisp_Object prompt, initial_input, keymap, read, position;
+Fifth arg HIST, if non-nil, specifies a history list\n\
+  and optionally the initial position in the list.\n\
+  It can be a symbol, which is the history list variable to use,\n\
+  or it can be a cons cell (HISTVAR . HISTPOS).\n\
+  In that case, HISTVAR is the history list variable to use,\n\
+  and HISTPOS is the initial position (the position in the list\n\
+  which INITIAL-CONTENTS corresponds to).\n\
+  Positions are counted starting from 1 at the beginning of the list."
+*/
+
+DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 5, 0,
+  0 /* See immediately above */)
+  (prompt, initial_contents, keymap, read, hist)
+     Lisp_Object prompt, initial_contents, keymap, read, hist;
 {
   int pos = 0;
+  Lisp_Object histvar, histpos, position;
+  position = Qnil;
 
   CHECK_STRING (prompt, 0);
-  if (!NILP (initial_input))
+  if (!NILP (initial_contents))
     {
-      CHECK_STRING (initial_input, 1);
+      if (XTYPE (initial_contents) == Lisp_Cons)
+       {
+         position = Fcdr (initial_contents);
+         initial_contents = Fcar (initial_contents);
+       }
+      CHECK_STRING (initial_contents, 1);
       if (!NILP (position))
        {
          CHECK_NUMBER (position, 0);
          /* Convert to distance from end of input.  */
-         pos = XINT (position) - 1 - XSTRING (initial_input)->size;
+         pos = XINT (position) - 1 - XSTRING (initial_contents)->size;
        }
     }
 
@@ -310,8 +438,24 @@ Fifth arg POSITION, if non-nil, is where to put point\n\
     keymap = Vminibuffer_local_map;
   else
     keymap = get_keymap (keymap,2);
-  return read_minibuf (keymap, initial_input, prompt,
-                      pos, !NILP (read));
+
+  if (XTYPE (hist) == Lisp_Symbol)
+    {
+      histvar = hist;
+      histpos = Qnil;
+    }
+  else
+    {
+      histvar = Fcar_safe (hist);
+      histpos = Fcdr_safe (hist);
+    }
+  if (NILP (histvar))
+    histvar = Qminibuffer_history;
+  if (NILP (histpos))
+    XFASTINT (histpos) = 0;
+
+  return read_minibuf (keymap, initial_contents, prompt,
+                      make_number (pos), !NILP (read), histvar, histpos);
 }
 
 DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
@@ -323,8 +467,9 @@ is a string to insert in the minibuffer before reading.")
 {
   CHECK_STRING (prompt, 0);
   if (!NILP (initial_contents))
-    CHECK_STRING (initial_contents, 1)
-  return read_minibuf (Vminibuffer_local_map, initial_contents, prompt, Qnil, 1);
+    CHECK_STRING (initial_contents, 1);
+  return read_minibuf (Vminibuffer_local_map, initial_contents,
+                      prompt, Qnil, 1, Qminibuffer_history, make_number (0));
 }
 
 DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
@@ -348,7 +493,7 @@ If non-nil second arg INITIAL-INPUT is a string to insert before reading.")
   return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, Qnil);
 }
 
-DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 2, 1, 0,
+DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 2, 0,
   "Args PROMPT and INIT, strings.  Read a string from the terminal, not allowing blanks.\n\
 Prompt with PROMPT, and provide INIT as an initial value of the input string.")
   (prompt, init)
@@ -358,7 +503,8 @@ Prompt with PROMPT, and provide INIT as an initial value of the input string.")
   if (! NILP (init))
     CHECK_STRING (init, 1);
 
-  return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil, 0);
+  return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil, 0,
+                      Qminibuffer_history, make_number (0));
 }
 
 DEFUN ("read-command", Fread_command, Sread_command, 1, 1, 0,
@@ -696,11 +842,14 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
 
       /* Is this element a possible completion? */
 
-      if (XTYPE (eltstring) == Lisp_String &&
-         XSTRING (string)->size <= XSTRING (eltstring)->size &&
-         XSTRING (eltstring)->data[0] != ' ' &&
-         0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
-                   XSTRING (string)->size))
+      if (XTYPE (eltstring) == Lisp_String
+         && XSTRING (string)->size <= XSTRING (eltstring)->size
+         /* Reject alternatives that start with space
+            unless the input starts with space.  */
+         && ((XSTRING (string)->size > 0 && XSTRING (string)->data[0] == ' ')
+             || XSTRING (eltstring)->data[0] != ' ')
+         && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
+                      XSTRING (string)->size))
        {
          /* Yes. */
          /* Ignore this element if there is a predicate
@@ -730,9 +879,13 @@ Lisp_Object Vminibuffer_completion_table, Qminibuffer_completion_table;
 Lisp_Object Vminibuffer_completion_predicate, Qminibuffer_completion_predicate;
 Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;
 
+/* This comment supplies the doc string for completing-read,
+   for make-docfile to see.  We cannot put this in the real DEFUN
+   due to limits in the Unix cpp.
+
 DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 6, 0,
   "Read a string in the minibuffer, with completion.\n\
-Args are PROMPT, TABLE, PREDICATE, REQUIRE-MATCH and INITIAL-INPUT.\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\
@@ -741,25 +894,70 @@ If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless\n\
  the input is (or completes to) an element of TABLE.\n\
  If it is also not t, Return does not exit if it does non-null completion.\n\
 If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\n\
-Case is ignored if ambient value of `completion-ignore-case' is non-nil.\n\
-If BACKUP-N is specified, point should be placed that many spaces from\n\
-the end of the buffer.  This is useful when providing default values,\n\
-because you can put point before the last component of a filename or any\n\
-other component that is likely to be deleted.")
-  (prompt, table, pred, require_match, init, backup_n)
-     Lisp_Object prompt, table, pred, require_match, init, backup_n;
+  If it is (STRING . POSITION), the initial input\n\
+  is STRING, but point is placed POSITION characters into the string.\n\
+HIST, if non-nil, specifies a history list\n\
+  and optionally the initial position in the list.\n\
+  It can be a symbol, which is the history list variable to use,\n\
+  or it can be a cons cell (HISTVAR . HISTPOS).\n\
+  In that case, HISTVAR is the history list variable to use,\n\
+  and HISTPOS is the initial position (the position in the list\n\
+  which INITIAL-CONTENTS corresponds to).\n\
+  Positions are counted starting from 1 at the beginning of the list.\n\
+Completion ignores case if the ambient value of\n\
+  `completion-ignore-case' is non-nil."
+*/
+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;
 {
-  Lisp_Object val;
+  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_confirm,
            EQ (require_match, Qt) ? Qnil : Qt);
   last_exact_completion = Qnil;
+
+  position = Qnil;
+  if (!NILP (init))
+    {
+      if (XTYPE (init) == Lisp_Cons)
+       {
+         position = Fcdr (init);
+         init = Fcar (init);
+       }
+      CHECK_STRING (init, 0);
+      if (!NILP (position))
+       {
+         CHECK_NUMBER (position, 0);
+         /* Convert to distance from end of input.  */
+         pos = XINT (position) - XSTRING (init)->size;
+       }
+    }
+
+  if (XTYPE (hist) == Lisp_Symbol)
+    {
+      histvar = hist;
+      histpos = Qnil;
+    }
+  else
+    {
+      histvar = Fcar_safe (hist);
+      histpos = Fcdr_safe (hist);
+    }
+  if (NILP (histvar))
+    histvar = Qminibuffer_history;
+  if (NILP (histpos))
+    XFASTINT (histpos) = 0;
+
   val = read_minibuf (NILP (require_match)
                      ? Vminibuffer_local_completion_map
                      : Vminibuffer_local_must_match_map,
-                     init, prompt, backup_n, 0);
+                     init, prompt, make_number (pos), 0,
+                     histvar, histpos);
   return unbind_to (count, val);
 }
 \f
@@ -772,17 +970,12 @@ other component that is likely to be deleted.")
 temp_echo_area_glyphs (m)
      char *m;
 {
-  /* It's not very modular to do things this way, but then it seems
-     to me that the whole echo_area_glyphs thing is a hack anyway.  */
-  extern char *previous_echo_glyphs;
-
   int osize = ZV;
   Lisp_Object oinhibit;
   oinhibit = Vinhibit_quit;
 
-  /* Clear out any old echo-area message to make way for our new
-     thing.  */
-  echo_area_glyphs = previous_echo_glyphs = 0;
+  /* Clear out any old echo-area message to make way for our new thing.  */
+  message (0);
 
   SET_PT (osize);
   insert_string (m);
@@ -793,7 +986,7 @@ temp_echo_area_glyphs (m)
   if (!NILP (Vquit_flag))
     {
       Vquit_flag = Qnil;
-      unread_command_char = Ctl ('g');
+      unread_command_events = Fcons (make_number (quit_char), Qnil);
     }
   Vinhibit_quit = oinhibit;
 }
@@ -921,7 +1114,8 @@ assoc_for_completion (key, list)
 }
 
 DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "",
-  "Complete the minibuffer contents as far as possible.")
+  "Complete the minibuffer contents as far as possible.\n\
+Return nil if there is no valid completion, else t.")
   ()
 {
   register int i = do_completion ();
@@ -984,15 +1178,17 @@ DEFUN ("minibuffer-complete-word", Fminibuffer_complete_word, Sminibuffer_comple
   0, 0, "",
   "Complete the minibuffer contents at most a single word.\n\
 After one word is completed as much as possible, a space or hyphen\n\
-is added, provided that matches some possible completion.")
+is added, provided that matches some possible completion.\n\
+Return nil if there is no valid completion, else t.")
   ()
 {
   Lisp_Object completion, tem;
   register int i;
   register unsigned char *completion_string;
-  /* We keep calling Fbuffer_string
-     rather than arrange for GC to hold onto a pointer to
-     one of the strings thus made.  */
+  struct gcpro gcpro1;
+
+  /* We keep calling Fbuffer_string rather than arrange for GC to
+     hold onto a pointer to one of the strings thus made.  */
 
   completion = Ftry_completion (Fbuffer_string (),
                                Vminibuffer_completion_table,
@@ -1006,7 +1202,7 @@ is added, provided that matches some possible completion.")
   if (EQ (completion, Qt))
     return Qnil;
 
-#if 0 /* How the below code used to look, for reference */
+#if 0 /* How the below code used to look, for reference. */
   tem = Fbuffer_string ();
   b = XSTRING (tem)->data;
   i = ZV - 1 - XSTRING (completion)->size;
@@ -1027,6 +1223,19 @@ is added, provided that matches some possible completion.")
     int buffer_length, completion_length;
 
     tem = Fbuffer_string ();
+    /* If reading a file name,
+       expand any $ENVVAR refs in the buffer and in TEM.  */
+    if (EQ (Vminibuffer_completion_table, Qread_file_name_internal))
+      {
+       Lisp_Object substituted;
+       substituted = Fsubstitute_in_file_name (tem);
+       if (! EQ (substituted, tem))
+         {
+           tem = substituted;
+           Ferase_buffer ();
+           insert_from_string (tem, 0, XSTRING (tem)->size, 0);
+         }
+      }
     buffer_string = XSTRING (tem)->data;
     completion_string = XSTRING (completion)->data;
     buffer_length = XSTRING (tem)->size; /* ie ZV - BEGV */
@@ -1050,19 +1259,26 @@ is added, provided that matches some possible completion.")
   i = ZV - BEGV;
 
   /* If completion finds next char not unique,
-     consider adding a space or a hyphen */
+     consider adding a space or a hyphen. */
   if (i == XSTRING (completion)->size)
     {
+      GCPRO1 (completion);
       tem = Ftry_completion (concat2 (Fbuffer_string (), build_string (" ")),
                             Vminibuffer_completion_table,
                             Vminibuffer_completion_predicate);
+      UNGCPRO;
+
       if (XTYPE (tem) == Lisp_String)
        completion = tem;
       else
        {
-         tem = Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")),
-                                Vminibuffer_completion_table,
-                                Vminibuffer_completion_predicate);
+         GCPRO1 (completion);
+         tem =
+           Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")),
+                            Vminibuffer_completion_table,
+                            Vminibuffer_completion_predicate);
+         UNGCPRO;
+
          if (XTYPE (tem) == Lisp_String)
            completion = tem;
        }
@@ -1070,6 +1286,7 @@ is added, provided that matches some possible completion.")
 
   /* Now find first word-break in the stuff found by completion.
      i gets index in string of where to stop completing.  */
+
   completion_string = XSTRING (completion)->data;
 
   for (; i < XSTRING (completion)->size; i++)
@@ -1089,31 +1306,36 @@ is added, provided that matches some possible completion.")
   /* Otherwise insert in minibuffer the chars we got */
 
   Ferase_buffer ();
-  insert_from_string (completion, 0, i);
+  insert_from_string (completion, 0, i, 1);
   return Qt;
 }
 \f
 DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_list,
        1, 1, 0,
-  "Display in a buffer the list of completions, COMPLETIONS.\n\
+  "Display the list of completions, COMPLETIONS, using `standard-output'.\n\
 Each element may be just a symbol or string\n\
-or may be a list of two strings to be printed as if concatenated.")
+or may be a list of two strings to be printed as if concatenated.\n\
+`standard-output' must be a buffer.\n\
+At the end, run the normal hook `completion-setup-hook'.\n\
+It can find the completion buffer in `standard-output'.")
   (completions)
      Lisp_Object completions;
 {
   register Lisp_Object tail, elt;
   register int i;
-  struct buffer *old = current_buffer;
+  int column = 0;
   /* No GCPRO needed, since (when it matters) every variable
      points to a non-string that is pointed to by COMPLETIONS.  */
-
-  set_buffer_internal (XBUFFER (Vstandard_output));
+  struct buffer *old = current_buffer;
+  if (XTYPE (Vstandard_output) == Lisp_Buffer)
+    set_buffer_internal (XBUFFER (Vstandard_output));
 
   if (NILP (completions))
-    insert_string ("There are no possible completions of what you have typed.");
+    write_string ("There are no possible completions of what you have typed.",
+                 -1);
   else
     {
-      insert_string ("Possible completions are:");
+      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
@@ -1121,20 +1343,57 @@ or may be a list of two strings to be printed as if concatenated.")
          /* Sadly, the window it will appear in is not known
             until after the text has been made. */
          if (i & 1)
-           Findent_to (make_number (35), make_number (1));
+           {
+             if (XTYPE (Vstandard_output) == Lisp_Buffer)
+               Findent_to (make_number (35), make_number (1));
+             else
+               {
+                 do
+                   {
+                     write_string (" ", -1);
+                     column++;
+                   }
+                 while (column < 35);
+               }
+           }
          else
-           Fterpri (Qnil);
+           {
+             Fterpri (Qnil);
+             column = 0;
+           }
          elt = Fcar (tail);
          if (CONSP (elt))
            {
+             if (XTYPE (Vstandard_output) != Lisp_Buffer)
+               {
+                 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);
+           {
+             if (XTYPE (Vstandard_output) != Lisp_Buffer)
+               {
+                 Lisp_Object tem;
+                 tem = Flength (elt);
+                 column += XINT (tem);
+               }
+             Fprinc (elt, Qnil);
+           }
        }
     }
-  set_buffer_internal (old);
+
+  if (XTYPE (Vstandard_output) == Lisp_Buffer)
+    set_buffer_internal (old);
+
+  if (!NILP (Vrun_hooks))
+    call1 (Vrun_hooks, intern ("completion-setup-hook"));
+
   return Qnil;
 }
 
@@ -1203,6 +1462,9 @@ syms_of_minibuf ()
   minibuf_save_vector_size = 5;
   minibuf_save_vector = (struct minibuf_save_data *) malloc (5 * sizeof (struct minibuf_save_data));
 
+  Qread_file_name_internal = intern ("read-file-name-internal");
+  staticpro (&Qread_file_name_internal);
+
   Qminibuffer_completion_table = intern ("minibuffer-completion-table");
   staticpro (&Qminibuffer_completion_table);
 
@@ -1218,7 +1480,15 @@ syms_of_minibuf ()
   Quser_variable_p = intern ("user-variable-p");
   staticpro (&Quser_variable_p);
 
+  Qminibuffer_history = intern ("minibuffer-history");
+  staticpro (&Qminibuffer_history);
+
+  Qminibuffer_setup_hook = intern ("minibuffer-setup-hook");
+  staticpro (&Qminibuffer_setup_hook);
 
+  DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook, 
+    "Normal hook run just after entry to minibuffer.");
+  Vminibuffer_setup_hook = Qnil;
 
   DEFVAR_BOOL ("completion-auto-help", &auto_help,
     "*Non-nil means automatically provide help for invalid completion input.");
@@ -1261,6 +1531,21 @@ t means to return a list of all possible completions of STRING.\n\
     "Value that `help-form' takes on inside the minibuffer.");
   Vminibuffer_help_form = Qnil;
 
+  DEFVAR_LISP ("minibuffer-history-variable", &Vminibuffer_history_variable,
+    "History list symbol to add minibuffer values to.\n\
+Each minibuffer output is added with\n\
+  (set minibuffer-history-variable\n\
+       (cons STRING (symbol-value minibuffer-history-variable)))");
+  XFASTINT (Vminibuffer_history_variable) = 0;
+
+  DEFVAR_LISP ("minibuffer-history-position", &Vminibuffer_history_position,
+    "Current position of redoing in the history list.");
+  Vminibuffer_history_position = Qnil;
+
+  DEFVAR_BOOL ("minibuffer-auto-raise", &minibuffer_auto_raise,
+    "*Non-nil means entering the minibuffer raises the minibuffer's frame.");
+  minibuffer_auto_raise = 0;
+
   defsubr (&Sread_from_minibuffer);
   defsubr (&Seval_minibuffer);
   defsubr (&Sread_minibuffer);