/* Minibuffer input and completion.
- Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,93,94,95,96,97,98,99,2000,01,03
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
init_window_once. That window doesn't have a buffer. */
buffer = XWINDOW (minibuf_window)->buffer;
if (BUFFERP (buffer))
- Fset_window_buffer (sf->minibuffer_window, buffer);
+ Fset_window_buffer (sf->minibuffer_window, buffer, Qnil);
minibuf_window = sf->minibuffer_window;
}
GCPRO2 (val, defalt);
- if (STRINGP (val) && XSTRING (val)->size == 0
+ if (STRINGP (val) && SCHARS (val) == 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)
+ if (pos != SCHARS (val))
{
/* Ignore trailing whitespace; any other trailing junk
is an error. */
int i;
pos = string_char_to_byte (val, pos);
- for (i = pos; i < STRING_BYTES (XSTRING (val)); i++)
+ for (i = pos; i < SBYTES (val); i++)
{
- int c = XSTRING (val)->data[i];
+ int c = SREF (val, i);
if (c != ' ' && c != '\t' && c != '\n')
error ("Trailing garbage following expression");
}
char *line, *s;
Lisp_Object val;
- fprintf (stdout, "%s", XSTRING (prompt)->data);
+ fprintf (stdout, "%s", SDATA (prompt));
fflush (stdout);
val = Qnil;
return val;
}
\f
+DEFUN ("minibufferp", Fminibufferp,
+ Sminibufferp, 0, 1, 0,
+ doc: /* Return t if BUFFER is a minibuffer.
+No argument or nil as argument means use current buffer as BUFFER.*/)
+ (buffer)
+ Lisp_Object buffer;
+{
+ Lisp_Object tem;
+
+ if (NILP (buffer))
+ buffer = Fcurrent_buffer ();
+ else if (STRINGP (buffer))
+ buffer = Fget_buffer (buffer);
+ else
+ CHECK_BUFFER (buffer);
+
+ tem = Fmemq (buffer, Vminibuffer_list);
+ return ! NILP (tem) ? Qt : Qnil;
+}
+
DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end,
Sminibuffer_prompt_end, 0, 0, 0,
doc: /* Return the buffer position of the end of the minibuffer prompt.
()
{
/* This function is written to be most efficient when there's a prompt. */
- Lisp_Object beg = make_number (BEGV);
- Lisp_Object end = Ffield_end (beg, Qnil, Qnil);
+ Lisp_Object beg, end, tem;
+ beg = make_number (BEGV);
+
+ tem = Fmemq (Fcurrent_buffer (), Vminibuffer_list);
+ if (NILP (tem))
+ return beg;
+
+ end = Ffield_end (beg, Qnil, Qnil);
if (XINT (end) == ZV && NILP (Fget_char_property (beg, Qfield, Qnil)))
return beg;
minibuffer_completion_contents ()
{
int prompt_end = XINT (Fminibuffer_prompt_end ());
+ if (PT < prompt_end)
+ error ("Cannot do completion in the prompt");
return make_buffer_string (prompt_end, PT, 1);
}
\f
match the front of that history list exactly. The value is pushed onto
the list as the string that was read.
- DEFALT specifies te default value for the sake of history commands.
+ DEFALT specifies the default value for the sake of history commands.
If ALLOW_PROPS is nonzero, we do not throw away text properties.
int inherit_input_method;
{
Lisp_Object val;
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
Lisp_Object mini_frame, ambient_dir, minibuffer, input_method;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
Lisp_Object enable_multibyte;
+
+ /* String to add to the history. */
+ Lisp_Object histstring;
+
extern Lisp_Object Qfront_sticky;
extern Lisp_Object Qrear_nonsticky;
val = read_minibuf_noninteractive (map, initial, prompt, backup_n,
expflag, histvar, histpos, defalt,
allow_props, inherit_input_method);
+ UNGCPRO;
return unbind_to (count, val);
}
Vminibuf_scroll_window = selected_window;
if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
minibuf_selected_window = selected_window;
- Fset_window_buffer (minibuf_window, Fcurrent_buffer ());
- Fselect_window (minibuf_window);
+ Fset_window_buffer (minibuf_window, Fcurrent_buffer (), Qnil);
+ Fselect_window (minibuf_window, Qnil);
XSETFASTINT (XWINDOW (minibuf_window)->hscroll, 0);
Fmake_local_variable (Qprint_escape_newlines);
last_minibuf_string = val;
- /* Add the value to the appropriate history list unless it is empty. */
- if (XSTRING (val)->size != 0
- && SYMBOLP (Vminibuffer_history_variable))
+ /* Choose the string to add to the history. */
+ if (SCHARS (val) != 0)
+ histstring = val;
+ else if (STRINGP (defalt))
+ histstring = defalt;
+ else
+ histstring = Qnil;
+
+ /* Add the value to the appropriate history list, if any. */
+ if (SYMBOLP (Vminibuffer_history_variable)
+ && !NILP (histstring))
{
/* If the caller wanted to save the value read on a history list,
then do so if the value is not already the front of the list. */
/* The value of the history variable must be a cons or nil. Other
values are unacceptable. We silently ignore these values. */
+
if (NILP (histval)
|| (CONSP (histval)
- && NILP (Fequal (last_minibuf_string, Fcar (histval)))))
+ /* Don't duplicate the most recent entry in the history. */
+ && NILP (Fequal (histstring, Fcar (histval)))))
{
Lisp_Object length;
- histval = Fcons (last_minibuf_string, histval);
+ histval = Fcons (histstring, histval);
Fset (Vminibuffer_history_variable, histval);
/* Truncate if requested. */
/* The appropriate frame will get selected
in set-window-configuration. */
- RETURN_UNGCPRO (unbind_to (count, val));
+ UNGCPRO;
+ return unbind_to (count, val);
}
/* Return a buffer to be used as the minibuffer at depth `depth'.
}
else
{
- int count = specpdl_ptr - specpdl;
-
+ int count = SPECPDL_INDEX ();
+ /* `reset_buffer' blindly sets the list of overlays to NULL, so we
+ have to empty the list, otherwise we end up with overlays that
+ think they belong to this buffer while the buffer doesn't know about
+ them any more. */
+ delete_all_overlays (XBUFFER (buf));
reset_buffer (XBUFFER (buf));
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
Fset_buffer (buf);
/* Erase the minibuffer we were using at this level. */
{
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
/* Prevent error in erase-buffer. */
specbind (Qinhibit_read_only, Qt);
specbind (Qinhibit_modification_hooks, Qt);
/* Convert to distance from end of input. */
if (XINT (position) < 1)
/* A number too small means the beginning of the string. */
- pos = - XSTRING (initial_contents)->size;
+ pos = - SCHARS (initial_contents);
else
- pos = XINT (position) - 1 - XSTRING (initial_contents)->size;
+ pos = XINT (position) - 1 - SCHARS (initial_contents);
}
}
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))
+ if (STRINGP (val) && SCHARS (val) == 0 && ! NILP (default_value))
val = default_value;
return val;
}
DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0,
doc: /* Read the name of a user variable and return it as a symbol.
Prompt with PROMPT. By default, return DEFAULT-VALUE.
-A user variable is one whose documentation starts with a `*' character. */)
+A user variable is one for which `user-variable-p' returns non-nil. */)
(prompt, default_value)
Lisp_Object prompt, default_value;
{
DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0,
doc: /* Return common substring of all completions of STRING in ALIST.
-Each car of each element of ALIST is tested to see if it begins with STRING.
+Each car of each element of ALIST (or each element if it is not a cons cell)
+is tested to see if it begins with STRING.
All that match are compared together; the longest initial sequence
common to all matches is returned as a string.
If there is no match at all, nil is returned.
/* Is this element a possible completion? */
if (STRINGP (eltstring)
- && XSTRING (string)->size <= XSTRING (eltstring)->size
+ && SCHARS (string) <= SCHARS (eltstring)
&& (tem = Fcompare_strings (eltstring, make_number (0),
- make_number (XSTRING (string)->size),
+ make_number (SCHARS (string)),
string, make_number (0), Qnil,
completion_ignore_case ?Qt : Qnil),
EQ (Qt, tem)))
{
matchcount = 1;
bestmatch = eltstring;
- bestmatchsize = XSTRING (eltstring)->size;
+ bestmatchsize = SCHARS (eltstring);
}
else
{
- compare = min (bestmatchsize, XSTRING (eltstring)->size);
+ compare = min (bestmatchsize, SCHARS (eltstring));
tem = Fcompare_strings (bestmatch, make_number (0),
make_number (compare),
eltstring, make_number (0),
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 ((matchsize == SCHARS (eltstring)
+ && matchsize < SCHARS (bestmatch))
||
/* If there is more than one exact match ignoring case,
and one of them is exact including case,
/* 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 == SCHARS (eltstring))
==
- (matchsize == XSTRING (bestmatch)->size)
+ (matchsize == SCHARS (bestmatch))
&& (tem = Fcompare_strings (eltstring, make_number (0),
- make_number (XSTRING (string)->size),
+ make_number (SCHARS (string)),
string, make_number (0),
Qnil,
Qnil),
EQ (Qt, tem))
&& (tem = Fcompare_strings (bestmatch, make_number (0),
- make_number (XSTRING (string)->size),
+ make_number (SCHARS (string)),
string, make_number (0),
Qnil,
Qnil),
! EQ (Qt, tem))))
bestmatch = eltstring;
}
- if (bestmatchsize != XSTRING (eltstring)->size
+ if (bestmatchsize != SCHARS (eltstring)
|| bestmatchsize != matchsize)
/* Don't count the same string multiple times. */
matchcount++;
bestmatchsize = matchsize;
- if (matchsize <= XSTRING (string)->size
+ if (matchsize <= SCHARS (string)
&& matchcount > 1)
/* No need to look any further. */
break;
/* 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)
+ if (completion_ignore_case && bestmatchsize == SCHARS (string)
+ && SCHARS (bestmatch) > 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
+ if (matchcount == 1 && bestmatchsize == SCHARS (string)
&& (tem = Fcompare_strings (bestmatch, make_number (0),
make_number (bestmatchsize),
string, make_number (0),
\f
DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 4, 0,
doc: /* Search for partial matches to STRING in ALIST.
-Each car of each element of ALIST is tested to see if it begins with STRING.
+Each car of each element of ALIST (or each element if it is not a cons cell)
+is tested to see if it begins with STRING.
The value is a list of all the strings from ALIST that match.
If ALIST is a hash-table, all the string keys are the possible matches.
/* Is this element a possible completion? */
if (STRINGP (eltstring)
- && XSTRING (string)->size <= XSTRING (eltstring)->size
+ && SCHARS (string) <= SCHARS (eltstring)
/* If HIDE_SPACES, reject alternatives that start with space
unless the input starts with space. */
- && ((STRING_BYTES (XSTRING (string)) > 0
- && XSTRING (string)->data[0] == ' ')
- || XSTRING (eltstring)->data[0] != ' '
+ && ((SBYTES (string) > 0
+ && SREF (string, 0) == ' ')
+ || SREF (eltstring, 0) != ' '
|| NILP (hide_spaces))
&& (tem = Fcompare_strings (eltstring, make_number (0),
- make_number (XSTRING (string)->size),
+ make_number (SCHARS (string)),
string, make_number (0),
- make_number (XSTRING (string)->size),
+ make_number (SCHARS (string)),
completion_ignore_case ? Qt : Qnil),
EQ (Qt, tem)))
{
and HISTPOS is the initial position (the position in the list
which INITIAL-INPUT corresponds to).
Positions are counted starting from 1 at the beginning of the list.
+ The variable `history-length' controls the maximum length of a
+ history list.
+
DEF, if non-nil, is the default value.
If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits
Lisp_Object val, histvar, histpos, position;
Lisp_Object init;
int pos = 0;
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
struct gcpro gcpro1;
init = initial_input;
{
CHECK_NUMBER (position);
/* Convert to distance from end of input. */
- pos = XINT (position) - XSTRING (init)->size;
+ pos = XINT (position) - SCHARS (init);
}
}
histvar, histpos, def, 0,
!NILP (inherit_input_method));
- if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (def))
+ if (STRINGP (val) && SCHARS (val) == 0 && ! NILP (def))
val = def;
RETURN_UNGCPRO (unbind_to (count, val));
{
/* Bypass intern-soft as that loses for nil. */
tem = oblookup (alist,
- XSTRING (string)->data,
- XSTRING (string)->size,
- STRING_BYTES (XSTRING (string)));
+ SDATA (string),
+ SCHARS (string),
+ SBYTES (string));
if (!SYMBOLP (tem))
{
if (STRING_MULTIBYTE (string))
string = Fstring_make_multibyte (string);
tem = oblookup (Vminibuffer_completion_table,
- XSTRING (string)->data,
- XSTRING (string)->size,
- STRING_BYTES (XSTRING (string)));
+ SDATA (string),
+ SCHARS (string),
+ SBYTES (string));
if (!SYMBOLP (tem))
return Qnil;
}
if (NILP (completion))
{
bitch_at_user ();
- temp_echo_area_glyphs (" [No match]");
+ temp_echo_area_glyphs (build_string (" [No match]"));
UNGCPRO;
return 0;
}
/* Some completion happened */
if (! NILP (Vminibuffer_completing_file_name)
- && XSTRING (completion)->data[STRING_BYTES (XSTRING (completion)) - 1] == '/'
+ && SREF (completion, SBYTES (completion) - 1) == '/'
&& PT < ZV
&& FETCH_CHAR (PT_BYTE) == '/')
{
else if (!NILP (Vcompletion_auto_help))
Fminibuffer_completion_help ();
else
- temp_echo_area_glyphs (" [Next char not unique]");
+ temp_echo_area_glyphs (build_string (" [Next char not unique]"));
return 6;
}
else if (completedp)
case 1:
if (PT != ZV)
Fgoto_char (make_number (ZV));
- temp_echo_area_glyphs (" [Sole completion]");
+ temp_echo_area_glyphs (build_string (" [Sole completion]"));
break;
case 3:
if (PT != ZV)
Fgoto_char (make_number (ZV));
- temp_echo_area_glyphs (" [Complete, but not unique]");
+ temp_echo_area_glyphs (build_string (" [Complete, but not unique]"));
break;
}
case 4:
if (!NILP (Vminibuffer_completion_confirm))
{
- temp_echo_area_glyphs (" [Confirm]");
+ temp_echo_area_glyphs (build_string (" [Confirm]"));
return Qnil;
}
else
{
Lisp_Object completion, tem, tem1;
register int i, i_byte;
- register unsigned char *completion_string;
+ register const unsigned char *completion_string;
struct gcpro gcpro1, gcpro2;
int prompt_end_charpos = XINT (Fminibuffer_prompt_end ());
if (NILP (completion))
{
bitch_at_user ();
- temp_echo_area_glyphs (" [No match]");
+ temp_echo_area_glyphs (build_string (" [No match]"));
return Qnil;
}
if (EQ (completion, Qt))
#if 0 /* How the below code used to look, for reference. */
tem = Fminibuffer_contents ();
- b = XSTRING (tem)->data;
- i = ZV - 1 - XSTRING (completion)->size;
- p = XSTRING (completion)->data;
+ b = SDATA (tem);
+ i = ZV - 1 - SCHARS (completion);
+ p = SDATA (completion);
if (i > 0 ||
0 <= scmp (b, p, ZV - 1))
{
Finsert (1, &tem);
}
}
- buffer_nchars = XSTRING (tem)->size; /* # chars in what we completed. */
- completion_nchars = XSTRING (completion)->size;
+ buffer_nchars = SCHARS (tem); /* # chars in what we completed. */
+ completion_nchars = SCHARS (completion);
i = buffer_nchars - completion_nchars;
if (i > 0
||
i++;
buffer_nchars--;
}
- del_range (1, i + 1);
+ del_range (start_pos, start_pos + buffer_nchars);
}
UNGCPRO;
}
/* If completion finds next char not unique,
consider adding a space or a hyphen. */
- if (i == XSTRING (completion)->size)
+ if (i == SCHARS (completion))
{
GCPRO1 (completion);
tem = Ftry_completion (concat2 (minibuffer_completion_contents (),
i gets index in string of where to stop completing. */
{
int len, c;
- int bytes = STRING_BYTES (XSTRING (completion));
- completion_string = XSTRING (completion)->data;
- for (; i_byte < STRING_BYTES (XSTRING (completion)); i_byte += len, i++)
+ int bytes = SBYTES (completion);
+ completion_string = SDATA (completion);
+ for (; i_byte < SBYTES (completion); i_byte += len, i++)
{
c = STRING_CHAR_AND_LENGTH (completion_string + i_byte,
bytes - i_byte,
/* Otherwise insert in minibuffer the chars we got */
if (! NILP (Vminibuffer_completing_file_name)
- && XSTRING (completion)->data[STRING_BYTES (XSTRING (completion)) - 1] == '/'
+ && SREF (completion, SBYTES (completion) - 1) == '/'
&& PT < ZV
&& FETCH_CHAR (PT_BYTE) == '/')
{
{
tem = XCAR (elt);
CHECK_STRING (tem);
- length = XSTRING (tem)->size;
+ length = SCHARS (tem);
tem = Fcar (XCDR (elt));
CHECK_STRING (tem);
- length += XSTRING (tem)->size;
+ length += SCHARS (tem);
}
else
{
CHECK_STRING (elt);
- length = XSTRING (elt)->size;
+ length = SCHARS (elt);
}
/* This does a bad job for narrower than usual windows.
if (NILP (completions))
{
bitch_at_user ();
- temp_echo_area_glyphs (" [No completions]");
+ temp_echo_area_glyphs (build_string (" [No completions]"));
}
else
internal_with_output_to_temp_buffer ("*Completions*",
}
\f
-/* Temporarily display the string M at the end of the current
+/* Temporarily display STRING at the end of the current
minibuffer contents. This is used to display things like
"[No Match]" when the user requests a completion for a prefix
that has no possible completions, and other quick, unobtrusive
messages. */
void
-temp_echo_area_glyphs (m)
- char *m;
+temp_echo_area_glyphs (string)
+ Lisp_Object string;
{
int osize = ZV;
int osize_byte = ZV_BYTE;
message (0);
SET_PT_BOTH (osize, osize_byte);
- insert_string (m);
+ insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 0);
SET_PT_BOTH (opoint, opoint_byte);
Vinhibit_quit = Qt;
Fsit_for (make_number (2), Qnil, Qnil);
(string)
Lisp_Object string;
{
- temp_echo_area_glyphs (XSTRING (string)->data);
+ CHECK_STRING (string);
+ temp_echo_area_glyphs (string);
return Qnil;
}
\f
defsubr (&Sminibuffer_depth);
defsubr (&Sminibuffer_prompt);
+ defsubr (&Sminibufferp);
defsubr (&Sminibuffer_prompt_end);
defsubr (&Sminibuffer_contents);
defsubr (&Sminibuffer_contents_no_properties);