*** empty log message ***
authorJim Blandy <jimb@redhat.com>
Mon, 15 Jul 1991 11:14:59 +0000 (11:14 +0000)
committerJim Blandy <jimb@redhat.com>
Mon, 15 Jul 1991 11:14:59 +0000 (11:14 +0000)
src/editfns.c
src/minibuf.c

index c79f75e..efdf7f7 100644 (file)
@@ -45,7 +45,7 @@ Lisp_Object Vuser_name;               /* user name from USER or LOGNAME.  */
 void
 init_editfns ()
 {
-  unsigned char *user_name;
+  char *user_name;
   register unsigned char *p, *q, *r;
   struct passwd *pw;   /* password entry for the current user */
   extern char *index ();
@@ -71,17 +71,23 @@ init_editfns ()
   pw = (struct passwd *) getpwuid (getuid ());
   Vuser_real_name = build_string (pw ? pw->pw_name : "unknown");
 
-  user_name = (unsigned char *) getenv ("USER");
+  /* Get the effective user name, by consulting environment variables,
+     or the effective uid if those are unset.  */
+  user_name = (char *) getenv ("USER");
   if (!user_name)
-    user_name = (unsigned char *) getenv ("LOGNAME");
-  if (user_name)
-    Vuser_name = build_string (user_name);
-  else
-    Vuser_name = Vuser_real_name;
+    user_name = (char *) getenv ("LOGNAME");
+  if (!user_name)
+    {
+      pw = (struct passwd *) getpwuid (geteuid ());
+      user_name = (char *) (pw ? pw->pw_name : "unknown");
+    }
+  Vuser_name = build_string (user_name);
 
+  /* If the user name claimed in the environment vars differs from
+     the real uid, use the claimed name to find the full name.  */
   tem = Fstring_equal (Vuser_name, Vuser_real_name);
-  if (!NULL (tem))
-    pw = (struct passwd *) getpwnam (user_name);
+  if (NULL (tem))
+    pw = (struct passwd *) getpwnam (XSTRING (Vuser_name)->data);
   
   p = (unsigned char *) (pw ? USER_FULL_NAME : "unknown");
   q = (unsigned char *) index (p, ',');
@@ -96,7 +102,7 @@ init_editfns ()
       r = (char *) alloca (strlen (p) + XSTRING (Vuser_name)->size + 1);
       bcopy (p, r, q - p);
       r[q - p] = 0;
-      strcat (r, XSTRING (user_name)->data);
+      strcat (r, XSTRING (Vuser_name)->data);
       r[q - p] = UPCASE (r[q - p]);
       strcat (r, q + 1);
       Vuser_full_name = build_string (r);
@@ -538,6 +544,12 @@ insert1 (arg)
   Finsert (1, &arg);
 }
 
+
+/* Callers passing one argument to Finsert need not gcpro the
+   argument "array", since the only element of the array will
+   not be used after calling insert or insert_from_string, so
+   we don't care if it gets trashed.  */
+
 DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
   "Insert the arguments, either strings or characters, at point.\n\
 Point moves forward so that it ends up after the inserted text.\n\
@@ -549,10 +561,6 @@ Any other markers at the point of insertion remain before the text.")
   register int argnum;
   register Lisp_Object tem;
   char str[1];
-  struct gcpro gcpro1;
-
-  GCPRO1 (*args);
-  gcpro1.nvars = nargs;
 
   for (argnum = 0; argnum < nargs; argnum++)
     {
@@ -574,7 +582,6 @@ Any other markers at the point of insertion remain before the text.")
        }
     }
 
-  UNGCPRO;
   return Qnil;
 }
 
@@ -589,10 +596,6 @@ Any other markers at the point of insertion also end up after the text.")
   register int argnum;
   register Lisp_Object tem;
   char str[1];
-  struct gcpro gcpro1;
-
-  GCPRO1 (*args);
-  gcpro1.nvars = nargs;
 
   for (argnum = 0; argnum < nargs; argnum++)
     {
@@ -614,7 +617,6 @@ Any other markers at the point of insertion also end up after the text.")
        }
     }
 
-  UNGCPRO;
   return Qnil;
 }
 \f
@@ -858,6 +860,8 @@ This allows the buffer's full text to be seen and edited.")
   BEGV = BEG;
   SET_BUF_ZV (current_buffer, Z);
   clip_changed = 1;
+  /* Changing the buffer bounds invalidates any recorded current column.  */
+  invalidate_current_column ();
   return Qnil;
 }
 
@@ -895,6 +899,8 @@ or markers) bounding the text that should remain visible.")
   if (point > XFASTINT (e))
     SET_PT (XFASTINT (e));
   clip_changed = 1;
+  /* Changing the buffer bounds invalidates any recorded current column.  */
+  invalidate_current_column ();
   return Qnil;
 }
 
@@ -1007,7 +1013,8 @@ It may contain %-sequences meaning to substitute the next argument.\n\
 %d means print as number in decimal (%o octal, %x hex).\n\
 %c means print a number as a single character.\n\
 %S means print any object as an s-expression (using prin1).\n\
-The argument used for %d, %o, %x or %c must be a number.")
+  The argument used for %d, %o, %x or %c must be a number.\n\
+Use %% to put a single % into the output.")
   (nargs, args)
      int nargs;
      register Lisp_Object *args;
index 478e95b..6369438 100644 (file)
@@ -530,14 +530,51 @@ The argument given to PREDICATE is the alist element or the symbol from the obar
              matchsize = scmp (XSTRING (bestmatch)->data,
                                XSTRING (eltstring)->data,
                                compare);
-             bestmatchsize = (matchsize >= 0) ? matchsize : compare;
+             if (matchsize < 0)
+               matchsize = compare;
+             if (completion_ignore_case)
+               {
+                 /* If this is an exact match except for case,
+                    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
+                      && matchsize < XSTRING (bestmatch)->size)
+                     ||
+                     /* If there is more than one exact match ignoring case,
+                        and one of them is exact including case,
+                        prefer that one.  */
+                     /* If there is no exact match ignoring case,
+                        prefer a match that does not change the case
+                        of the input.  */
+                     ((matchsize == XSTRING (eltstring)->size)
+                      ==
+                      (matchsize == XSTRING (bestmatch)->size)
+                      && !bcmp (XSTRING (eltstring)->data,
+                                XSTRING (string)->data, XSTRING (string)->size)
+                      && bcmp (XSTRING (bestmatch)->data,
+                               XSTRING (string)->data, XSTRING (string)->size)))
+                   bestmatch = eltstring;
+               }
+             bestmatchsize = matchsize;
            }
        }
     }
 
   if (NULL (bestmatch))
     return Qnil;               /* No completions found */
-  if (matchcount == 1 && bestmatchsize == XSTRING (string)->size)
+  /* 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
+      && XSTRING (bestmatch)->size > bestmatchsize)
+    return string;
+
+  /* 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
+      && !bcmp (XSTRING (bestmatch)->data, XSTRING (string)->data,
+               bestmatchsize))
     return Qt;
 
   XFASTINT (zero) = 0;         /* Else extract the part in which */
@@ -752,6 +789,7 @@ temp_echo_area_glyphs (m)
 }
 
 Lisp_Object Fminibuffer_completion_help ();
+Lisp_Object assoc_for_completion ();
 
 /* returns:
  * 0 no possible completion
@@ -794,7 +832,8 @@ do_completion ()
   /* It did find a match.  Do we match some possibility exactly now? */
   if (CONSP (Vminibuffer_completion_table)
       || NULL (Vminibuffer_completion_table))
-    tem = Fassoc (Fbuffer_string (), Vminibuffer_completion_table);
+    tem = assoc_for_completion (Fbuffer_string (),
+                               Vminibuffer_completion_table);
   else if (XTYPE (Vminibuffer_completion_table) == Lisp_Vector)
     {
       /* the primitive used by Fintern_soft */
@@ -831,7 +870,7 @@ do_completion ()
     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 no we give him help.  */
+     message and the user's hit TAB again, so now we give him help.  */
   last_exact_completion = completion;
   if (!NULL (last))
     {
@@ -840,9 +879,36 @@ do_completion ()
        Fminibuffer_completion_help ();
     }
   return 3;
-
 }
   
+/* Like assoc but assumes KEY is a string, and ignores case if appropriate.  */
+
+Lisp_Object
+assoc_for_completion (key, list)
+     register Lisp_Object key;
+     Lisp_Object list;
+{
+  register Lisp_Object tail;
+
+  if (completion_ignore_case)
+    key = Fupcase (key);
+
+  for (tail = list; !NULL (tail); tail = Fcdr (tail))
+    {
+      register Lisp_Object elt, tem, thiscar;
+      elt = Fcar (tail);
+      if (!CONSP (elt)) continue;
+      thiscar = Fcar (elt);
+      if (XTYPE (thiscar) != Lisp_String)
+       continue;
+      if (completion_ignore_case)
+       thiscar = Fupcase (thiscar);
+      tem = Fequal (thiscar, key);
+      if (!NULL (tem)) return elt;
+      QUIT;
+    }
+  return Qnil;
+}
 
 DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "",
   "Complete the minibuffer contents as far as possible.")