/* Minibuffer input and completion.
- Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "frame.h"
#include "window.h"
#include "syntax.h"
+#include "keyboard.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
/* Non-nil means it is the window for C-M-v to scroll
when the minibuffer is selected. */
extern Lisp_Object Vminibuf_scroll_window;
+
+extern Lisp_Object Voverriding_local_map;
+\f
+/* Put minibuf on currently selected frame's minibuffer.
+ We do this whenever the user starts a new minibuffer
+ or when a minibuffer exits. */
+
+void
+choose_minibuf_frame ()
+{
+ if (selected_frame != 0
+ && !EQ (minibuf_window, selected_frame->minibuffer_window))
+ {
+#if defined(MSDOS) && !defined(HAVE_X_WINDOWS)
+ selected_frame->minibuffer_window = minibuf_window;
+#else
+ /* I don't think that any frames may validly have a null minibuffer
+ window anymore. */
+ if (NILP (selected_frame->minibuffer_window))
+ abort ();
+
+ Fset_window_buffer (selected_frame->minibuffer_window,
+ XWINDOW (minibuf_window)->buffer);
+ minibuf_window = selected_frame->minibuffer_window;
+#endif
+ }
+}
\f
/* Actual minibuffer invocation. */
Lisp_Object histvar;
Lisp_Object histpos;
{
- register Lisp_Object val;
+ Lisp_Object val;
int count = specpdl_ptr - specpdl;
Lisp_Object mini_frame;
+ struct gcpro gcpro1, gcpro2, gcpro3;
+
+ single_kboard_state ();
+
+ val = Qnil;
+ /* Don't need to protect PROMPT, HISTVAR, and HISTPOS because we
+ store them away before we can GC. Don't need to protect
+ BACKUP_N because we use the value only if it is an integer. */
+ GCPRO3 (map, initial, val);
if (!STRINGP (prompt))
prompt = build_string ("");
- /* Emacs in -batch mode calls minibuffer: print the prompt. */
- if (noninteractive && STRINGP (prompt))
- printf ("%s", XSTRING (prompt)->data);
-
if (!enable_recursive_minibuffers
&& minibuf_level > 0
&& (EQ (selected_window, minibuf_window)))
-#if 0
- || selected_frame != XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)))
-#endif
error ("Command attempted to use minibuffer while in minibuffer");
/* Could we simply bind these variables instead? */
+ minibuf_save_list
+ = Fcons (Voverriding_local_map,
+ Fcons (minibuf_window, minibuf_save_list));
minibuf_save_list
= Fcons (minibuf_prompt,
Fcons (make_number (minibuf_prompt_width),
Fcons (Vminibuffer_history_position,
Fcons (Vminibuffer_history_variable,
minibuf_save_list))))));
- minibuf_prompt_width = 0;
+
+ minibuf_prompt_width = 0; /* xdisp.c puts in the right value. */
+ minibuf_prompt = Fcopy_sequence (prompt);
+ Vminibuffer_history_position = histpos;
+ Vminibuffer_history_variable = histvar;
+
+ choose_minibuf_frame ();
record_unwind_protect (Fset_window_configuration,
Fcurrent_window_configuration (Qnil));
Fforward_char (backup_n);
}
- minibuf_prompt = Fcopy_sequence (prompt);
echo_area_glyphs = 0;
/* This is in case the minibuffer-setup-hook calls Fsit_for. */
previous_echo_glyphs = 0;
Vhelp_form = Vminibuffer_help_form;
current_buffer->keymap = map;
- Vminibuffer_history_position = histpos;
- Vminibuffer_history_variable = histvar;
/* Run our hook, but not if it is empty.
(run-hooks would do nothing if it is empty,
}
/* Make minibuffer contents into a string */
- val = make_buffer_string (1, Z);
+ val = make_buffer_string (1, Z, 1);
+#if 0 /* make_buffer_string should handle the gap. */
bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT);
+#endif
/* VAL is the string of minibuffer text. */
last_minibuf_string = val;
val = Fcar (expr_and_pos);
}
- return unbind_to (count, val); /* The appropriate frame will get selected
- in set-window-configuration. */
+ /* The appropriate frame will get selected
+ in set-window-configuration. */
+ RETURN_UNGCPRO (unbind_to (count, val));
}
/* Return a buffer to be used as the minibuffer at depth `depth'.
so run the hook. */
if (!NILP (Vminibuffer_exit_hook) && !EQ (Vminibuffer_exit_hook, Qunbound)
&& !NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qminibuffer_exit_hook);
+ safe_run_hooks (Qminibuffer_exit_hook);
/* Erase the minibuffer we were using at this level. */
Fset_buffer (XWINDOW (minibuf_window)->buffer);
minibuf_save_list = Fcdr (minibuf_save_list);
Vminibuffer_history_variable = Fcar (minibuf_save_list);
minibuf_save_list = Fcdr (minibuf_save_list);
+ Voverriding_local_map = Fcar (minibuf_save_list);
+ minibuf_save_list = Fcdr (minibuf_save_list);
+ minibuf_window = Fcar (minibuf_save_list);
+ minibuf_save_list = Fcdr (minibuf_save_list);
}
\f
/* Functions that use the minibuffer to read various things. */
-DEFUN ("read-string", Fread_string, Sread_string, 1, 2, 0,
+DEFUN ("read-string", Fread_string, Sread_string, 1, 3, 0,
"Read a string from the minibuffer, prompting with string PROMPT.\n\
-If non-nil second arg INITIAL-INPUT is a string to insert before reading.")
- (prompt, initial_input)
- Lisp_Object prompt, initial_input;
+If non-nil, second arg INITIAL-INPUT is a string to insert before reading.\n\
+The third arg HISTORY, if non-nil, specifies a history list\n\
+ and optionally the initial position in the list.\n\
+See `read-from-minibuffer' for details of HISTORY argument.")
+ (prompt, initial_input, history)
+ Lisp_Object prompt, initial_input, history;
{
- return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, Qnil);
+ return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, history);
}
DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 2, 0,
If optional third argument PREDICATE is non-nil,\n\
it is used to test each possible match.\n\
The match is a candidate only if PREDICATE returns non-nil.\n\
-The argument given to PREDICATE is the alist element or the symbol from the obarray.")
+The argument given to PREDICATE is the alist element\n\
+or the symbol from the obarray.")
(string, alist, pred)
Lisp_Object string, alist, pred;
{
return len - l;
}
\f
-DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 3, 0,
+DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 4, 0,
"Search for partial matches to STRING in ALIST.\n\
Each car of each element of ALIST is tested to see if it begins with STRING.\n\
The value is a list of all the strings from ALIST that match.\n\
+\n\
ALIST can be an obarray instead of an alist.\n\
Then the print names of all symbols in the obarray are the possible matches.\n\
\n\
If optional third argument PREDICATE is non-nil,\n\
it is used to test each possible match.\n\
The match is a candidate only if PREDICATE returns non-nil.\n\
-The argument given to PREDICATE is the alist element or the symbol from the obarray.")
- (string, alist, pred)
- Lisp_Object string, alist, pred;
+The argument given to PREDICATE is the alist element\n\
+or the symbol from the obarray.\n\
+\n\
+If the optional fourth argument HIDE-SPACES is non-nil,\n\
+strings in ALIST that start with a space\n\
+are ignored unless STRING itself starts with a space.")
+ (string, alist, pred, hide_spaces)
+ Lisp_Object string, alist, pred, hide_spaces;
{
Lisp_Object tail, elt, eltstring;
Lisp_Object allmatches;
if (STRINGP (eltstring)
&& XSTRING (string)->size <= XSTRING (eltstring)->size
- /* Reject alternatives that start with space
+ /* If HIDE_SPACES, reject alternatives that start with space
unless the input starts with space. */
&& ((XSTRING (string)->size > 0 && XSTRING (string)->data[0] == ' ')
- || XSTRING (eltstring)->data[0] != ' ')
+ || XSTRING (eltstring)->data[0] != ' '
+ || NILP (hide_spaces))
&& 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data,
XSTRING (string)->size))
{
char *m;
{
int osize = ZV;
+ int opoint = PT;
Lisp_Object oinhibit;
oinhibit = Vinhibit_quit;
SET_PT (osize);
insert_string (m);
- SET_PT (osize);
+ SET_PT (opoint);
Vinhibit_quit = Qt;
Fsit_for (make_number (2), Qnil, Qnil);
- del_range (PT, ZV);
+ del_range (osize, ZV);
+ SET_PT (opoint);
if (!NILP (Vquit_flag))
{
Vquit_flag = Qnil;
/* If the previous command was not this, then mark the completion
buffer obsolete. */
- if (! EQ (last_command, this_command))
+ if (! EQ (current_kboard->Vlast_command, this_command))
Vminibuf_scroll_window = Qnil;
window = Vminibuf_scroll_window;
(completions)
Lisp_Object completions;
{
- register Lisp_Object tail, elt;
+ Lisp_Object tail, elt;
register int i;
int column = 0;
- struct gcpro gcpro1;
+ struct gcpro gcpro1, gcpro2;
struct buffer *old = current_buffer;
int first = 1;
/* Note that (when it matters) every variable
- points to a non-string that is pointed to by COMPLETIONS. */
- GCPRO1 (completions);
+ points to a non-string that is pointed to by COMPLETIONS,
+ except for ELT. ELT can be pointing to a string
+ when terpri or Findent_to calls a change hook. */
+ elt = Qnil;
+ GCPRO2 (completions, elt);
if (BUFFERP (Vstandard_output))
set_buffer_internal (XBUFFER (Vstandard_output));
{
Lisp_Object tem;
int length;
+ Lisp_Object startpos, endpos;
elt = Fcar (tail);
/* Compute the length of this element. */
Sadly, the window it will appear in is not known
until after the text has been made. */
+ if (BUFFERP (Vstandard_output))
+ XSETINT (startpos, BUF_PT (XBUFFER (Vstandard_output)));
+
/* If the previous completion was very wide,
or we have two on this line already,
don't put another on the same line. */
if (BUFFERP (Vstandard_output))
{
tem = Findent_to (make_number (35), make_number (2));
+
column = XINT (tem);
}
else
}
}
+ if (BUFFERP (Vstandard_output))
+ {
+ XSETINT (endpos, BUF_PT (XBUFFER (Vstandard_output)));
+ Fset_text_properties (startpos, endpos,
+ Qnil, Vstandard_output);
+ }
+
/* Output this element and update COLUMN. */
if (CONSP (elt))
{
message ("Making completion list...");
completions = Fall_completions (Fbuffer_string (),
Vminibuffer_completion_table,
- Vminibuffer_completion_predicate);
+ Vminibuffer_completion_predicate,
+ Qt);
echo_area_glyphs = 0;
if (NILP (completions))
DEFVAR_LISP ("minibuffer-history-variable", &Vminibuffer_history_variable,
"History list symbol to add minibuffer values to.\n\
-Each minibuffer output is added with\n\
+Each string of minibuffer input, as it appears on exit from the minibuffer,\n\
+is added with\n\
(set minibuffer-history-variable\n\
(cons STRING (symbol-value minibuffer-history-variable)))");
XSETFASTINT (Vminibuffer_history_variable, 0);