(read_minibuf): Clear previous_echo_glyphs.
[bpt/emacs.git] / src / minibuf.c
index 428e82b..190e644 100644 (file)
@@ -79,9 +79,10 @@ Lisp_Object Qminibuffer_history;
 
 Lisp_Object Qread_file_name_internal;
 
-/* Normal hook for entry to minibuffer.  */
+/* Normal hooks for entry to and exit from minibuffer.  */
 
 Lisp_Object Qminibuffer_setup_hook, Vminibuffer_setup_hook;
+Lisp_Object Qminibuffer_exit_hook, Vminibuffer_exit_hook;
 
 /* Nonzero means completion ignores case.  */
 
@@ -250,6 +251,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
   minibuf_prompt = (char *) alloca (XSTRING (prompt)->size + 1);
   bcopy (XSTRING (prompt)->data, minibuf_prompt, XSTRING (prompt)->size + 1);
   echo_area_glyphs = 0;
+  /* This is in case the minibuffer-setup-hook calls Fsit_for.  */
+  previous_echo_glyphs = 0;
 
   Vhelp_form = Vminibuffer_help_form;
   current_buffer->keymap = map;
@@ -266,6 +269,10 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
 /* ??? MCC did redraw_screen here if switching screens.  */
   recursive_edit_1 ();
 
+  if (!NILP (Vminibuffer_exit_hook) && !EQ (Vminibuffer_exit_hook, Qunbound)
+      && !NILP (Vrun_hooks))
+    call1 (Vrun_hooks, Qminibuffer_exit_hook);
+
   /* If cursor is on the minibuffer line,
      show the user we have exited by putting it in column 0.  */
   if ((FRAME_CURSOR_Y (selected_frame)
@@ -1019,11 +1026,11 @@ temp_echo_area_glyphs (m)
   SET_PT (osize);
   Vinhibit_quit = Qt;
   Fsit_for (make_number (2), Qnil, Qnil);
-  del_range (point, ZV);
+  del_range (PT, ZV);
   if (!NILP (Vquit_flag))
     {
       Vquit_flag = Qnil;
-      unread_command_events = Fcons (make_number (quit_char), Qnil);
+      Vunread_command_events = Fcons (make_number (quit_char), Qnil);
     }
   Vinhibit_quit = oinhibit;
 }
@@ -1045,21 +1052,28 @@ do_completion ()
   Lisp_Object completion, tem;
   int completedp;
   Lisp_Object last;
+  struct gcpro gcpro1, gcpro2;
 
   completion = Ftry_completion (Fbuffer_string (), Vminibuffer_completion_table,
                                Vminibuffer_completion_predicate);
   last = last_exact_completion;
   last_exact_completion = Qnil;
 
+  GCPRO2 (completion, last);
+
   if (NILP (completion))
     {
       bitch_at_user ();
       temp_echo_area_glyphs (" [No match]");
+      UNGCPRO;
       return 0;
     }
 
   if (EQ (completion, Qt))     /* exact and unique match */
-    return 1;
+    {
+      UNGCPRO;
+      return 1;
+    }
 
   /* compiler bug */
   tem = Fstring_equal (completion, Fbuffer_string());
@@ -1097,7 +1111,9 @@ do_completion ()
                 Qlambda);
 
   if (NILP (tem))
-    { /* not an exact match */
+    {
+      /* not an exact match */
+      UNGCPRO;
       if (completedp)
        return 5;
       else if (auto_help)
@@ -1107,7 +1123,10 @@ do_completion ()
       return 6;
     }
   else if (completedp)
-    return 4;
+    {
+      UNGCPRO;
+      return 4;
+    }
   /* If the last exact completion and this one were the same,
      it means we've already given a "Complete but not unique"
      message and the user's hit TAB again, so now we give him help.  */
@@ -1118,9 +1137,10 @@ do_completion ()
       if (!NILP (Fequal (tem, last)))
        Fminibuffer_completion_help ();
     }
+  UNGCPRO;
   return 3;
 }
-  
+
 /* Like assoc but assumes KEY is a string, and ignores case if appropriate.  */
 
 Lisp_Object
@@ -1178,7 +1198,7 @@ scroll the window of possible completions.")
       tem = Fpos_visible_in_window_p (make_number (ZV), window);
       if (! NILP (tem))
        /* If end is in view, scroll up to the beginning.  */
-       Fset_window_start (window, BEGV);
+       Fset_window_start (window, BEGV, Qnil);
       else
        /* Else scroll down one screen.  */
        Fscroll_other_window (Qnil);
@@ -1517,6 +1537,25 @@ DEFUN ("minibuffer-depth", Fminibuffer_depth, Sminibuffer_depth, 0, 0, 0,
   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.")
+  ()
+{
+  if (!minibuf_prompt)
+    return Qnil;
+  return build_string (minibuf_prompt);
+}
+
+DEFUN ("minibuffer-prompt-width", Fminibuffer_prompt_width,
+  Sminibuffer_prompt_width, 0, 0, 0,
+  "Return the display width of the minibuffer prompt.")
+  ()
+{
+  Lisp_Object width;
+  XFASTINT (width) = minibuf_prompt_width;
+  return width;
+}
 \f
 init_minibuf_once ()
 {
@@ -1543,6 +1582,9 @@ syms_of_minibuf ()
   Qminibuffer_completion_predicate = intern ("minibuffer-completion-predicate");
   staticpro (&Qminibuffer_completion_predicate);
 
+  staticpro (&last_exact_completion);
+  last_exact_completion = Qnil;
+
   staticpro (&last_minibuf_string);
   last_minibuf_string = Qnil;
 
@@ -1555,10 +1597,17 @@ syms_of_minibuf ()
   Qminibuffer_setup_hook = intern ("minibuffer-setup-hook");
   staticpro (&Qminibuffer_setup_hook);
 
+  Qminibuffer_exit_hook = intern ("minibuffer-exit-hook");
+  staticpro (&Qminibuffer_exit_hook);
+
   DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook, 
     "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.");
+  Vminibuffer_exit_hook = Qnil;
+
   DEFVAR_BOOL ("completion-auto-help", &auto_help,
     "*Non-nil means automatically provide help for invalid completion input.");
   auto_help = 1;
@@ -1628,6 +1677,8 @@ Each minibuffer output is added with\n\
   defsubr (&Sread_buffer);
   defsubr (&Sread_no_blanks_input);
   defsubr (&Sminibuffer_depth);
+  defsubr (&Sminibuffer_prompt);
+  defsubr (&Sminibuffer_prompt_width);
 
   defsubr (&Stry_completion);
   defsubr (&Sall_completions);