(calendar-mode-map): Rename `holidays' menu to `Holidays'.
[bpt/emacs.git] / src / minibuf.c
index a35fcf4..2e89c61 100644 (file)
@@ -77,7 +77,7 @@ Lisp_Object Vminibuffer_history_variable;
 
 Lisp_Object Vminibuffer_history_position;
 
-Lisp_Object Qminibuffer_history;
+Lisp_Object Qminibuffer_history, Qbuffer_name_history;
 
 Lisp_Object Qread_file_name_internal;
 
@@ -391,6 +391,10 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   if (inherit_input_method)
     current_buffer->enable_multibyte_characters = enable_multibyte;
 
+  if (!NILP (current_buffer->enable_multibyte_characters)
+      && ! STRING_MULTIBYTE (minibuf_prompt))
+    minibuf_prompt = Fstring_make_multibyte (minibuf_prompt);
+
   /* 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).  */
@@ -398,7 +402,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
       && !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,
@@ -415,15 +418,9 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
   /* Make minibuffer contents into a string.  */
   Fset_buffer (minibuffer);
   val = make_buffer_string (1, Z, allow_props);
-#if 0  /* make_buffer_string should handle the gap.  */
-  bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT);
-#endif
 
   /* VAL is the string of minibuffer text.  */
 
-  if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (defalt))
-    val = defalt;
-
   last_minibuf_string = val;
 
   /* Add the value to the appropriate history list unless it is empty.  */
@@ -472,6 +469,10 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
       unsigned char *p;
       int pos;
 
+      if (STRINGP (val) && XSTRING (val)->size == 0
+         && STRINGP (defalt))
+       val = defalt;
+
       expr_and_pos = Fread_from_string (val, Qnil, Qnil);
       pos = XINT (Fcdr (expr_and_pos));
       if (pos != XSTRING (val)->size)
@@ -479,7 +480,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
          /* Ignore trailing whitespace; any other trailing junk is an error.  */
          int i;
          pos = string_char_to_byte (val, pos);
-         for (i = pos; i < XSTRING (val)->size_byte; i++)
+         for (i = pos; i < STRING_BYTES (XSTRING (val)); i++)
            {
              int c = XSTRING (val)->data[i];
              if (c != ' ' && c != '\t' && c != '\n')
@@ -629,12 +630,12 @@ Fifth arg HIST, if non-nil, specifies a history list\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 used\n\
- for history commands, and as the value to return if the user enters\n\
- the empty string.\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\
+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)
@@ -736,30 +737,37 @@ 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 INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\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)
      Lisp_Object prompt, initial_input, history, default_value;
      Lisp_Object inherit_input_method;
 {
-  return Fread_from_minibuffer (prompt, initial_input, Qnil,
-                               Qnil, history, default_value,
-                               inherit_input_method);
+  Lisp_Object val;
+  val = Fread_from_minibuffer (prompt, initial_input, Qnil,
+                              Qnil, history, default_value,
+                              inherit_input_method);
+  if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (default_value))
+    val = default_value;
+  return val;
 }
 
 DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 3, 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.\n\
+  "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, init, inherit_input_method)
-     Lisp_Object prompt, init, inherit_input_method;
+  (prompt, initial, inherit_input_method)
+     Lisp_Object prompt, initial, inherit_input_method;
 {
   CHECK_STRING (prompt, 0);
-  if (! NILP (init))
-    CHECK_STRING (init, 1);
+  if (! NILP (initial))
+    CHECK_STRING (initial, 1);
 
-  return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil,
+  return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, Qnil,
                       0, Qminibuffer_history, make_number (0), Qnil, 0,
                       !NILP (inherit_input_method));
 }
@@ -847,7 +855,8 @@ If optional third arg REQUIRE-MATCH is non-nil, only existing buffer names are a
        }
 
       return Fcompleting_read (prompt, Vbuffer_alist, Qnil,
-                              require_match, Qnil, Qnil, def, Qnil);
+                              require_match, Qnil, Qbuffer_name_history,
+                              def, Qnil);
     }
   else
     {
@@ -859,6 +868,19 @@ If optional third arg REQUIRE-MATCH is non-nil, only existing buffer names are a
     }
 }
 \f
+static Lisp_Object
+minibuf_conform_representation (string, basis)
+     Lisp_Object string, basis;
+{
+  if (STRING_MULTIBYTE (string) == STRING_MULTIBYTE (basis))
+    return string;
+
+  if (STRING_MULTIBYTE (string))
+    return Fstring_make_unibyte (string);
+  else
+    return Fstring_make_multibyte (string);
+}
+
 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\
@@ -946,9 +968,12 @@ or the symbol from the obarray.")
       /* Is this element a possible completion? */
 
       if (STRINGP (eltstring)
-         && XSTRING (string)->size_byte <= XSTRING (eltstring)->size_byte
-         && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
-                      XSTRING (string)->size_byte))
+         && STRING_BYTES (XSTRING (string)) <= STRING_BYTES (XSTRING (eltstring))
+         && (tem = Fcompare_strings (eltstring, make_number (0),
+                                     make_number (XSTRING (string)->size),
+                                     string, make_number (0), Qnil,
+                                     completion_ignore_case ?Qt : Qnil),
+             EQ (Qt, tem)))
        {
          /* Yes. */
          Lisp_Object regexps;
@@ -988,14 +1013,23 @@ or the symbol from the obarray.")
          if (NILP (bestmatch))
            {
              bestmatch = eltstring;
-             bestmatchsize = XSTRING (eltstring)->size_byte;
+             bestmatchsize = XSTRING (eltstring)->size;
            }
          else
            {
-             compare = min (bestmatchsize, XSTRING (eltstring)->size_byte);
-             matchsize = scmp (XSTRING (bestmatch)->data,
-                               XSTRING (eltstring)->data,
-                               compare);
+             compare = min (bestmatchsize, XSTRING (eltstring)->size);
+             tem = Fcompare_strings (bestmatch, make_number (0),
+                                     make_number (compare),
+                                     eltstring, make_number (0),
+                                     make_number (compare),
+                                     completion_ignore_case ? Qt : Qnil);
+             if (EQ (tem, Qt))
+               matchsize = compare;
+             else if (XINT (tem) < 0)
+               matchsize = - XINT (tem) - 1;
+             else
+               matchsize = XINT (tem) - 1;
+
              if (matchsize < 0)
                matchsize = compare;
              if (completion_ignore_case)
@@ -1004,8 +1038,8 @@ or the symbol from the obarray.")
                     use it as the best match rather than one that is not an
                     exact match.  This way, we get the case pattern
                     of the actual match.  */
-                 if ((matchsize == XSTRING (eltstring)->size_byte
-                      && matchsize < XSTRING (bestmatch)->size_byte)
+                 if ((matchsize == XSTRING (eltstring)->size
+                      && matchsize < XSTRING (bestmatch)->size)
                      ||
                      /* If there is more than one exact match ignoring case,
                         and one of them is exact including case,
@@ -1013,15 +1047,21 @@ or the symbol from the obarray.")
                      /* If there is no exact match ignoring case,
                         prefer a match that does not change the case
                         of the input.  */
-                     ((matchsize == XSTRING (eltstring)->size_byte)
+                     ((matchsize == XSTRING (eltstring)->size)
                       ==
-                      (matchsize == XSTRING (bestmatch)->size_byte)
-                      && !bcmp (XSTRING (eltstring)->data,
-                                XSTRING (string)->data,
-                                XSTRING (string)->size_byte)
-                      && bcmp (XSTRING (bestmatch)->data,
-                               XSTRING (string)->data,
-                               XSTRING (string)->size_byte)))
+                      (matchsize == XSTRING (bestmatch)->size)
+                      && (tem = Fcompare_strings (eltstring, make_number (0),
+                                                  make_number (XSTRING (string)->size),
+                                                  string, make_number (0),
+                                                  Qnil,
+                                                  Qnil),
+                          EQ (Qt, tem))
+                      && (tem = Fcompare_strings (bestmatch, make_number (0),
+                                                  make_number (XSTRING (string)->size),
+                                                  string, make_number (0),
+                                                  Qnil,
+                                                  Qnil),
+                          ! EQ (Qt, tem))))
                    bestmatch = eltstring;
                }
              bestmatchsize = matchsize;
@@ -1034,19 +1074,21 @@ or the symbol from the obarray.")
   /* If we are ignoring case, and there is no exact match,
      and no additional text was supplied,
      don't change the case of what the user typed.  */
-  if (completion_ignore_case && bestmatchsize == XSTRING (string)->size_byte
-      && XSTRING (bestmatch)->size_byte > bestmatchsize)
-    return string;
+  if (completion_ignore_case && bestmatchsize == XSTRING (string)->size
+      && XSTRING (bestmatch)->size > bestmatchsize)
+    return minibuf_conform_representation (string, bestmatch);
 
   /* Return t if the supplied string is an exact match (counting case);
      it does not require any change to be made.  */
-  if (matchcount == 1 && bestmatchsize == XSTRING (string)->size_byte
-      && !bcmp (XSTRING (bestmatch)->data, XSTRING (string)->data,
-               bestmatchsize))
+  if (matchcount == 1 && bestmatchsize == XSTRING (string)->size
+      && (tem = Fcompare_strings (bestmatch, make_number (0),
+                                 make_number (bestmatchsize),
+                                 string, make_number (0),
+                                 make_number (bestmatchsize),
+                                 Qnil),
+         EQ (Qt, tem)))
     return Qt;
 
-  bestmatchsize = string_byte_to_char (bestmatch, bestmatchsize);
-
   XSETFASTINT (zero, 0);               /* Else extract the part in which */
   XSETFASTINT (end, bestmatchsize);    /* all completions agree */
   return Fsubstring (bestmatch, zero, end);
@@ -1174,15 +1216,19 @@ are ignored unless STRING itself starts with a space.")
       /* Is this element a possible completion? */
 
       if (STRINGP (eltstring)
-         && XSTRING (string)->size_byte <= XSTRING (eltstring)->size_byte
+         && STRING_BYTES (XSTRING (string)) <= STRING_BYTES (XSTRING (eltstring))
          /* If HIDE_SPACES, reject alternatives that start with space
             unless the input starts with space.  */
-         && ((XSTRING (string)->size_byte > 0
+         && ((STRING_BYTES (XSTRING (string)) > 0
               && XSTRING (string)->data[0] == ' ')
              || XSTRING (eltstring)->data[0] != ' '
              || NILP (hide_spaces))
-         && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
-                      XSTRING (string)->size_byte))
+         && (tem = Fcompare_strings (eltstring, make_number (0),
+                                     make_number (XSTRING (string)->size),
+                                     string, make_number (0),
+                                     make_number (XSTRING (string)->size),
+                                     completion_ignore_case ? Qt : Qnil),
+             EQ (Qt, tem)))
        {
          /* Yes. */
          Lisp_Object regexps;
@@ -1322,6 +1368,10 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
                      init, prompt, make_number (pos), 0,
                      histvar, histpos, def, 0,
                      !NILP (inherit_input_method));
+
+  if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (def))
+    val = def;
+
   RETURN_UNGCPRO (unbind_to (count, val));
 }
 \f
@@ -1344,10 +1394,22 @@ test_completion (txt)
       tem = oblookup (Vminibuffer_completion_table,
                      XSTRING (txt)->data,
                      XSTRING (txt)->size,
-                     XSTRING (txt)->size_byte);
+                     STRING_BYTES (XSTRING (txt)));
       if (!SYMBOLP (tem))
-       return Qnil;
-      else if (!NILP (Vminibuffer_completion_predicate))
+       {
+         if (STRING_MULTIBYTE (txt))
+           txt = Fstring_make_unibyte (txt);
+         else
+           txt = Fstring_make_multibyte (txt);
+
+         tem = oblookup (Vminibuffer_completion_table,
+                         XSTRING (txt)->data,
+                         XSTRING (txt)->size,
+                         STRING_BYTES (XSTRING (txt)));
+         if (!SYMBOLP (tem))
+           return Qnil;
+       }
+      if (!NILP (Vminibuffer_completion_predicate))
        return call1 (Vminibuffer_completion_predicate, tem);
       else
        return Qt;
@@ -1444,9 +1506,6 @@ assoc_for_completion (key, list)
 {
   register Lisp_Object tail;
 
-  if (completion_ignore_case)
-    key = Fupcase (key);
-
   for (tail = list; !NILP (tail); tail = Fcdr (tail))
     {
       register Lisp_Object elt, tem, thiscar;
@@ -1455,10 +1514,11 @@ assoc_for_completion (key, list)
       thiscar = Fcar (elt);
       if (!STRINGP (thiscar))
        continue;
-      if (completion_ignore_case)
-       thiscar = Fupcase (thiscar);
-      tem = Fequal (thiscar, key);
-      if (!NILP (tem)) return elt;
+      tem = Fcompare_strings (thiscar, make_number (0), Qnil,
+                             key, make_number (0), Qnil,
+                             completion_ignore_case ? Qt : Qnil);
+      if (EQ (tem, Qt))
+       return elt;
       QUIT;
     }
   return Qnil;
@@ -1592,7 +1652,7 @@ is added, provided that matches some possible completion.\n\
 Return nil if there is no valid completion, else t.")
   ()
 {
-  Lisp_Object completion, tem;
+  Lisp_Object completion, tem, tem1;
   register int i, i_byte;
   register unsigned char *completion_string;
   struct gcpro gcpro1, gcpro2;
@@ -1629,8 +1689,7 @@ Return nil if there is no valid completion, else t.")
     }
 #else /* Rewritten code */
   {
-    register unsigned char *buffer_string;
-    int buffer_nbytes, completion_nbytes;
+    int buffer_nchars, completion_nchars;
 
     CHECK_STRING (completion, 0);
     tem = Fbuffer_string ();
@@ -1646,24 +1705,40 @@ Return nil if there is no valid completion, else t.")
            tem = substituted;
            Ferase_buffer ();
            insert_from_string (tem, 0, 0, XSTRING (tem)->size,
-                               XSTRING (tem)->size_byte, 0);
+                               STRING_BYTES (XSTRING (tem)), 0);
          }
       }
-    buffer_string = XSTRING (tem)->data;
-    completion_string = XSTRING (completion)->data;
-    buffer_nbytes = XSTRING (tem)->size_byte; /* ie ZV_BYTE - BEGV_BYTE */
-    completion_nbytes = XSTRING (completion)->size_byte;
-    i_byte = buffer_nbytes - completion_nbytes;
-    if (i_byte > 0 ||
-       0 <= scmp (buffer_string, completion_string, buffer_nbytes))
+    buffer_nchars = XSTRING (tem)->size; /* ie ZV - BEGV */
+    completion_nchars = XSTRING (completion)->size;
+    i = buffer_nchars - completion_nchars;
+    if (i > 0
+       ||
+       (tem1 = Fcompare_strings (tem, make_number (0),
+                                 make_number (buffer_nchars),
+                                 completion, make_number (0),
+                                 make_number (buffer_nchars),
+                                 completion_ignore_case ? Qt : Qnil),
+        ! EQ (tem1, Qt)))
       {
-       /* Set buffer to longest match of buffer tail and completion head. */
-       if (i_byte <= 0) i_byte = 1;
-       buffer_string += i_byte;
-       buffer_nbytes -= i_byte;
-       while (0 <= scmp (buffer_string++, completion_string, buffer_nbytes--))
-         i_byte++;
-       del_range_byte (1, i_byte + 1, 1);
+       int start_pos;
+
+       /* Set buffer to longest match of buffer tail and completion head.  */
+       if (i <= 0) i = 1;
+       start_pos= i;
+       buffer_nchars -= i;
+       while (1)
+         {
+           tem1 = Fcompare_strings (tem, make_number (start_pos),
+                                    make_number (buffer_nchars + start_pos),
+                                    completion, make_number (0),
+                                    make_number (buffer_nchars),
+                                    completion_ignore_case ? Qt : Qnil);
+           start_pos++;
+           if (EQ (tem1, Qt))
+             break;
+           i++;
+         }
+       del_range (1, i + 1);
        SET_PT_BOTH (ZV, ZV_BYTE);
       }
     UNGCPRO;
@@ -1704,7 +1779,7 @@ Return nil if there is no valid completion, else t.")
     int len, c;
 
     completion_string = XSTRING (completion)->data;
-    for (; i_byte < XSTRING (completion)->size_byte; i_byte += len, i++)
+    for (; i_byte < STRING_BYTES (XSTRING (completion)); i_byte += len, i++)
       {
        c = STRING_CHAR_AND_LENGTH (completion_string + i_byte,
                                    XSTRING (completion)->size - i_byte,
@@ -1770,7 +1845,7 @@ It can find the completion buffer in `standard-output'.")
       write_string ("Possible completions are:", -1);
       for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++)
        {
-         Lisp_Object tem;
+         Lisp_Object tem, string;
          int length;
          Lisp_Object startpos, endpos;
 
@@ -1836,15 +1911,25 @@ It can find the completion buffer in `standard-output'.")
                                    Qnil, Vstandard_output);
            }
 
-         /* Output this element and update COLUMN.  */
+         /* Output this element.
+            If necessary, convert it to unibyte or to multibyte first.  */
          if (CONSP (elt))
-           {
-             Fprinc (Fcar (elt), Qnil);
-             Fprinc (Fcar (Fcdr (elt)), Qnil);
-           }
+           string = Fcar (elt);
          else
-           Fprinc (elt, Qnil);
+           string = elt;
+         if (NILP (current_buffer->enable_multibyte_characters)
+             && STRING_MULTIBYTE (string))
+           string = Fstring_make_unibyte (string);
+         else if (!NILP (current_buffer->enable_multibyte_characters)
+                  && !STRING_MULTIBYTE (string))
+           string = Fstring_make_multibyte (string);
+         Fprinc (string, Qnil);
+
+         /* Output the annotation for this element.  */
+         if (CONSP (elt))
+           Fprinc (Fcar (Fcdr (elt)), Qnil);
 
+         /* Update COLUMN for what we have output.  */
          column += length;
 
          /* If output is to a buffer, recompute COLUMN in a way
@@ -1901,7 +1986,7 @@ DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0,
   ()
 {
   if (INTEGERP (last_command_char))
-    internal_self_insert (last_command_char, 0);
+    internal_self_insert (XINT (last_command_char), 0);
   else
     bitch_at_user ();
 
@@ -1965,7 +2050,7 @@ temp_echo_area_glyphs (m)
   SET_PT_BOTH (opoint, opoint_byte);
   Vinhibit_quit = Qt;
   Fsit_for (make_number (2), Qnil, Qnil);
-  del_range_both (osize, ZV, osize_byte, ZV_BYTE, 1);
+  del_range_both (osize, osize_byte, ZV, ZV_BYTE, 1);
   SET_PT_BOTH (opoint, opoint_byte);
   if (!NILP (Vquit_flag))
     {
@@ -2032,6 +2117,9 @@ syms_of_minibuf ()
   Qminibuffer_history = intern ("minibuffer-history");
   staticpro (&Qminibuffer_history);
 
+  Qbuffer_name_history = intern ("buffer-name-history");
+  staticpro (&Qbuffer_name_history);
+
   Qminibuffer_setup_hook = intern ("minibuffer-setup-hook");
   staticpro (&Qminibuffer_setup_hook);