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 ();
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, ',');
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);
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\
register int argnum;
register Lisp_Object tem;
char str[1];
- struct gcpro gcpro1;
-
- GCPRO1 (*args);
- gcpro1.nvars = nargs;
for (argnum = 0; argnum < nargs; argnum++)
{
}
}
- UNGCPRO;
return Qnil;
}
register int argnum;
register Lisp_Object tem;
char str[1];
- struct gcpro gcpro1;
-
- GCPRO1 (*args);
- gcpro1.nvars = nargs;
for (argnum = 0; argnum < nargs; argnum++)
{
}
}
- UNGCPRO;
return Qnil;
}
\f
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;
}
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;
}
%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;
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 */
}
Lisp_Object Fminibuffer_completion_help ();
+Lisp_Object assoc_for_completion ();
/* returns:
* 0 no possible 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 */
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))
{
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.")