/* Minibuffer input and completion.
- Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "commands.h"
#include "buffer.h"
#include "dispextern.h"
-#include "screen.h"
+#include "frame.h"
#include "window.h"
#include "syntax.h"
int prompt_width;
Lisp_Object help_form;
Lisp_Object current_prefix_arg;
+ Lisp_Object history_position;
+ Lisp_Object history_variable;
};
int minibuf_save_vector_size;
Lisp_Object Vminibuffer_help_form;
+/* Variable which is the history list to add minibuffer values to. */
+
+Lisp_Object Vminibuffer_history_variable;
+
+/* Current position in the history list (adjusted by M-n and M-p). */
+
+Lisp_Object Vminibuffer_history_position;
+
+Lisp_Object Qminibuffer_history;
+
/* Nonzero means completion ignores case. */
int completion_ignore_case;
Lisp_Object get_minibuffer ();
Lisp_Object read_minibuf ();
+/* Read from the minibuffer using keymap MAP, initial contents INITIAL
+ (a string), putting point minus BACKUP_N chars from the end of INITIAL,
+ prompting with PROMPT (a string), using history list HISTVAR
+ with initial position HISTPOS. (BACKUP_N should be <= 0.)
+
+ Normally return the result as a string (the text that was read),
+ but if EXPFLAG is non-nil, read it and return the object read. */
+
Lisp_Object
-read_minibuf (map, initial, prompt, backup_n, expflag)
+read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos)
Lisp_Object map;
Lisp_Object initial;
Lisp_Object prompt;
Lisp_Object backup_n;
int expflag;
+ Lisp_Object histvar;
+ Lisp_Object histpos;
{
register Lisp_Object val;
int count = specpdl_ptr - specpdl;
- Lisp_Object mini_screen = WINDOW_SCREEN (XWINDOW (minibuf_window));
+ Lisp_Object mini_frame;
struct gcpro gcpro1, gcpro2;
if (XTYPE (prompt) != Lisp_String)
&& minibuf_level > 0
&& (EQ (selected_window, minibuf_window)))
#if 0
- || selected_screen != XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)))
+ || selected_frame != XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)))
#endif
error ("Command attempted to use minibuffer while in minibuffer");
/* >> Why is this done this way rather than binding these variables? */
minibuf_save_vector[minibuf_level].help_form = Vhelp_form;
minibuf_save_vector[minibuf_level].current_prefix_arg = Vcurrent_prefix_arg;
+ minibuf_save_vector[minibuf_level].history_position = Vminibuffer_history_position;
+ minibuf_save_vector[minibuf_level].history_variable = Vminibuffer_history_variable;
GCPRO2 (minibuf_save_vector[minibuf_level].help_form,
minibuf_save_vector[minibuf_level].current_prefix_arg);
record_unwind_protect (Fset_window_configuration,
Fcurrent_window_configuration (Qnil));
- /* If the minibuffer window is on a different screen, save that
- screen's configuration too. */
- if (XSCREEN (mini_screen) != selected_screen)
- {
- record_unwind_protect (Fset_window_configuration,
- Fcurrent_window_configuration (mini_screen));
- }
+ /* If the minibuffer window is on a different frame, save that
+ frame's configuration too. */
+#ifdef MULTI_FRAME
+ XSET (mini_frame, Lisp_Frame, WINDOW_FRAME (XWINDOW (minibuf_window)));
+ if (XFRAME (mini_frame) != selected_frame)
+ record_unwind_protect (Fset_window_configuration,
+ Fcurrent_window_configuration (mini_frame));
+#endif
val = current_buffer->directory;
Fset_buffer (get_minibuffer (minibuf_level));
- current_buffer->directory = val;
- Fmake_local_variable (Qprint_escape_newlines);
- print_escape_newlines = 1;
-#ifdef MULTI_SCREEN
- /* If the minibuffer window is on another screen, shift this screen's
- focus to that window, and arrange to put it back later. */
- if (XSCREEN (WINDOW_SCREEN (XWINDOW (minibuf_window)))
- != selected_screen)
+ /* The current buffer's default directory is usually the right thing
+ for our minibuffer here. However, if you're typing a command at
+ a minibuffer-only frame when minibuf_level is zero, then buf IS
+ the current_buffer, so reset_buffer leaves buf's default
+ directory unchanged. This is a bummer when you've just started
+ up Emacs and buf's default directory is Qnil. Here's a hack; can
+ you think of something better to do? Find another buffer with a
+ better directory, and use that one instead. */
+ if (XTYPE (val) == Lisp_String)
+ current_buffer->directory = val;
+ else
{
- record_unwind_protect (read_minibuf_unwind,
- Fcons (Fselected_screen (),
- SCREEN_FOCUS_SCREEN (selected_screen)));
+ Lisp_Object buf_list;
+
+ for (buf_list = Vbuffer_alist;
+ CONSP (buf_list);
+ buf_list = XCONS (buf_list)->cdr)
+ {
+ Lisp_Object other_buf = XCONS (XCONS (buf_list)->car)->cdr;
- Fredirect_screen_focus (Fselected_screen (), mini_screen);
+ if (XTYPE (XBUFFER (other_buf)->directory) == Lisp_String)
+ {
+ current_buffer->directory = XBUFFER (other_buf)->directory;
+ break;
+ }
+ }
}
- else
- record_unwind_protect (read_minibuf_unwind, Qnil);
-#else
- record_unwind_protect (read_minibuf_unwind, Qnil);
+
+#ifdef MULTI_FRAME
+ Fredirect_frame_focus (Fselected_frame (), mini_frame);
#endif
+ Fmake_local_variable (Qprint_escape_newlines);
+ print_escape_newlines = 1;
+
+ record_unwind_protect (read_minibuf_unwind, Qnil);
Vminibuf_scroll_window = selected_window;
Fset_window_buffer (minibuf_window, Fcurrent_buffer ());
Vhelp_form = Vminibuffer_help_form;
current_buffer->keymap = map;
+ Vminibuffer_history_position = histpos;
+ Vminibuffer_history_variable = histvar;
/* ??? MCC did redraw_screen here if switching screens. */
recursive_edit_1 ();
/* If cursor is on the minibuffer line,
show the user we have exited by putting it in column 0. */
- if ((SCREEN_CURSOR_Y (selected_screen)
+ if ((FRAME_CURSOR_Y (selected_frame)
>= XFASTINT (XWINDOW (minibuf_window)->top))
&& !noninteractive)
{
- SCREEN_CURSOR_X (selected_screen) = 0;
- update_screen (selected_screen, 1, 1);
+ FRAME_CURSOR_X (selected_frame) = 0;
+ update_frame (selected_frame, 1, 1);
}
/* Make minibuffer contents into a string */
val = make_buffer_string (1, Z);
bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT);
- unbind_to (count, Qnil); /* The appropriate screen will get selected
+
+ /* Add the value to the appropriate history list. */
+ if (XTYPE (Vminibuffer_history_variable) == Lisp_Symbol
+ && ! EQ (XSYMBOL (Vminibuffer_history_variable)->value, Qunbound))
+ Fset (Vminibuffer_history_variable,
+ Fcons (val, Fsymbol_value (Vminibuffer_history_variable)));
+
+ unbind_to (count, Qnil); /* The appropriate frame will get selected
in set-window-configuration. */
UNGCPRO;
/* VAL is the string of minibuffer text. */
-
last_minibuf_string = val;
/* If Lisp form desired instead of string, parse it */
{
sprintf (name, " *Minibuf-%d*", depth);
buf = Fget_buffer_create (build_string (name));
+
+ /* Although the buffer's name starts with a space, undo should be
+ enabled in it. */
+ Fbuffer_enable_undo (buf);
+
XCONS (tail)->car = buf;
}
else
reset_buffer (XBUFFER (buf));
+
return buf;
}
minibuf_prompt_width = minibuf_save_vector[minibuf_level].prompt_width;
Vhelp_form = minibuf_save_vector[minibuf_level].help_form;
Vcurrent_prefix_arg = minibuf_save_vector[minibuf_level].current_prefix_arg;
-
-#ifdef MULTI_SCREEN
- /* Redirect the focus of the screen that called the minibuffer. */
- if (CONSP (data))
- Fredirect_screen_focus (XCONS (data)->car, XCONS (data)->cdr);
-#endif
+ Vminibuffer_history_position
+ = minibuf_save_vector[minibuf_level].history_position;
+ Vminibuffer_history_variable
+ = minibuf_save_vector[minibuf_level].history_variable;
}
\f
+
+/* This comment supplies the doc string for read-from-minibuffer,
+ for make-docfile to see. We cannot put this in the real DEFUN
+ due to limits in the Unix cpp.
+
DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 5, 0,
"Read a string from the minibuffer, prompting with string PROMPT.\n\
If optional second arg INITIAL-CONTENTS is non-nil, it is a string\n\
to be inserted into the minibuffer before reading input.\n\
+ If INITIAL-CONTENTS is (STRING . POSITION), the initial input\n\
+ is STRING, but point is placed POSITION characters into the string.\n\
Third arg KEYMAP is a keymap to use whilst reading;\n\
if omitted or nil, the default is `minibuffer-local-map'.\n\
If fourth arg READ is non-nil, then interpret the result as a lisp object\n\
and return that object:\n\
in other words, do `(car (read-from-string INPUT-STRING))'\n\
-Fifth arg POSITION, if non-nil, is where to put point\n\
- in the minibuffer after inserting INITIAL-CONTENTS.")
- (prompt, initial_input, keymap, read, position)
- Lisp_Object prompt, initial_input, keymap, read, position;
+Fifth arg HIST, if non-nil, specifies a history list\n\
+ and optionally the initial position in the list.\n\
+ It can be a symbol, which is the history list variable to use,\n\
+ or it can be a cons cell (HISTVAR . HISTPOS).\n\
+ In that case, HISTVAR is the history list variable to use,\n\
+ and HISTPOS is the initial position (the position in the list\n\
+ which INITIAL-CONTENTS corresponds to).\n\
+ Positions are counted starting from 1 at the beginning of the list."
+*/
+
+DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 5, 0,
+ 0 /* See immediately above */)
+ (prompt, initial_input, keymap, read, hist)
+ Lisp_Object prompt, initial_input, keymap, read, hist;
{
int pos = 0;
+ Lisp_Object histvar, histpos, position;
+ position = Qnil;
CHECK_STRING (prompt, 0);
if (!NILP (initial_input))
{
+ if (XTYPE (initial_input) == Lisp_Cons)
+ {
+ position = Fcdr (initial_input);
+ initial_input = Fcar (initial_input);
+ }
CHECK_STRING (initial_input, 1);
if (!NILP (position))
{
keymap = Vminibuffer_local_map;
else
keymap = get_keymap (keymap,2);
+
+ if (XTYPE (hist) == Lisp_Symbol)
+ {
+ histvar = hist;
+ histpos = Qnil;
+ }
+ else
+ {
+ histvar = Fcar_safe (hist);
+ histpos = Fcdr_safe (hist);
+ }
+ if (NILP (histvar))
+ histvar = Qminibuffer_history;
+ if (NILP (histpos))
+ XFASTINT (histpos) = 0;
+
return read_minibuf (keymap, initial_input, prompt,
- pos, !NILP (read));
+ make_number (pos), !NILP (read), histvar, histpos);
}
DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
CHECK_STRING (prompt, 0);
if (!NILP (initial_contents))
CHECK_STRING (initial_contents, 1)
- return read_minibuf (Vminibuffer_local_map, initial_contents, prompt, Qnil, 1);
+ return read_minibuf (Vminibuffer_local_map, initial_contents,
+ prompt, Qnil, 1, Qminibuffer_history, make_number (0));
}
DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, Qnil);
}
-DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 2, 1, 0,
+DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 2, 2, 0,
"Args PROMPT and INIT, strings. Read a string from the terminal, not allowing blanks.\n\
Prompt with PROMPT, and provide INIT as an initial value of the input string.")
(prompt, init)
if (! NILP (init))
CHECK_STRING (init, 1);
- return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil, 0);
+ return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil, 0,
+ Qminibuffer_history, make_number (0));
}
DEFUN ("read-command", Fread_command, Sread_command, 1, 1, 0,
Lisp_Object Vminibuffer_completion_predicate, Qminibuffer_completion_predicate;
Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;
+/* This comment supplies the doc string for completing-read,
+ for make-docfile to see. We cannot put this in the real DEFUN
+ due to limits in the Unix cpp.
+
DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 6, 0,
"Read a string in the minibuffer, with completion.\n\
-Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, BACKUP-N.\n\
+Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST.\n\
PROMPT is a string to prompt with; normally it ends in a colon and a space.\n\
TABLE is an alist whose elements' cars are strings, or an obarray.\n\
PREDICATE limits completion to a subset of TABLE.\n\
the input is (or completes to) an element of TABLE.\n\
If it is also not t, Return does not exit if it does non-null completion.\n\
If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\n\
-Case is ignored if ambient value of `completion-ignore-case' is non-nil.\n\
-If BACKUP-N is specified, point should be placed that many spaces from\n\
-the end of the buffer. This is useful when providing default values,\n\
-because you can put point before the last component of a filename or any\n\
-other component that is likely to be deleted.")
- (prompt, table, pred, require_match, init, backup_n)
- Lisp_Object prompt, table, pred, require_match, init, backup_n;
+ If it is (STRING . POSITION), the initial input\n\
+ is STRING, but point is placed POSITION characters into the string.\n\
+HIST, if non-nil, specifies a history list\n\
+ and optionally the initial position in the list.\n\
+ It can be a symbol, which is the history list variable to use,\n\
+ or it can be a cons cell (HISTVAR . HISTPOS).\n\
+ In that case, HISTVAR is the history list variable to use,\n\
+ and HISTPOS is the initial position (the position in the list\n\
+ which INITIAL-CONTENTS corresponds to).\n\
+ Positions are counted starting from 1 at the beginning of the list.\n\
+Completion ignores case if the ambient value of\n\
+ `completion-ignore-case' is non-nil."
+*/
+DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 6, 0,
+ 0 /* See immediately above */)
+ (prompt, table, pred, require_match, init, hist)
+ Lisp_Object prompt, table, pred, require_match, init, hist;
{
- Lisp_Object val;
+ Lisp_Object val, histvar, histpos, position;
+ int pos = 0;
int count = specpdl_ptr - specpdl;
specbind (Qminibuffer_completion_table, table);
specbind (Qminibuffer_completion_predicate, pred);
specbind (Qminibuffer_completion_confirm,
EQ (require_match, Qt) ? Qnil : Qt);
last_exact_completion = Qnil;
+
+ position = Qnil;
+ if (!NILP (init))
+ {
+ if (XTYPE (init) == Lisp_Cons)
+ {
+ position = Fcdr (init);
+ init = Fcar (init);
+ }
+ CHECK_STRING (init, 0);
+ if (!NILP (position))
+ {
+ CHECK_NUMBER (position, 0);
+ /* Convert to distance from end of input. */
+ pos = XINT (position) - XSTRING (init)->size;
+ }
+ }
+
+ if (XTYPE (hist) == Lisp_Symbol)
+ {
+ histvar = hist;
+ histpos = Qnil;
+ }
+ else
+ {
+ histvar = Fcar_safe (hist);
+ histpos = Fcdr_safe (hist);
+ }
+ if (NILP (histvar))
+ histvar = Qminibuffer_history;
+ if (NILP (histpos))
+ XFASTINT (histpos) = 0;
+
val = read_minibuf (NILP (require_match)
? Vminibuffer_local_completion_map
: Vminibuffer_local_must_match_map,
- init, prompt, backup_n, 0);
+ init, prompt, make_number (pos), 0,
+ histvar, histpos);
return unbind_to (count, val);
}
\f
temp_echo_area_glyphs (m)
char *m;
{
- /* It's not very modular to do things this way, but then it seems
- to me that the whole echo_area_glyphs thing is a hack anyway. */
- extern char *previous_echo_glyphs;
-
int osize = ZV;
Lisp_Object oinhibit;
oinhibit = Vinhibit_quit;
- /* Clear out any old echo-area message to make way for our new
- thing. */
- echo_area_glyphs = previous_echo_glyphs = 0;
+ /* Clear out any old echo-area message to make way for our new thing. */
+ message (0);
SET_PT (osize);
insert_string (m);
if (!NILP (Vquit_flag))
{
Vquit_flag = Qnil;
- unread_command_char = Ctl ('g');
+ unread_command_events = Fcons (make_number (Ctl ('g')), Qnil);
}
Vinhibit_quit = oinhibit;
}
\f
DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_list,
1, 1, 0,
- "Display in a buffer the list of completions, COMPLETIONS.\n\
+ "Display the list of completions, COMPLETIONS, using `standard-output'.\n\
Each element may be just a symbol or string\n\
or may be a list of two strings to be printed as if concatenated.")
(completions)
{
register Lisp_Object tail, elt;
register int i;
- struct buffer *old = current_buffer;
+ int column = 0;
/* No GCPRO needed, since (when it matters) every variable
points to a non-string that is pointed to by COMPLETIONS. */
-
- set_buffer_internal (XBUFFER (Vstandard_output));
+ struct buffer *old = current_buffer;
+ if (XTYPE (Vstandard_output) == Lisp_Buffer)
+ set_buffer_internal (XBUFFER (Vstandard_output));
if (NILP (completions))
- insert_string ("There are no possible completions of what you have typed.");
+ write_string ("There are no possible completions of what you have typed.", -1);
else
{
- insert_string ("Possible completions are:");
+ write_string ("Possible completions are:", -1);
for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++)
{
/* this needs fixing for the case of long completions
/* Sadly, the window it will appear in is not known
until after the text has been made. */
if (i & 1)
- Findent_to (make_number (35), make_number (1));
+ {
+ if (XTYPE (Vstandard_output) == Lisp_Buffer)
+ Findent_to (make_number (35), make_number (1));
+ else
+ {
+ do
+ {
+ write_string (" ", -1);
+ column++;
+ }
+ while (column < 35);
+ }
+ }
else
- Fterpri (Qnil);
+ {
+ Fterpri (Qnil);
+ column = 0;
+ }
elt = Fcar (tail);
if (CONSP (elt))
{
+ if (XTYPE (Vstandard_output) != Lisp_Buffer)
+ {
+ Lisp_Object tem;
+ tem = Flength (Fcar (elt));
+ column += XINT (tem);
+ tem = Flength (Fcar (Fcdr (elt)));
+ column += XINT (tem);
+ }
Fprinc (Fcar (elt), Qnil);
Fprinc (Fcar (Fcdr (elt)), Qnil);
}
else
- Fprinc (elt, Qnil);
+ {
+ if (XTYPE (Vstandard_output) != Lisp_Buffer)
+ {
+ Lisp_Object tem;
+ tem = Flength (elt);
+ column += XINT (tem);
+ }
+ Fprinc (elt, Qnil);
+ }
}
}
- set_buffer_internal (old);
+
+ if (XTYPE (Vstandard_output) == Lisp_Buffer)
+ set_buffer_internal (old);
return Qnil;
}
Quser_variable_p = intern ("user-variable-p");
staticpro (&Quser_variable_p);
-
+ Qminibuffer_history = intern ("minibuffer-history");
+ staticpro (&Qminibuffer_history);
DEFVAR_BOOL ("completion-auto-help", &auto_help,
"*Non-nil means automatically provide help for invalid completion input.");
"Value that `help-form' takes on inside the minibuffer.");
Vminibuffer_help_form = Qnil;
+ DEFVAR_LISP ("minibuffer-history-variable", &Vminibuffer_history_variable,
+ "History list symbol to add minibuffer values to.\n\
+Each minibuffer output is added with\n\
+ (set minibuffer-history-variable\n\
+ (cons STRING (symbol-value minibuffer-history-variable)))");
+ XFASTINT (Vminibuffer_history_variable) = 0;
+
+ DEFVAR_LISP ("minibuffer-history-position", &Vminibuffer_history_position,
+ "Current position of redoing in the history list.");
+ Vminibuffer_history_position = Qnil;
+
defsubr (&Sread_from_minibuffer);
defsubr (&Seval_minibuffer);
defsubr (&Sread_minibuffer);