]> code.delx.au - gnu-emacs/blobdiff - src/minibuf.c
(Fmake_network_process): Only support server sockets
[gnu-emacs] / src / minibuf.c
index 5edd58e3a89cfaf76b26012ec416d9f948511410..388c912292c5e3a405d411a832ea25013b9610d3 100644 (file)
@@ -1,6 +1,6 @@
 /* Minibuffer input and completion.
-   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-         Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include <stdio.h>
+
 #include "lisp.h"
 #include "commands.h"
 #include "buffer.h"
@@ -31,8 +32,8 @@ Boston, MA 02111-1307, USA.  */
 #include "frame.h"
 #include "window.h"
 #include "syntax.h"
-
-#define min(a, b) ((a) < (b) ? (a) : (b))
+#include "intervals.h"
+#include "keymap.h"
 
 extern int quit_char;
 
@@ -86,6 +87,12 @@ Lisp_Object Vminibuffer_history_variable;
 
 Lisp_Object Vminibuffer_history_position;
 
+/* Text properties that are added to minibuffer prompts.
+   These are in addition to the basic `field' property, and stickiness
+   properties.  */
+
+Lisp_Object Vminibuffer_prompt_properties;
+
 Lisp_Object Qminibuffer_history, Qbuffer_name_history;
 
 Lisp_Object Qread_file_name_internal;
@@ -116,11 +123,6 @@ int minibuffer_auto_raise;
 
 static Lisp_Object last_exact_completion;
 
-/* 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;
 
 Lisp_Object Quser_variable_p;
@@ -186,13 +188,13 @@ choose_minibuf_frame_1 (ignore)
 
 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)
+       doc: /* Specify which minibuffer window to use for the minibuffer.
+This effects where the minibuffer is displayed if you put text in it
+without invoking the usual minibuffer commands.  */)
+     (window)
      Lisp_Object window;
 {
-  CHECK_WINDOW (window, 1);
+  CHECK_WINDOW (window);
   if (! MINI_WINDOW_P (XWINDOW (window)))
     error ("Window is not a minibuffer window");
 
@@ -317,6 +319,55 @@ read_minibuf_noninteractive (map, initial, prompt, backup_n, expflag,
 }
 
 
+DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end,
+       Sminibuffer_prompt_end, 0, 0, 0,
+       doc: /* Return the buffer position of the end of the minibuffer prompt.
+Return (point-min) if current buffer is not a mini-buffer.  */)
+     ()
+{
+  /* This function is written to be most efficient when there's a prompt.  */
+  Lisp_Object beg = make_number (BEGV);
+  Lisp_Object end = Ffield_end (beg, Qnil, Qnil);
+  
+  if (XINT (end) == ZV && NILP (Fget_char_property (beg, Qfield, Qnil)))
+    return beg;
+  else
+    return end;
+}
+
+DEFUN ("minibuffer-contents", Fminibuffer_contents,
+       Sminibuffer_contents, 0, 0, 0,
+       doc: /* Return the user input in a minibuffer as a string.
+The current buffer must be a minibuffer.  */)
+     ()
+{
+  int prompt_end = XINT (Fminibuffer_prompt_end ());
+  return make_buffer_string (prompt_end, ZV, 1);
+}
+
+DEFUN ("minibuffer-contents-no-properties", Fminibuffer_contents_no_properties,
+       Sminibuffer_contents_no_properties, 0, 0, 0,
+       doc: /* Return the user input in a minibuffer as a string, without text-properties.
+The current buffer must be a minibuffer.  */)
+     ()
+{
+  int prompt_end = XINT (Fminibuffer_prompt_end ());
+  return make_buffer_string (prompt_end, ZV, 0);
+}
+
+DEFUN ("delete-minibuffer-contents", Fdelete_minibuffer_contents,
+       Sdelete_minibuffer_contents, 0, 0, 0,
+       doc: /* Delete all user input in a minibuffer.
+The current buffer must be a minibuffer.  */)
+     ()
+{
+  int prompt_end = XINT (Fminibuffer_prompt_end ());
+  if (prompt_end < ZV)
+    del_range (prompt_end, ZV);
+  return Qnil;
+}
+
+
 /* Read from the minibuffer using keymap MAP, initial contents INITIAL
    (a string), putting point minus BACKUP_N bytes from the end of INITIAL,
    prompting with PROMPT (a string), using history list HISTVAR
@@ -354,15 +405,15 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   Lisp_Object mini_frame, ambient_dir, minibuffer, input_method;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   Lisp_Object enable_multibyte;
-  extern Lisp_Object Qread_only, Qfront_sticky;
+  extern Lisp_Object Qfront_sticky;
   extern Lisp_Object Qrear_nonsticky;
 
   specbind (Qminibuffer_default, defalt);
 
   single_kboard_state ();
 #ifdef HAVE_X_WINDOWS
-  if (display_busy_cursor_p)
-    cancel_busy_cursor ();
+  if (display_hourglass_p)
+    cancel_hourglass ();
 #endif
 
   val = Qnil;
@@ -376,7 +427,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   GCPRO5 (map, initial, val, ambient_dir, input_method);
 
   if (!STRINGP (prompt))
-    prompt = build_string ("");
+    prompt = empty_string;
 
   if (!enable_recursive_minibuffers
       && minibuf_level > 0)
@@ -390,9 +441,12 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
     }
 
   if (noninteractive)
-    return read_minibuf_noninteractive (map, initial, prompt, backup_n,
-                                       expflag, histvar, histpos, defalt,
-                                       allow_props, inherit_input_method);
+    {
+      val = read_minibuf_noninteractive (map, initial, prompt, backup_n,
+                                        expflag, histvar, histpos, defalt,
+                                        allow_props, inherit_input_method);
+      return unbind_to (count, val);
+    }
 
   /* Choose the minibuffer window and frame, and take action on them.  */
 
@@ -448,7 +502,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
 
   if (inherit_input_method)
     {
-      /* `current-input-method' is buffer local.  So, remeber it in
+      /* `current-input-method' is buffer local.  So, remember it in
         INPUT_METHOD before changing the current buffer.  */
       input_method = Fsymbol_value (Qcurrent_input_method);
       enable_multibyte = current_buffer->enable_multibyte_characters;
@@ -492,6 +546,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
     Fredirect_frame_focus (selected_frame, mini_frame);
 
   Vminibuf_scroll_window = selected_window;
+  if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
+    minibuf_selected_window = selected_window;
   Fset_window_buffer (minibuf_window, Fcurrent_buffer ());
   Fselect_window (minibuf_window);
   XSETFASTINT (XWINDOW (minibuf_window)->hscroll, 0);
@@ -501,8 +557,9 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
 
   /* Erase the buffer.  */
   {
-    int count1 = specpdl_ptr - specpdl;
+    int count1 = BINDING_STACK_SIZE ();
     specbind (Qinhibit_read_only, Qt);
+    specbind (Qinhibit_modification_hooks, Qt);
     Ferase_buffer ();
     unbind_to (count1, Qnil);
   }
@@ -521,8 +578,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
                          Qrear_nonsticky, Qt, Qnil);
       Fput_text_property (make_number (BEG), make_number (PT),
                          Qfield, Qt, Qnil);
-      Fput_text_property (make_number (BEG), make_number (PT),
-                         Qread_only, Qt, Qnil);
+      Fadd_text_properties (make_number (BEG), make_number (PT),
+                           Vminibuffer_prompt_properties, Qnil);
     }
   
   minibuf_prompt_width = current_column ();
@@ -548,11 +605,14 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
 
   /* 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);
 
+  /* Don't allow the user to undo past this point.  */
+  current_buffer->undo_list = Qnil;
+
   recursive_edit_1 ();
 
   /* If cursor is on the minibuffer line,
@@ -571,9 +631,9 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   /* Make minibuffer contents into a string.  */
   Fset_buffer (minibuffer);
   if (allow_props)
-    val = Ffield_string (make_number (ZV));
+    val = Fminibuffer_contents ();
   else
-    val = Ffield_string_no_properties (make_number (ZV));
+    val = Fminibuffer_contents_no_properties ();
 
   /* VAL is the string of minibuffer text.  */
 
@@ -588,7 +648,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
       Lisp_Object histval;
 
       /* If variable is unbound, make it nil.  */
-      if (EQ (XSYMBOL (Vminibuffer_history_variable)->value, Qunbound))
+      if (EQ (SYMBOL_VALUE (Vminibuffer_history_variable), Qunbound))
        Fset (Vminibuffer_history_variable, Qnil);
 
       histval = Fsymbol_value (Vminibuffer_history_variable);
@@ -660,7 +720,7 @@ get_minibuffer (depth)
         enabled in it.  */
       Fbuffer_enable_undo (buf);
 
-      XCAR (tail) = buf;
+      XSETCAR (tail, buf);
     }
   else
     {
@@ -728,6 +788,7 @@ read_minibuf_unwind (data)
     int count = specpdl_ptr - specpdl;
     /* Prevent error in erase-buffer.  */
     specbind (Qinhibit_read_only, Qt);
+    specbind (Qinhibit_modification_hooks, Qt);
     old_deactivate_mark = Vdeactivate_mark;
     Ferase_buffer ();
     Vdeactivate_mark = old_deactivate_mark;
@@ -747,43 +808,34 @@ read_minibuf_unwind (data)
 }
 \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, 7, 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 at position POSITION in the minibuffer.\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 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\
-Sixth arg DEFAULT-VALUE is the default value.  If non-nil, it is available\n\
- for history commands; but `read-from-minibuffer' does NOT return DEFAULT-VALUE\n\
- if the user enters empty input!  It returns the empty string.\n\
-Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\
- the current input method and the setting of enable-multibyte-characters.\n\
-If the variable `minibuffer-allow-text-properties' is non-nil,\n\
- then the string which is returned includes whatever text properties\n\
- were present in the minibuffer.  Otherwise the value has no text properties.")
-  (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
-  */
-
 DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0,
-  0 /* See immediately above */)
-  (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
+       doc: /* Read a string from the minibuffer, prompting with string PROMPT.
+If optional second arg INITIAL-CONTENTS is non-nil, it is a string
+  to be inserted into the minibuffer before reading input.
+  If INITIAL-CONTENTS is (STRING . POSITION), the initial input
+  is STRING, but point is placed at position POSITION in the minibuffer.
+Third arg KEYMAP is a keymap to use whilst reading;
+  if omitted or nil, the default is `minibuffer-local-map'.
+If fourth arg READ is non-nil, then interpret the result as a Lisp object
+  and return that object:
+  in other words, do `(car (read-from-string INPUT-STRING))'
+Fifth arg HIST, if non-nil, specifies a history list
+  and optionally the initial position in the list.
+  It can be a symbol, which is the history list variable to use,
+  or it can be a cons cell (HISTVAR . HISTPOS).
+  In that case, HISTVAR is the history list variable to use,
+  and HISTPOS is the initial position (the position in the list
+  which INITIAL-CONTENTS corresponds to).
+  Positions are counted starting from 1 at the beginning of the list.
+Sixth arg DEFAULT-VALUE is the default value.  If non-nil, it is available
+ for history commands; but `read-from-minibuffer' does NOT return DEFAULT-VALUE
+ if the user enters empty input!  It returns the empty string.
+Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
+ the current input method and the setting of `enable-multibyte-characters'.
+If the variable `minibuffer-allow-text-properties' is non-nil,
+ then the string which is returned includes whatever text properties
+ were present in the minibuffer.  Otherwise the value has no text properties.  */)
+     (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
      Lisp_Object prompt, initial_contents, keymap, read, hist, default_value;
      Lisp_Object inherit_input_method;
 {
@@ -793,7 +845,7 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1,
 
   position = Qnil;
 
-  CHECK_STRING (prompt, 0);
+  CHECK_STRING (prompt);
   if (!NILP (initial_contents))
     {
       if (CONSP (initial_contents))
@@ -801,10 +853,10 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1,
          position = Fcdr (initial_contents);
          initial_contents = Fcar (initial_contents);
        }
-      CHECK_STRING (initial_contents, 1);
+      CHECK_STRING (initial_contents);
       if (!NILP (position))
        {
-         CHECK_NUMBER (position, 0);
+         CHECK_NUMBER (position);
          /* Convert to distance from end of input.  */
          if (XINT (position) < 1)
            /* A number too small means the beginning of the string.  */
@@ -817,7 +869,7 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1,
   if (NILP (keymap))
     keymap = Vminibuffer_local_map;
   else
-    keymap = get_keymap (keymap);
+    keymap = get_keymap (keymap, 1, 0);
 
   if (SYMBOLP (hist))
     {
@@ -845,25 +897,25 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1,
 }
 
 DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
-  "Return a Lisp object read using the minibuffer.\n\
-Prompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS\n\
-is a string to insert in the minibuffer before reading.")
-  (prompt, initial_contents)
+       doc: /* Return a Lisp object read using the minibuffer.
+Prompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS
+is a string to insert in the minibuffer before reading.  */)
+     (prompt, initial_contents)
      Lisp_Object prompt, initial_contents;
 {
-  CHECK_STRING (prompt, 0);
+  CHECK_STRING (prompt);
   if (!NILP (initial_contents))
-    CHECK_STRING (initial_contents, 1);
+    CHECK_STRING (initial_contents);
   return read_minibuf (Vminibuffer_local_map, initial_contents,
                       prompt, Qnil, 1, Qminibuffer_history,
                       make_number (0), Qnil, 0, 0);
 }
 
 DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
-  "Return value of Lisp expression read using the minibuffer.\n\
-Prompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS\n\
-is a string to insert in the minibuffer before reading.")
-  (prompt, initial_contents)
+       doc: /* Return value of Lisp expression read using the minibuffer.
+Prompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS
+is a string to insert in the minibuffer before reading.  */)
+     (prompt, initial_contents)
      Lisp_Object prompt, initial_contents;
 {
   return Feval (Fread_minibuffer (prompt, initial_contents));
@@ -872,17 +924,17 @@ 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, 5, 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.\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.\n\
-Fourth arg DEFAULT-VALUE is the default value.  If non-nil, it is used\n\
- for history commands, and as the value to return if the user enters\n\
- the empty string.\n\
-Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\
- the current input method and the setting of enable-multibyte-characters.")
-  (prompt, initial_input, history, default_value, inherit_input_method)
+       doc: /* Read a string from the minibuffer, prompting with string PROMPT.
+If non-nil, second arg INITIAL-INPUT is a string to insert before reading.
+The third arg HISTORY, if non-nil, specifies a history list
+  and optionally the initial position in the list.
+See `read-from-minibuffer' for details of HISTORY argument.
+Fourth arg DEFAULT-VALUE is the default value.  If non-nil, it is used
+ for history commands, and as the value to return if the user enters
+ the empty string.
+Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
+ the current input method and the setting of `enable-multibyte-characters'.  */)
+     (prompt, initial_input, history, default_value, inherit_input_method)
      Lisp_Object prompt, initial_input, history, default_value;
      Lisp_Object inherit_input_method;
 {
@@ -896,16 +948,16 @@ Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\
 }
 
 DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 3, 0,
-  "Read a string from the terminal, not allowing blanks.\n\
-Prompt with PROMPT, and provide INITIAL as an initial value of the input string.\n\
-Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\
-the current input method and the setting of enable-multibyte-characters.")
-  (prompt, initial, inherit_input_method)
+       doc: /* Read a string from the terminal, not allowing blanks.
+Prompt with PROMPT, and provide INITIAL as an initial value of the input string.
+Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
+the current input method and the setting of `enable-multibyte-characters'.  */)
+     (prompt, initial, inherit_input_method)
      Lisp_Object prompt, initial, inherit_input_method;
 {
-  CHECK_STRING (prompt, 0);
+  CHECK_STRING (prompt);
   if (! NILP (initial))
-    CHECK_STRING (initial, 1);
+    CHECK_STRING (initial);
 
   return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, Qnil,
                       0, Qminibuffer_history, make_number (0), Qnil, 0,
@@ -913,9 +965,9 @@ the current input method and the setting of enable-multibyte-characters.")
 }
 
 DEFUN ("read-command", Fread_command, Sread_command, 1, 2, 0,
-  "Read the name of a command and return as a symbol.\n\
-Prompts with PROMPT.  By default, return DEFAULT-VALUE.")
-  (prompt, default_value)
+       doc: /* Read the name of a command and return as a symbol.
+Prompt with PROMPT.  By default, return DEFAULT-VALUE.  */)
+     (prompt, default_value)
      Lisp_Object prompt, default_value;
 {
   Lisp_Object name, default_string;
@@ -936,9 +988,9 @@ Prompts with PROMPT.  By default, return DEFAULT-VALUE.")
 
 #ifdef NOTDEF
 DEFUN ("read-function", Fread_function, Sread_function, 1, 1, 0,
-  "One arg PROMPT, a string.  Read the name of a function and return as a symbol.\n\
-Prompts with PROMPT.")
-  (prompt)
+       doc: /* One arg PROMPT, a string.  Read the name of a function and return as a symbol.
+Prompt with PROMPT.  */)
+     (prompt)
      Lisp_Object prompt;
 {
   return Fintern (Fcompleting_read (prompt, Vobarray, Qfboundp, Qt, Qnil, Qnil, Qnil, Qnil),
@@ -947,10 +999,10 @@ Prompts with PROMPT.")
 #endif /* NOTDEF */
 
 DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0,
-  "Read the name of a user variable and return it as a symbol.\n\
-Prompts with PROMPT.  By default, return DEFAULT-VALUE.\n\
-A user variable is one whose documentation starts with a `*' character.")
-  (prompt, default_value)
+       doc: /* Read the name of a user variable and return it as a symbol.
+Prompt with PROMPT.  By default, return DEFAULT-VALUE.
+A user variable is one whose documentation starts with a `*' character.  */)
+     (prompt, default_value)
      Lisp_Object prompt, default_value;
 {
   Lisp_Object name, default_string;
@@ -971,11 +1023,12 @@ A user variable is one whose documentation starts with a `*' character.")
 }
 
 DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0,
-  "One arg PROMPT, a string.  Read the name of a buffer and return as a string.\n\
-Prompts with PROMPT.\n\
-Optional second arg DEF is value to return if user enters an empty line.\n\
-If optional third arg REQUIRE-MATCH is non-nil, only existing buffer names are allowed.")
-  (prompt, def, require_match)
+       doc: /* Read the name of a buffer and return as a string.
+Prompt with PROMPT.
+Optional second arg DEF is value to return if user enters an empty line.
+If optional third arg REQUIRE-MATCH is non-nil,
+ only existing buffer names are allowed.  */)
+     (prompt, def, require_match)
      Lisp_Object prompt, def, require_match;
 {
   Lisp_Object args[4];
@@ -1021,28 +1074,28 @@ minibuf_conform_representation (string, basis)
 }
 
 DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0,
-  "Return common substring of all completions of STRING in ALIST.\n\
-Each car of each element of ALIST is tested to see if it begins with STRING.\n\
-All that match are compared together; the longest initial sequence\n\
-common to all matches is returned as a string.\n\
-If there is no match at all, nil is returned.\n\
-For a unique match which is exact, t is returned.\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\
-ALIST can also be a function to do the completion itself.\n\
-It receives three arguments: the values STRING, PREDICATE and nil.\n\
-Whatever it returns becomes the value of `try-completion'.\n\
-\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\n\
-or the symbol from the obarray.\n\
-Additionally to this predicate, `completion-regexp-list'\n\
-is used to further constrain the set of candidates.")
-  (string, alist, predicate)
+       doc: /* Return common substring of all completions of STRING in ALIST.
+Each car of each element of ALIST is tested to see if it begins with STRING.
+All that match are compared together; the longest initial sequence
+common to all matches is returned as a string.
+If there is no match at all, nil is returned.
+For a unique match which is exact, t is returned.
+
+ALIST can be an obarray instead of an alist.
+Then the print names of all symbols in the obarray are the possible matches.
+
+ALIST can also be a function to do the completion itself.
+It receives three arguments: the values STRING, PREDICATE and nil.
+Whatever it returns becomes the value of `try-completion'.
+
+If optional third argument PREDICATE is non-nil,
+it is used to test each possible match.
+The match is a candidate only if PREDICATE returns non-nil.
+The argument given to PREDICATE is the alist element
+or the symbol from the obarray.
+Additionally to this predicate, `completion-regexp-list'
+is used to further constrain the set of candidates.  */)
+     (string, alist, predicate)
      Lisp_Object string, alist, predicate;
 {
   Lisp_Object bestmatch, tail, elt, eltstring;
@@ -1050,13 +1103,15 @@ is used to further constrain the set of candidates.")
   int bestmatchsize = 0;
   /* These are in bytes, too.  */
   int compare, matchsize;
-  int list = CONSP (alist) || NILP (alist);
+  int list = NILP (alist) || (CONSP (alist)
+                             && (!SYMBOLP (XCAR (alist))
+                                 || NILP (XCAR (alist))));
   int index = 0, obsize = 0;
   int matchcount = 0;
   Lisp_Object bucket, zero, end, tem;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
-  CHECK_STRING (string, 0);
+  CHECK_STRING (string);
   if (!list && !VECTORP (alist))
     return call3 (alist, string, predicate, Qnil);
 
@@ -1080,11 +1135,11 @@ is used to further constrain the set of candidates.")
 
       if (list)
        {
-         if (NILP (tail))
+         if (!CONSP (tail))
            break;
-         elt = Fcar (tail);
-         eltstring = Fcar (elt);
-         tail = Fcdr (tail);
+         elt = XCAR (tail);
+         eltstring = CONSP (elt) ? XCAR (elt) : elt;
+         tail = XCDR (tail);
        }
       else
        {
@@ -1138,7 +1193,7 @@ is used to further constrain the set of candidates.")
          if (!NILP (predicate))
            {
              if (EQ (predicate, Qcommandp))
-               tem = Fcommandp (elt);
+               tem = Fcommandp (elt, Qnil);
              else
                {
                  GCPRO4 (tail, string, eltstring, bestmatch);
@@ -1172,6 +1227,7 @@ is used to further constrain the set of candidates.")
                matchsize = XINT (tem) - 1;
 
              if (matchsize < 0)
+               /* When can this happen ?  -stef  */
                matchsize = compare;
              if (completion_ignore_case)
                {
@@ -1206,6 +1262,10 @@ is used to further constrain the set of candidates.")
                    bestmatch = eltstring;
                }
              bestmatchsize = matchsize;
+             if (matchsize <= XSTRING (string)->size
+                 && matchcount > 1)
+               /* No need to look any further.  */
+               break;
            }
        }
     }
@@ -1234,77 +1294,43 @@ is used to further constrain the set of candidates.")
   XSETFASTINT (end, bestmatchsize);    /* all completions agree */
   return Fsubstring (bestmatch, zero, end);
 }
-
-/* Compare exactly LEN chars of strings at S1 and S2,
-   ignoring case if appropriate.
-   Return -1 if strings match,
-   else number of chars that match at the beginning.  */
-
-int
-scmp (s1, s2, len)
-     register unsigned char *s1, *s2;
-     int len;
-{
-  register int l = len;
-
-  if (completion_ignore_case)
-    {
-      while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
-       l--;
-    }
-  else
-    {
-      while (l && *s1++ == *s2++)
-       l--;
-    }
-  if (l == 0)
-    return -1;
-  else
-    {
-      int match = len - l;
-
-      /* Now *--S1 is the unmatching byte.  If it is in the middle of
-         multi-byte form, we must say that the multi-byte character
-         there doesn't match.  */
-      while (match && *--s1 >= 0xA0) match--;
-      return match;
-    }
-}
 \f
 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\
-ALIST can also be a function to do the completion itself.\n\
-It receives three arguments: the values STRING, PREDICATE and t.\n\
-Whatever it returns becomes the value of `all-completions'.\n\
-\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\n\
-or the symbol from the obarray.\n\
-Additionally to this predicate, `completion-regexp-list'\n\
-is used to further constrain the set of candidates.\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)
+       doc: /* Search for partial matches to STRING in ALIST.
+Each car of each element of ALIST is tested to see if it begins with STRING.
+The value is a list of all the strings from ALIST that match.
+
+ALIST can be an obarray instead of an alist.
+Then the print names of all symbols in the obarray are the possible matches.
+
+ALIST can also be a function to do the completion itself.
+It receives three arguments: the values STRING, PREDICATE and t.
+Whatever it returns becomes the value of `all-completions'.
+
+If optional third argument PREDICATE is non-nil,
+it is used to test each possible match.
+The match is a candidate only if PREDICATE returns non-nil.
+The argument given to PREDICATE is the alist element
+or the symbol from the obarray.
+Additionally to this predicate, `completion-regexp-list'
+is used to further constrain the set of candidates.
+
+If the optional fourth argument HIDE-SPACES is non-nil,
+strings in ALIST that start with a space
+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;
-  int list = CONSP (alist) || NILP (alist);
+  int list = NILP (alist) || (CONSP (alist)
+                             && (!SYMBOLP (XCAR (alist))
+                                 || NILP (XCAR (alist))));
   int index = 0, obsize = 0;
   Lisp_Object bucket, tem;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
-  CHECK_STRING (string, 0);
+  CHECK_STRING (string);
   if (!list && !VECTORP (alist))
     {
       return call3 (alist, string, predicate, Qt);
@@ -1329,11 +1355,11 @@ are ignored unless STRING itself starts with a space.")
 
       if (list)
        {
-         if (NILP (tail))
+         if (!CONSP (tail))
            break;
-         elt = Fcar (tail);
-         eltstring = Fcar (elt);
-         tail = Fcdr (tail);
+         elt = XCAR (tail);
+         eltstring = CONSP (elt) ? XCAR (elt) : elt;
+         tail = XCDR (tail);
        }
       else
        {
@@ -1394,7 +1420,7 @@ are ignored unless STRING itself starts with a space.")
          if (!NILP (predicate))
            {
              if (EQ (predicate, Qcommandp))
-               tem = Fcommandp (elt);
+               tem = Fcommandp (elt, Qnil);
              else
                {
                  GCPRO4 (tail, eltstring, allmatches, string);
@@ -1416,47 +1442,44 @@ Lisp_Object Vminibuffer_completion_predicate, Qminibuffer_completion_predicate;
 Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;
 Lisp_Object Vminibuffer_completing_file_name;
 
-/* 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, 8, 0,
-  "Read a string in the minibuffer, with completion.\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\
-TABLE can also be a function to do the completion itself.\n\
-PREDICATE limits completion to a subset of TABLE.\n\
-See `try-completion' and `all-completions' for more details\n\
- on completion, TABLE, and PREDICATE.\n\
-\n\
-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 or is null.\n\
- If it is also not t, Return does not exit if it does non-null completion.\n\
-If the input is null, `completing-read' returns an empty string,\n\
- regardless of the value of REQUIRE-MATCH.\n\
-\n\
-If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\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-INPUT corresponds to).\n\
-  Positions are counted starting from 1 at the beginning of the list.\n\
-DEF, if non-nil, is the default value.\n\
-\n\
-If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits\n\
-  the current input method and the setting of enable-multibyte-characters.\n\
-\n\
-Completion ignores case if the ambient value of\n\
-  `completion-ignore-case' is non-nil."
-*/
 DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
-  0 /* See immediately above */)
-  (prompt, table, predicate, require_match, initial_input, hist, def, inherit_input_method)
+       doc: /* Read a string in the minibuffer, with completion.
+PROMPT is a string to prompt with; normally it ends in a colon and a space.
+TABLE is an alist whose elements' cars are strings, or an obarray.
+TABLE can also be a function to do the completion itself.
+PREDICATE limits completion to a subset of TABLE.
+See `try-completion' and `all-completions' for more details
+ on completion, TABLE, and PREDICATE.
+
+If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
+ the input is (or completes to) an element of TABLE or is null.
+ If it is also not t, typing RET does not exit if it does non-null completion.
+If the input is null, `completing-read' returns an empty string,
+ regardless of the value of REQUIRE-MATCH.
+
+If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.
+  If it is (STRING . POSITION), the initial input
+  is STRING, but point is placed POSITION characters into the string.
+  This feature is deprecated--it is best to pass nil for INITIAL-INPUT
+  and supply the default value DEF instead.  The user can yank the
+  default value into the minibuffer easily using \\[next-history-element].
+  
+HIST, if non-nil, specifies a history list
+  and optionally the initial position in the list.
+  It can be a symbol, which is the history list variable to use,
+  or it can be a cons cell (HISTVAR . HISTPOS).
+  In that case, HISTVAR is the history list variable to use,
+  and HISTPOS is the initial position (the position in the list
+  which INITIAL-INPUT corresponds to).
+  Positions are counted starting from 1 at the beginning of the list.
+DEF, if non-nil, is the default value.
+
+If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits
+  the current input method and the setting of `enable-multibyte-characters'.
+
+Completion ignores case if the ambient value of
+  `completion-ignore-case' is non-nil.  */)
+     (prompt, table, predicate, require_match, initial_input, hist, def, inherit_input_method)
      Lisp_Object prompt, table, predicate, require_match, initial_input;
      Lisp_Object hist, def, inherit_input_method;
 {
@@ -1472,7 +1495,7 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
   specbind (Qminibuffer_completion_table, table);
   specbind (Qminibuffer_completion_predicate, predicate);
   specbind (Qminibuffer_completion_confirm,
-           EQ (require_match, Qt) ? Qnil : Qt);
+           EQ (require_match, Qt) ? Qnil : require_match);
   last_exact_completion = Qnil;
 
   position = Qnil;
@@ -1483,10 +1506,10 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
          position = Fcdr (init);
          init = Fcar (init);
        }
-      CHECK_STRING (init, 0);
+      CHECK_STRING (init);
       if (!NILP (position))
        {
-         CHECK_NUMBER (position, 0);
+         CHECK_NUMBER (position);
          /* Convert to distance from end of input.  */
          pos = XINT (position) - XSTRING (init)->size;
        }
@@ -1521,47 +1544,70 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
 }
 \f
 Lisp_Object Fminibuffer_completion_help ();
-Lisp_Object assoc_for_completion ();
+Lisp_Object Fassoc_string ();
 
 /* Test whether TXT is an exact completion.  */
-Lisp_Object
-test_completion (txt)
-     Lisp_Object txt;
+DEFUN ("test-completion", Ftest_completion, Stest_completion, 2, 3, 0,
+       doc: /* Return non-nil if STRING is a valid completion.
+Takes the same arguments as `all-completions' and `try-completion'.
+If ALIST is a function, it is called with three arguments:
+the values STRING, PREDICATE and `lambda'.  */)
+       (string, alist, predicate)
+     Lisp_Object string, alist, predicate;
 {
-  Lisp_Object tem;
+  Lisp_Object regexps, tem = Qnil;
+
+  CHECK_STRING (string);
 
-  if (CONSP (Vminibuffer_completion_table)
-      || NILP (Vminibuffer_completion_table))
-    return assoc_for_completion (txt, Vminibuffer_completion_table);
-  else if (VECTORP (Vminibuffer_completion_table))
+  if ((CONSP (alist) && (!SYMBOLP (XCAR (alist)) || NILP (XCAR (alist))))
+      || NILP (alist))
+    {
+      tem = Fassoc_string (string, alist, completion_ignore_case ? Qt : Qnil);
+      if (CONSP (tem))
+       tem = XCAR (tem);
+      else
+       return Qnil;
+    }
+  else if (VECTORP (alist))
     {
-      /* Bypass intern-soft as that loses for nil */
-      tem = oblookup (Vminibuffer_completion_table,
-                     XSTRING (txt)->data,
-                     XSTRING (txt)->size,
-                     STRING_BYTES (XSTRING (txt)));
+      /* Bypass intern-soft as that loses for nil */
+      tem = oblookup (alist,
+                     XSTRING (string)->data,
+                     XSTRING (string)->size,
+                     STRING_BYTES (XSTRING (string)));
       if (!SYMBOLP (tem))
        {
-         if (STRING_MULTIBYTE (txt))
-           txt = Fstring_make_unibyte (txt);
+         if (STRING_MULTIBYTE (string))
+           string = Fstring_make_unibyte (string);
          else
-           txt = Fstring_make_multibyte (txt);
+           string = Fstring_make_multibyte (string);
 
          tem = oblookup (Vminibuffer_completion_table,
-                         XSTRING (txt)->data,
-                         XSTRING (txt)->size,
-                         STRING_BYTES (XSTRING (txt)));
+                         XSTRING (string)->data,
+                         XSTRING (string)->size,
+                         STRING_BYTES (XSTRING (string)));
          if (!SYMBOLP (tem))
            return Qnil;
        }
-      if (!NILP (Vminibuffer_completion_predicate))
-       return call1 (Vminibuffer_completion_predicate, tem);
-      else
-       return Qt;
     }
   else
-    return call3 (Vminibuffer_completion_table, txt,
-                 Vminibuffer_completion_predicate, Qlambda);
+    return call3 (alist, string, predicate, Qlambda);
+
+  /* Reject this element if it fails to match all the regexps.  */
+  for (regexps = Vcompletion_regexp_list; CONSP (regexps);
+       regexps = XCDR (regexps))
+    {
+      if (NILP (Fstring_match (XCAR (regexps),
+                              SYMBOLP (tem) ? string : tem,
+                              Qnil)))
+       return Qnil;
+    }
+
+  /* Finally, check the predicate.  */
+  if (!NILP (predicate))
+    return call1 (predicate, tem);
+  else
+    return Qt;
 }
 
 /* returns:
@@ -1580,7 +1626,7 @@ do_completion ()
   Lisp_Object last;
   struct gcpro gcpro1, gcpro2;
 
-  completion = Ftry_completion (Ffield_string (make_number (ZV)),
+  completion = Ftry_completion (Fminibuffer_contents (),
                                Vminibuffer_completion_table,
                                Vminibuffer_completion_predicate);
   last = last_exact_completion;
@@ -1602,7 +1648,7 @@ do_completion ()
       return 1;
     }
 
-  string = Ffield_string (make_number (ZV));
+  string = Fminibuffer_contents ();
 
   /* COMPLETEDP should be true if some completion was done, which
      doesn't include simply changing the case of the entered string.
@@ -1615,7 +1661,7 @@ do_completion ()
   if (!EQ (tem, Qt))
     /* Rewrite the user's input.  */
     {
-      Fdelete_field (make_number (ZV)); /* Some completion happened */
+      Fdelete_minibuffer_contents (); /* Some completion happened */
       Finsert (1, &completion);
 
       if (! completedp)
@@ -1631,7 +1677,9 @@ do_completion ()
     }
 
   /* It did find a match.  Do we match some possibility exactly now? */
-  tem = test_completion (Ffield_string (make_number (ZV)));
+  tem = Ftest_completion (Fminibuffer_contents (),
+                         Vminibuffer_completion_table,
+                         Vminibuffer_completion_predicate);
   if (NILP (tem))
     {
       /* not an exact match */
@@ -1655,7 +1703,7 @@ do_completion ()
   last_exact_completion = completion;
   if (!NILP (last))
     {
-      tem = Ffield_string (make_number (ZV));
+      tem = Fminibuffer_contents ();
       if (!NILP (Fequal (tem, last)))
        Fminibuffer_completion_help ();
     }
@@ -1665,10 +1713,15 @@ do_completion ()
 
 /* Like assoc but assumes KEY is a string, and ignores case if appropriate.  */
 
-Lisp_Object
-assoc_for_completion (key, list)
+DEFUN ("assoc-string", Fassoc_string, Sassoc_string, 2, 3, 0,
+       doc: /* Like `assoc' but specifically for strings.
+Unibyte strings are converted to multibyte for comparison.
+And case is ignored if CASE-FOLD is non-nil.
+As opposed to `assoc', it will also match an entry consisting of a single
+string rather than a cons cell whose car is a string.  */)
+       (key, list, case_fold)
      register Lisp_Object key;
-     Lisp_Object list;
+     Lisp_Object list, case_fold;
 {
   register Lisp_Object tail;
 
@@ -1676,13 +1729,12 @@ assoc_for_completion (key, list)
     {
       register Lisp_Object elt, tem, thiscar;
       elt = Fcar (tail);
-      if (!CONSP (elt)) continue;
-      thiscar = Fcar (elt);
+      thiscar = CONSP (elt) ? XCAR (elt) : elt;
       if (!STRINGP (thiscar))
        continue;
       tem = Fcompare_strings (thiscar, make_number (0), Qnil,
                              key, make_number (0), Qnil,
-                             completion_ignore_case ? Qt : Qnil);
+                             case_fold);
       if (EQ (tem, Qt))
        return elt;
       QUIT;
@@ -1691,12 +1743,12 @@ assoc_for_completion (key, list)
 }
 
 DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "",
-  "Complete the minibuffer contents as far as possible.\n\
-Return nil if there is no valid completion, else t.\n\
-If no characters can be completed, display a list of possible completions.\n\
-If you repeat this command after it displayed such a list,\n\
-scroll the window of possible completions.")
-  ()
+       doc: /* Complete the minibuffer contents as far as possible.
+Return nil if there is no valid completion, else t.
+If no characters can be completed, display a list of possible completions.
+If you repeat this command after it displayed such a list,
+scroll the window of possible completions.  */)
+     ()
 {
   register int i;
   Lisp_Object window, tem;
@@ -1770,20 +1822,22 @@ complete_and_exit_2 (ignore)
 }
 
 DEFUN ("minibuffer-complete-and-exit", Fminibuffer_complete_and_exit,
-        Sminibuffer_complete_and_exit, 0, 0, "",
-  "If the minibuffer contents is a valid completion then exit.\n\
-Otherwise try to complete it.  If completion leads to a valid completion,\n\
-a repetition of this command will exit.")
-  ()
+       Sminibuffer_complete_and_exit, 0, 0, "",
+       doc: /* If the minibuffer contents is a valid completion then exit.
+Otherwise try to complete it.  If completion leads to a valid completion,
+a repetition of this command will exit.  */)
+     ()
 {
   register int i;
   Lisp_Object val;
 
   /* Allow user to specify null string */
-  if (XINT (Ffield_beginning (make_number (ZV), Qnil)) == ZV)
+  if (XINT (Fminibuffer_prompt_end ()) == ZV)
     goto exit;
 
-  if (!NILP (test_completion (Ffield_string (make_number (ZV)))))
+  if (!NILP (Ftest_completion (Fminibuffer_contents (),
+                              Vminibuffer_completion_table,
+                              Vminibuffer_completion_predicate)))
     goto exit;
 
   /* Call do_completion, but ignore errors.  */
@@ -1815,12 +1869,12 @@ a repetition of this command will exit.")
 }
 
 DEFUN ("minibuffer-complete-word", Fminibuffer_complete_word, Sminibuffer_complete_word,
-  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.\n\
-Return nil if there is no valid completion, else t.")
-  ()
+       0, 0, "",
+       doc: /* Complete the minibuffer contents at most a single word.
+After one word is completed as much as possible, a space or hyphen
+is added, provided that matches some possible completion.
+Return nil if there is no valid completion, else t.  */)
+     ()
 {
   Lisp_Object completion, tem, tem1;
   register int i, i_byte;
@@ -1831,7 +1885,7 @@ Return nil if there is no valid completion, else t.")
   /* 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 (Ffield_string (make_number (ZV)),
+  completion = Ftry_completion (Fminibuffer_contents (),
                                Vminibuffer_completion_table,
                                Vminibuffer_completion_predicate);
   if (NILP (completion))
@@ -1844,7 +1898,7 @@ Return nil if there is no valid completion, else t.")
     return Qnil;
 
 #if 0 /* How the below code used to look, for reference. */
-  tem = Ffield_string (make_number (ZV));
+  tem = Fminibuffer_contents ();
   b = XSTRING (tem)->data;
   i = ZV - 1 - XSTRING (completion)->size;
   p = XSTRING (completion)->data;
@@ -1862,8 +1916,8 @@ Return nil if there is no valid completion, else t.")
   {
     int buffer_nchars, completion_nchars;
 
-    CHECK_STRING (completion, 0);
-    tem = Ffield_string (make_number (ZV));
+    CHECK_STRING (completion);
+    tem = Fminibuffer_contents ();
     GCPRO2 (completion, tem);
     /* If reading a file name,
        expand any $ENVVAR refs in the buffer and in TEM.  */
@@ -1874,7 +1928,7 @@ Return nil if there is no valid completion, else t.")
        if (! EQ (substituted, tem))
          {
            tem = substituted;
-           Fdelete_field (make_number (ZV));
+           Fdelete_minibuffer_contents ();
            insert_from_string (tem, 0, 0, XSTRING (tem)->size,
                                STRING_BYTES (XSTRING (tem)), 0);
          }
@@ -1916,7 +1970,7 @@ Return nil if there is no valid completion, else t.")
   }
 #endif /* Rewritten code */
   
-  prompt_end_charpos = XINT (Ffield_beginning (make_number (ZV), Qnil));
+  prompt_end_charpos = XINT (Fminibuffer_prompt_end ());
 
   {
     int prompt_end_bytepos;
@@ -1930,7 +1984,7 @@ Return nil if there is no valid completion, else t.")
   if (i == XSTRING (completion)->size)
     {
       GCPRO1 (completion);
-      tem = Ftry_completion (concat2 (Ffield_string (make_number (ZV)), build_string (" ")),
+      tem = Ftry_completion (concat2 (Fminibuffer_contents (), build_string (" ")),
                             Vminibuffer_completion_table,
                             Vminibuffer_completion_predicate);
       UNGCPRO;
@@ -1941,7 +1995,7 @@ Return nil if there is no valid completion, else t.")
        {
          GCPRO1 (completion);
          tem =
-           Ftry_completion (concat2 (Ffield_string (make_number (ZV)), build_string ("-")),
+           Ftry_completion (concat2 (Fminibuffer_contents (), build_string ("-")),
                             Vminibuffer_completion_table,
                             Vminibuffer_completion_predicate);
          UNGCPRO;
@@ -1982,22 +2036,22 @@ Return nil if there is no valid completion, else t.")
 
   /* Otherwise insert in minibuffer the chars we got */
 
-  Fdelete_field (make_number (ZV));
+  Fdelete_minibuffer_contents ();
   insert_from_string (completion, 0, 0, i, i_byte, 1);
   return Qt;
 }
 \f
 DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_list,
        1, 1, 0,
-  "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.\n\
-`standard-output' must be a buffer.\n\
-The actual completion alternatives, as inserted, are given `mouse-face'\n\
-properties of `highlight'.\n\
-At the end, this runs the normal hook `completion-setup-hook'.\n\
-It can find the completion buffer in `standard-output'.")
-  (completions)
+       doc: /* Display the list of completions, COMPLETIONS, using `standard-output'.
+Each element may be just a symbol or string
+or may be a list of two strings to be printed as if concatenated.
+`standard-output' must be a buffer.
+The actual completion alternatives, as inserted, are given `mouse-face'
+properties of `highlight'.
+At the end, this runs the normal hook `completion-setup-hook'.
+It can find the completion buffer in `standard-output'.  */)
+     (completions)
      Lisp_Object completions;
 {
   Lisp_Object tail, elt;
@@ -2036,16 +2090,16 @@ It can find the completion buffer in `standard-output'.")
          if (CONSP (elt))
            {
              tem = XCAR (elt);
-             CHECK_STRING (tem, 0);
+             CHECK_STRING (tem);
              length = XSTRING (tem)->size;
 
              tem = Fcar (XCDR (elt));
-             CHECK_STRING (tem, 0);
+             CHECK_STRING (tem);
              length += XSTRING (tem)->size;
            }
          else
            {
-             CHECK_STRING (elt, 0);
+             CHECK_STRING (elt);
              length = XSTRING (elt)->size;
            }
 
@@ -2171,14 +2225,14 @@ It can find the completion buffer in `standard-output'.")
 }
 
 DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_completion_help,
-  0, 0, "",
-  "Display a list of possible completions of the current minibuffer contents.")
-  ()
+       0, 0, "",
+       doc: /* Display a list of possible completions of the current minibuffer contents.  */)
+     ()
 {
   Lisp_Object completions;
 
   message ("Making completion list...");
-  completions = Fall_completions (Ffield_string (make_number (ZV)),
+  completions = Fall_completions (Fminibuffer_contents (),
                                  Vminibuffer_completion_table,
                                  Vminibuffer_completion_predicate,
                                  Qt);
@@ -2197,8 +2251,8 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co
 }
 \f
 DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0, 0, "",
-  "Terminate minibuffer input.")
-  ()
+       doc: /* Terminate minibuffer input.  */)
+     ()
 {
   if (INTEGERP (last_command_char))
     internal_self_insert (XINT (last_command_char), 0);
@@ -2209,23 +2263,23 @@ DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0,
 }
 
 DEFUN ("exit-minibuffer", Fexit_minibuffer, Sexit_minibuffer, 0, 0, "",
-  "Terminate this minibuffer argument.")
-  ()
+       doc: /* Terminate this minibuffer argument.  */)
+     ()
 {
   return Fthrow (Qexit, Qnil);
 }
 
 DEFUN ("minibuffer-depth", Fminibuffer_depth, Sminibuffer_depth, 0, 0, 0,
-  "Return current depth of activations of minibuffer, a nonnegative integer.")
-  ()
+       doc: /* Return current depth of activations of minibuffer, a nonnegative integer.  */)
+     ()
 {
   return make_number (minibuf_level);
 }
 
 DEFUN ("minibuffer-prompt", Fminibuffer_prompt, Sminibuffer_prompt, 0, 0, 0,
-  "Return the prompt string of the currently-active minibuffer.\n\
-If no minibuffer is active, return nil.")
-  ()
+       doc: /* Return the prompt string of the currently-active minibuffer.
+If no minibuffer is active, return nil.  */)
+     ()
 {
   return Fcopy_sequence (minibuf_prompt);
 }
@@ -2267,11 +2321,11 @@ temp_echo_area_glyphs (m)
 }
 
 DEFUN ("minibuffer-message", Fminibuffer_message, Sminibuffer_message,
-  1, 1, 0,
-  "Temporarily display STRING at the end of the minibuffer.\n\
-The text is displayed for two seconds,\n\
-or until the next input event arrives, whichever comes first.")
-  (string)
+       1, 1, 0,
+       doc: /* Temporarily display STRING at the end of the minibuffer.
+The text is displayed for two seconds,
+or until the next input event arrives, whichever comes first.  */)
+     (string)
      Lisp_Object string;
 {
   temp_echo_area_glyphs (XSTRING (string)->data);
@@ -2342,98 +2396,107 @@ syms_of_minibuf ()
   Qactivate_input_method = intern ("activate-input-method");
   staticpro (&Qactivate_input_method);
 
-  DEFVAR_LISP ("read-buffer-function", &Vread_buffer_function, 
-    "If this is non-nil, `read-buffer' does its work by calling this function.");
+  DEFVAR_LISP ("read-buffer-function", &Vread_buffer_function,
+              doc: /* If this is non-nil, `read-buffer' does its work by calling this function.  */);
   Vread_buffer_function = Qnil;
 
-  DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook, 
-    "Normal hook run just after entry to minibuffer.");
+  DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook,
+              doc: /* Normal hook run just after entry to minibuffer.  */);
   Vminibuffer_setup_hook = Qnil;
 
   DEFVAR_LISP ("minibuffer-exit-hook", &Vminibuffer_exit_hook,
-    "Normal hook run just after exit from minibuffer.");
+              doc: /* Normal hook run just after exit from minibuffer.  */);
   Vminibuffer_exit_hook = Qnil;
 
   DEFVAR_LISP ("history-length", &Vhistory_length,
-    "*Maximum length for history lists before truncation takes place.\n\
-A number means that length; t means infinite.  Truncation takes place\n\
-just after a new element is inserted.  Setting the history-length\n\
-property of a history variable overrides this default.");
+              doc: /* *Maximum length for history lists before truncation takes place.
+A number means that length; t means infinite.  Truncation takes place
+just after a new element is inserted.  Setting the history-length
+property of a history variable overrides this default.  */);
   XSETFASTINT (Vhistory_length, 30);
 
   DEFVAR_LISP ("completion-auto-help", &Vcompletion_auto_help,
-    "*Non-nil means automatically provide help for invalid completion input.");
+              doc: /* *Non-nil means automatically provide help for invalid completion input.  */);
   Vcompletion_auto_help = Qt;
 
   DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case,
-    "Non-nil means don't consider case significant in completion.");
+              doc: /* Non-nil means don't consider case significant in completion.  */);
   completion_ignore_case = 0;
 
   DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers,
-    "*Non-nil means to allow minibuffer commands while in the minibuffer.\n\
-This variable makes a difference whenever the minibuffer window is active.");
+              doc: /* *Non-nil means to allow minibuffer commands while in the minibuffer.
+This variable makes a difference whenever the minibuffer window is active. */);
   enable_recursive_minibuffers = 0;
 
   DEFVAR_LISP ("minibuffer-completion-table", &Vminibuffer_completion_table,
-    "Alist or obarray used for completion in the minibuffer.\n\
-This becomes the ALIST argument to `try-completion' and `all-completion'.\n\
-\n\
-The value may alternatively be a function, which is given three arguments:\n\
-  STRING, the current buffer contents;\n\
-  PREDICATE, the predicate for filtering possible matches;\n\
-  CODE, which says what kind of things to do.\n\
-CODE can be nil, t or `lambda'.\n\
-nil means to return the best completion of STRING, or nil if there is none.\n\
-t means to return a list of all possible completions of STRING.\n\
-`lambda' means to return t if STRING is a valid completion as it stands.");
+              doc: /* Alist or obarray used for completion in the minibuffer.
+This becomes the ALIST argument to `try-completion' and `all-completion'.
+
+The value may alternatively be a function, which is given three arguments:
+  STRING, the current buffer contents;
+  PREDICATE, the predicate for filtering possible matches;
+  CODE, which says what kind of things to do.
+CODE can be nil, t or `lambda'.
+nil means to return the best completion of STRING, or nil if there is none.
+t means to return a list of all possible completions of STRING.
+`lambda' means to return t if STRING is a valid completion as it stands.  */);
   Vminibuffer_completion_table = Qnil;
 
   DEFVAR_LISP ("minibuffer-completion-predicate", &Vminibuffer_completion_predicate,
-    "Within call to `completing-read', this holds the PREDICATE argument.");
+              doc: /* Within call to `completing-read', this holds the PREDICATE argument.  */);
   Vminibuffer_completion_predicate = Qnil;
 
   DEFVAR_LISP ("minibuffer-completion-confirm", &Vminibuffer_completion_confirm,
-    "Non-nil => demand confirmation of completion before exiting minibuffer.");
+              doc: /* Non-nil means to demand confirmation of completion before exiting minibuffer.  */);
   Vminibuffer_completion_confirm = Qnil;
 
   DEFVAR_LISP ("minibuffer-completing-file-name",
               &Vminibuffer_completing_file_name,
-    "Non-nil means completing file names.");
+              doc: /* Non-nil means completing file names.  */);
   Vminibuffer_completing_file_name = Qnil;
 
   DEFVAR_LISP ("minibuffer-help-form", &Vminibuffer_help_form,
-    "Value that `help-form' takes on inside the minibuffer.");
+              doc: /* 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 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)))");
+              doc: /* History list symbol to add minibuffer values to.
+Each string of minibuffer input, as it appears on exit from the minibuffer,
+is added with
+  (set minibuffer-history-variable
+  (cons STRING (symbol-value minibuffer-history-variable)))  */);
   XSETFASTINT (Vminibuffer_history_variable, 0);
 
   DEFVAR_LISP ("minibuffer-history-position", &Vminibuffer_history_position,
-    "Current position of redoing in the history list.");
+              doc: /* 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.\n\
-Some uses of the echo area also raise that frame (since they use it too).");
+              doc: /* *Non-nil means entering the minibuffer raises the minibuffer's frame.
+Some uses of the echo area also raise that frame (since they use it too).  */);
   minibuffer_auto_raise = 0;
 
   DEFVAR_LISP ("completion-regexp-list", &Vcompletion_regexp_list,
-    "List of regexps that should restrict possible completions.");
+              doc: /* List of regexps that should restrict possible completions.  */);
   Vcompletion_regexp_list = Qnil;
 
   DEFVAR_BOOL ("minibuffer-allow-text-properties",
               &minibuffer_allow_text_properties,
-    "Non-nil means `read-from-minibuffer' should not discard text properties.\n\
-This also affects `read-string', but it does not affect `read-minibuffer',\n\
-`read-no-blanks-input', or any of the functions that do minibuffer input\n\
-with completion; they always discard text properties.");
+              doc: /* Non-nil means `read-from-minibuffer' should not discard text properties.
+This also affects `read-string', but it does not affect `read-minibuffer',
+`read-no-blanks-input', or any of the functions that do minibuffer input
+with completion; they always discard text properties.  */);
   minibuffer_allow_text_properties = 0;
 
+  DEFVAR_LISP ("minibuffer-prompt-properties", &Vminibuffer_prompt_properties,
+              doc: /* Text properties that are added to minibuffer prompts.
+These are in addition to the basic `field' property, and stickiness
+properties.  */);
+  /* We use `intern' here instead of Qread_only to avoid
+     initialization-order problems.  */
+  Vminibuffer_prompt_properties
+    = Fcons (intern ("read-only"), Fcons (Qt, Qnil));
+
   defsubr (&Sset_minibuffer_window);
   defsubr (&Sread_from_minibuffer);
   defsubr (&Seval_minibuffer);
@@ -2446,8 +2509,15 @@ with completion; they always discard text properties.");
   defsubr (&Sminibuffer_depth);
   defsubr (&Sminibuffer_prompt);
 
+  defsubr (&Sminibuffer_prompt_end);
+  defsubr (&Sminibuffer_contents);
+  defsubr (&Sminibuffer_contents_no_properties);
+  defsubr (&Sdelete_minibuffer_contents);
+
   defsubr (&Stry_completion);
   defsubr (&Sall_completions);
+  defsubr (&Stest_completion);
+  defsubr (&Sassoc_string);
   defsubr (&Scompleting_read);
   defsubr (&Sminibuffer_complete);
   defsubr (&Sminibuffer_complete_word);
@@ -2471,13 +2541,6 @@ keys_of_minibuf ()
   initial_define_key (Vminibuffer_local_map, Ctl ('j'),
                      "exit-minibuffer");
 
-  initial_define_key (Vminibuffer_local_ns_map, Ctl ('g'),
-                     "abort-recursive-edit");
-  initial_define_key (Vminibuffer_local_ns_map, Ctl ('m'),
-                     "exit-minibuffer");
-  initial_define_key (Vminibuffer_local_ns_map, Ctl ('j'),
-                     "exit-minibuffer");
-
   initial_define_key (Vminibuffer_local_ns_map, ' ',
                      "exit-minibuffer");
   initial_define_key (Vminibuffer_local_ns_map, '\t',
@@ -2485,13 +2548,6 @@ keys_of_minibuf ()
   initial_define_key (Vminibuffer_local_ns_map, '?',
                      "self-insert-and-exit");
 
-  initial_define_key (Vminibuffer_local_completion_map, Ctl ('g'),
-                     "abort-recursive-edit");
-  initial_define_key (Vminibuffer_local_completion_map, Ctl ('m'),
-                     "exit-minibuffer");
-  initial_define_key (Vminibuffer_local_completion_map, Ctl ('j'),
-                     "exit-minibuffer");
-
   initial_define_key (Vminibuffer_local_completion_map, '\t',
                      "minibuffer-complete");
   initial_define_key (Vminibuffer_local_completion_map, ' ',
@@ -2499,16 +2555,8 @@ keys_of_minibuf ()
   initial_define_key (Vminibuffer_local_completion_map, '?',
                      "minibuffer-completion-help");
 
-  initial_define_key (Vminibuffer_local_must_match_map, Ctl ('g'),
-                     "abort-recursive-edit");
   initial_define_key (Vminibuffer_local_must_match_map, Ctl ('m'),
                      "minibuffer-complete-and-exit");
   initial_define_key (Vminibuffer_local_must_match_map, Ctl ('j'),
                      "minibuffer-complete-and-exit");
-  initial_define_key (Vminibuffer_local_must_match_map, '\t',
-                     "minibuffer-complete");
-  initial_define_key (Vminibuffer_local_must_match_map, ' ',
-                     "minibuffer-complete-word");
-  initial_define_key (Vminibuffer_local_must_match_map, '?',
-                     "minibuffer-completion-help");
 }