# HG changeset patch # User Jim Blandy # Date 679576499 0 # Node ID 9b1e9b496441f3376d7ac937b111c059ccfde4f5 # Parent 52f53a69e5c4112a6c89b1c577eb098ca3e12955 *** empty log message *** diff -r 52f53a69e5c4 -r 9b1e9b496441 src/editfns.c --- 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; diff -r 52f53a69e5c4 -r 9b1e9b496441 src/minibuf.c --- 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.")