changeset 330:9b1e9b496441

*** empty log message ***
author Jim Blandy <jimb@redhat.com>
date Mon, 15 Jul 1991 11:14:59 +0000
parents 52f53a69e5c4
children c1f8ba0ea512
files src/editfns.c src/minibuf.c
diffstat 2 files changed, 99 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/editfns.c	Sat Jul 13 22:29:48 1991 +0000
+++ b/src/editfns.c	Mon Jul 15 11:14:59 1991 +0000
@@ -45,7 +45,7 @@
 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 @@
   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 = (char *) getenv ("LOGNAME");
   if (!user_name)
-    user_name = (unsigned char *) getenv ("LOGNAME");
-  if (user_name)
-    Vuser_name = build_string (user_name);
-  else
-    Vuser_name = Vuser_real_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 @@
       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 @@
   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 @@
   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 @@
 	}
     }
 
-  UNGCPRO;
   return Qnil;
 }
 
@@ -589,10 +596,6 @@
   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 @@
 	}
     }
 
-  UNGCPRO;
   return Qnil;
 }
 
@@ -858,6 +860,8 @@
   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 @@
   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 @@
 %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;
--- a/src/minibuf.c	Sat Jul 13 22:29:48 1991 +0000
+++ b/src/minibuf.c	Mon Jul 15 11:14:59 1991 +0000
@@ -530,14 +530,51 @@
 	      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 @@
 }
 
 Lisp_Object Fminibuffer_completion_help ();
+Lisp_Object assoc_for_completion ();
 
 /* returns:
  * 0 no possible completion
@@ -794,7 +832,8 @@
   /* 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 @@
     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 @@
 	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.")