/* Minibuffer input and completion.
- Copyright (C) 1985,86,93,94,95,96,97,98,99,2000,01,03
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005,
+ 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
Lisp_Object Qhistory_length, Vhistory_length;
+/* No duplicates in history. */
+
+int history_delete_duplicates;
+
+/* Non-nil means add new input to history. */
+
+Lisp_Object Vhistory_add_new_input;
+
/* Fread_minibuffer leaves the input here as a string. */
Lisp_Object last_minibuf_string;
static Lisp_Object last_exact_completion;
-extern Lisp_Object Voverriding_local_map;
+/* Keymap for reading expressions. */
+Lisp_Object Vread_expression_map;
Lisp_Object Quser_variable_p;
Lisp_Object Qcase_fold_search;
+Lisp_Object Qread_expression_history;
+
+extern Lisp_Object Voverriding_local_map;
+
extern Lisp_Object Qmouse_face;
extern Lisp_Object Qfield;
/* Actual minibuffer invocation. */
static Lisp_Object read_minibuf_unwind P_ ((Lisp_Object));
+static Lisp_Object run_exit_minibuf_hook P_ ((Lisp_Object));
static Lisp_Object read_minibuf P_ ((Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object,
int, Lisp_Object,
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.
-Return (point-min) if current buffer is not a mini-buffer. */)
+Return (point-min) if current buffer is not a minibuffer. */)
()
{
/* This function is written to be most efficient when there's a prompt. */
return make_buffer_string (prompt_end, ZV, 0);
}
+DEFUN ("minibuffer-completion-contents", Fminibuffer_completion_contents,
+ Sminibuffer_completion_contents, 0, 0, 0,
+ doc: /* Return the user input in a minibuffer before point as a string.
+That is what completion commands operate on.
+The current buffer must be a minibuffer. */)
+ ()
+{
+ 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);
+}
+
DEFUN ("delete-minibuffer-contents", Fdelete_minibuffer_contents,
Sdelete_minibuffer_contents, 0, 0, 0,
doc: /* Delete all user input in a minibuffer.
return Qnil;
}
-/* Get the text in the minibuffer before point.
- That is what completion commands operate on. */
-
-Lisp_Object
-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
/* Read from the minibuffer using keymap MAP and initial contents INITIAL,
putting point minus BACKUP_N bytes from the end of INITIAL,
/* String to add to the history. */
Lisp_Object histstring;
+ Lisp_Object empty_minibuf;
+ Lisp_Object dummy, frame;
+
extern Lisp_Object Qfront_sticky;
extern Lisp_Object Qrear_nonsticky;
build_string ("Command attempted to use minibuffer while in minibuffer"));
}
- if (noninteractive)
+ if (noninteractive && NILP (Vexecuting_kbd_macro))
{
val = read_minibuf_noninteractive (map, initial, prompt,
make_number (pos),
record_unwind_protect (read_minibuf_unwind, Qnil);
minibuf_level++;
+ /* We are exiting the minibuffer one way or the other, so run the hook.
+ It should be run before unwinding the minibuf settings. Do it
+ separately from read_minibuf_unwind because we need to make sure that
+ read_minibuf_unwind is fully executed even if exit-minibuffer-hook
+ signals an error. --Stef */
+ record_unwind_protect (run_exit_minibuf_hook, Qnil);
/* Now that we can restore all those variables, start changing them. */
minibuffer = get_minibuffer (minibuf_level);
Fset_buffer (minibuffer);
+ /* If appropriate, copy enable-multibyte-characters into the minibuffer. */
+ if (inherit_input_method)
+ current_buffer->enable_multibyte_characters = enable_multibyte;
+
/* 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
Vminibuf_scroll_window = selected_window;
if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
minibuf_selected_window = selected_window;
+
+ /* Empty out the minibuffers of all frames other than the one
+ where we are going to display one now.
+ Set them to point to ` *Minibuf-0*', which is always empty. */
+ empty_minibuf = Fget_buffer (build_string (" *Minibuf-0*"));
+
+ FOR_EACH_FRAME (dummy, frame)
+ {
+ Lisp_Object root_window = Fframe_root_window (frame);
+ Lisp_Object mini_window = XWINDOW (root_window)->next;
+
+ if (! NILP (mini_window) && ! EQ (mini_window, minibuf_window)
+ && !NILP (Fwindow_minibuffer_p (mini_window)))
+ Fset_window_buffer (mini_window, empty_minibuf, Qnil);
+ }
+
+ /* Display this minibuffer in the proper window. */
Fset_window_buffer (minibuf_window, Fcurrent_buffer (), Qnil);
Fselect_window (minibuf_window, Qnil);
XSETFASTINT (XWINDOW (minibuf_window)->hscroll, 0);
minibuf_prompt_width = (int) current_column (); /* iftc */
- /* If appropriate, copy enable-multibyte-characters into the minibuffer. */
- if (inherit_input_method)
- current_buffer->enable_multibyte_characters = enable_multibyte;
-
/* Put in the initial input. */
if (!NILP (initial))
{
histstring = Qnil;
/* Add the value to the appropriate history list, if any. */
- if (SYMBOLP (Vminibuffer_history_variable)
+ if (!NILP (Vhistory_add_new_input)
+ && SYMBOLP (Vminibuffer_history_variable)
&& !NILP (histstring))
{
/* If the caller wanted to save the value read on a history list,
if (NILP (histval)
|| (CONSP (histval)
/* Don't duplicate the most recent entry in the history. */
- && NILP (Fequal (histstring, Fcar (histval)))))
+ && (NILP (Fequal (histstring, Fcar (histval))))))
{
Lisp_Object length;
+ if (history_delete_duplicates) Fdelete (histstring, histval);
histval = Fcons (histstring, histval);
Fset (Vminibuffer_history_variable, histval);
return buf;
}
+static Lisp_Object
+run_exit_minibuf_hook (data)
+ Lisp_Object data;
+{
+ if (!NILP (Vminibuffer_exit_hook) && !EQ (Vminibuffer_exit_hook, Qunbound)
+ && !NILP (Vrun_hooks))
+ safe_run_hooks (Qminibuffer_exit_hook);
+
+ return Qnil;
+}
+
/* This function is called on exiting minibuffer, whether normally or
not, and it restores the current window, buffer, etc. */
Lisp_Object old_deactivate_mark;
Lisp_Object window;
- /* We are exiting the minibuffer one way or the other,
- so run the hook. */
- if (!NILP (Vminibuffer_exit_hook) && !EQ (Vminibuffer_exit_hook, Qunbound)
- && !NILP (Vrun_hooks))
- safe_run_hooks (Qminibuffer_exit_hook);
-
/* If this was a recursive minibuffer,
tie the minibuffer window back to the outer level minibuffer buffer. */
minibuf_level--;
one puts point at the beginning of the string. *Note* that this
behavior differs from the way such arguments are used in `completing-read'
and some related functions, which use zero-indexing for POSITION. */)
- (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
+(prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
Lisp_Object prompt, initial_contents, keymap, read, hist, default_value;
Lisp_Object inherit_input_method;
{
Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
is a string to insert in the minibuffer before reading.
\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
-arguments are used as in `read-from-minibuffer') */)
+arguments are used as in `read-from-minibuffer'.) */)
(prompt, initial_contents)
Lisp_Object prompt, initial_contents;
{
Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
is a string to insert in the minibuffer before reading.
\(INITIAL-CONTENTS can also be a cons of a string and an integer. Such
-arguments are used as in `read-from-minibuffer') */)
+arguments are used as in `read-from-minibuffer'.) */)
(prompt, initial_contents)
Lisp_Object prompt, initial_contents;
{
- return Feval (Fread_minibuffer (prompt, initial_contents));
+ return Feval (read_minibuf (Vread_expression_map, initial_contents,
+ prompt, Qnil, 1, Qread_expression_history,
+ make_number (0), Qnil, 0, 0));
}
/* Functions that use the minibuffer to read various things. */
Prompt with PROMPT.
Optional second arg DEF is value to return if user enters an empty line.
If optional third arg REQUIRE-MATCH is non-nil,
- only existing buffer names are allowed. */)
+ only existing buffer names are allowed.
+The argument PROMPT should be a string ending with a colon and a space. */)
(prompt, def, require_match)
Lisp_Object prompt, def, require_match;
{
Lisp_Object args[4];
+ unsigned char *s;
+ int len;
if (BUFFERP (def))
def = XBUFFER (def)->name;
{
if (!NILP (def))
{
- args[0] = build_string ("%s(default %s) ");
+ /* A default value was provided: we must change PROMPT,
+ editing the default value in before the colon. To achieve
+ this, we replace PROMPT with a substring that doesn't
+ contain the terminal space and colon (if present). They
+ are then added back using Fformat. */
+
+ if (STRINGP (prompt))
+ {
+ s = SDATA (prompt);
+ len = strlen (s);
+ if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ')
+ len = len - 2;
+ else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' '))
+ len--;
+
+ prompt = make_specified_string (s, -1, len,
+ STRING_MULTIBYTE (prompt));
+ }
+
+ args[0] = build_string ("%s (default %s): ");
args[1] = prompt;
args[2] = def;
prompt = Fformat (3, args);
}
- return Fcompleting_read (prompt, Vbuffer_alist, Qnil,
- require_match, Qnil, Qbuffer_name_history,
+ return Fcompleting_read (prompt, intern ("internal-complete-buffer"),
+ Qnil, require_match, Qnil, Qbuffer_name_history,
def, Qnil);
}
else
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 (or each element if it is not a cons cell)
-is tested to see if it begins with STRING.
+is tested to see if it begins with STRING. The possible matches may be
+strings or symbols. Symbols are converted to strings before testing,
+see `symbol-name'.
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.
For a unique match which is exact, t is returned.
-If ALIST is a hash-table, all the string keys are the possible matches.
+If ALIST is a hash-table, all the string and symbol keys are the
+possible matches.
If ALIST is an obarray, the names of all symbols in the obarray
are the possible matches.
int bestmatchsize = 0;
/* These are in bytes, too. */
int compare, matchsize;
- int type = HASH_TABLE_P (alist) ? 3
- : VECTORP (alist) ? 2
- : NILP (alist) || (CONSP (alist)
- && (!SYMBOLP (XCAR (alist))
- || NILP (XCAR (alist))));
+ int type = (HASH_TABLE_P (alist) ? 3
+ : VECTORP (alist) ? 2
+ : NILP (alist) || (CONSP (alist)
+ && (!SYMBOLP (XCAR (alist))
+ || NILP (XCAR (alist)))));
int index = 0, obsize = 0;
int matchcount = 0;
+ int bindcount = -1;
Lisp_Object bucket, zero, end, tem;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
return call3 (alist, string, predicate, Qnil);
bestmatch = bucket = Qnil;
+ zero = make_number (0);
/* If ALIST is not a list, set TAIL just for gc pro. */
tail = alist;
}
else if (type == 2)
{
- if (XFASTINT (bucket) != 0)
+ if (!EQ (bucket, zero))
{
elt = bucket;
- eltstring = Fsymbol_name (elt);
+ eltstring = elt;
if (XSYMBOL (bucket)->next)
XSETSYMBOL (bucket, XSYMBOL (bucket)->next);
else
/* Is this element a possible completion? */
+ if (SYMBOLP (eltstring))
+ eltstring = Fsymbol_name (eltstring);
+
if (STRINGP (eltstring)
&& SCHARS (string) <= SCHARS (eltstring)
- && (tem = Fcompare_strings (eltstring, make_number (0),
+ && (tem = Fcompare_strings (eltstring, zero,
make_number (SCHARS (string)),
- string, make_number (0), Qnil,
+ string, zero, Qnil,
completion_ignore_case ? Qt : Qnil),
EQ (Qt, tem)))
{
/* Yes. */
Lisp_Object regexps;
- Lisp_Object zero;
- XSETFASTINT (zero, 0);
/* Ignore this element if it fails to match all the regexps. */
{
- int count = SPECPDL_INDEX ();
- specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
for (regexps = Vcompletion_regexp_list; CONSP (regexps);
regexps = XCDR (regexps))
{
+ if (bindcount < 0) {
+ bindcount = SPECPDL_INDEX ();
+ specbind (Qcase_fold_search,
+ completion_ignore_case ? Qt : Qnil);
+ }
tem = Fstring_match (XCAR (regexps), eltstring, zero);
if (NILP (tem))
break;
}
- unbind_to (count, Qnil);
if (CONSP (regexps))
continue;
}
tem = Fcommandp (elt, Qnil);
else
{
+ if (bindcount >= 0) {
+ unbind_to (bindcount, Qnil);
+ bindcount = -1;
+ }
GCPRO4 (tail, string, eltstring, bestmatch);
tem = type == 3
? call2 (predicate, elt,
else
{
compare = min (bestmatchsize, SCHARS (eltstring));
- tem = Fcompare_strings (bestmatch, make_number (0),
+ tem = Fcompare_strings (bestmatch, zero,
make_number (compare),
- eltstring, make_number (0),
+ eltstring, zero,
make_number (compare),
completion_ignore_case ? Qt : Qnil);
if (EQ (tem, Qt))
((matchsize == SCHARS (eltstring))
==
(matchsize == SCHARS (bestmatch))
- && (tem = Fcompare_strings (eltstring, make_number (0),
+ && (tem = Fcompare_strings (eltstring, zero,
make_number (SCHARS (string)),
- string, make_number (0),
+ string, zero,
Qnil,
Qnil),
EQ (Qt, tem))
- && (tem = Fcompare_strings (bestmatch, make_number (0),
+ && (tem = Fcompare_strings (bestmatch, zero,
make_number (SCHARS (string)),
- string, make_number (0),
+ string, zero,
Qnil,
Qnil),
! EQ (Qt, tem))))
}
}
+ if (bindcount >= 0) {
+ unbind_to (bindcount, Qnil);
+ bindcount = -1;
+ }
+
if (NILP (bestmatch))
return Qnil; /* No completions found */
/* If we are ignoring case, and there is no exact match,
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 (or each element if it is not a cons cell)
-is tested to see if it begins with STRING.
+is tested to see if it begins with STRING. The possible matches may be
+strings or symbols. Symbols are converted to strings before testing,
+see `symbol-name'.
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.
+If ALIST is a hash-table, all the string and symbol keys are the
+possible matches.
If ALIST is an obarray, the names of all symbols in the obarray
are the possible matches.
&& (!SYMBOLP (XCAR (alist))
|| NILP (XCAR (alist))));
int index = 0, obsize = 0;
- Lisp_Object bucket, tem;
+ int bindcount = -1;
+ Lisp_Object bucket, tem, zero;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
CHECK_STRING (string);
if (type == 0)
return call3 (alist, string, predicate, Qt);
allmatches = bucket = Qnil;
+ zero = make_number (0);
/* If ALIST is not a list, set TAIL just for gc pro. */
tail = alist;
}
else if (type == 2)
{
- if (XFASTINT (bucket) != 0)
+ if (!EQ (bucket, zero))
{
elt = bucket;
- eltstring = Fsymbol_name (elt);
+ eltstring = elt;
if (XSYMBOL (bucket)->next)
XSETSYMBOL (bucket, XSYMBOL (bucket)->next);
else
/* Is this element a possible completion? */
+ if (SYMBOLP (eltstring))
+ eltstring = Fsymbol_name (eltstring);
+
if (STRINGP (eltstring)
&& SCHARS (string) <= SCHARS (eltstring)
/* If HIDE_SPACES, reject alternatives that start with space
&& SREF (string, 0) == ' ')
|| SREF (eltstring, 0) != ' '
|| NILP (hide_spaces))
- && (tem = Fcompare_strings (eltstring, make_number (0),
+ && (tem = Fcompare_strings (eltstring, zero,
make_number (SCHARS (string)),
- string, make_number (0),
+ string, zero,
make_number (SCHARS (string)),
completion_ignore_case ? Qt : Qnil),
EQ (Qt, tem)))
/* Ignore this element if it fails to match all the regexps. */
{
- int count = SPECPDL_INDEX ();
- specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
for (regexps = Vcompletion_regexp_list; CONSP (regexps);
regexps = XCDR (regexps))
{
+ if (bindcount < 0) {
+ bindcount = SPECPDL_INDEX ();
+ specbind (Qcase_fold_search,
+ completion_ignore_case ? Qt : Qnil);
+ }
tem = Fstring_match (XCAR (regexps), eltstring, zero);
if (NILP (tem))
break;
}
- unbind_to (count, Qnil);
if (CONSP (regexps))
continue;
}
tem = Fcommandp (elt, Qnil);
else
{
+ if (bindcount >= 0) {
+ unbind_to (bindcount, Qnil);
+ bindcount = -1;
+ }
GCPRO4 (tail, eltstring, allmatches, string);
tem = type == 3
? call2 (predicate, elt,
}
}
+ if (bindcount >= 0) {
+ unbind_to (bindcount, Qnil);
+ bindcount = -1;
+ }
+
return Fnreverse (allmatches);
}
\f
is the initial position (the position in the list used by the
minibuffer history commands). For consistency, you should also
specify that element of the history as the value of
- INITIAL-CONTENTS. (This is the only case in which you should use
+ INITIAL-INPUT. (This is the only case in which you should use
INITIAL-INPUT instead of DEF.) Positions are counted starting from
1 at the beginning of the list. The variable `history-length'
controls the maximum length of a history list.
XSETFASTINT (histpos, 0);
val = read_minibuf (NILP (require_match)
- ? Vminibuffer_local_completion_map
- : Vminibuffer_local_must_match_map,
+ ? (NILP (Vminibuffer_completing_file_name)
+ ? Vminibuffer_local_completion_map
+ : Vminibuffer_local_filename_completion_map)
+ : (NILP (Vminibuffer_completing_file_name)
+ ? Vminibuffer_local_must_match_map
+ : Vminibuffer_local_must_match_filename_map),
init, prompt, make_number (pos), 0,
histvar, histpos, def, 0,
!NILP (inherit_input_method));
|| NILP (alist))
{
tem = Fassoc_string (string, alist, completion_ignore_case ? Qt : Qnil);
- if NILP (tem)
+ if (NILP (tem))
return Qnil;
}
else if (VECTORP (alist))
return call3 (alist, string, predicate, Qlambda);
/* Reject this element if it fails to match all the regexps. */
- {
- int count = SPECPDL_INDEX ();
- specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
- for (regexps = Vcompletion_regexp_list; CONSP (regexps);
- regexps = XCDR (regexps))
- {
- if (NILP (Fstring_match (XCAR (regexps),
- SYMBOLP (tem) ? string : tem,
- Qnil)))
- return unbind_to (count, Qnil);
- }
- unbind_to (count, Qnil);
- }
+ if (CONSP (Vcompletion_regexp_list))
+ {
+ int count = SPECPDL_INDEX ();
+ specbind (Qcase_fold_search, completion_ignore_case ? Qt : Qnil);
+ for (regexps = Vcompletion_regexp_list; CONSP (regexps);
+ regexps = XCDR (regexps))
+ {
+ if (NILP (Fstring_match (XCAR (regexps),
+ SYMBOLP (tem) ? string : tem,
+ Qnil)))
+ return unbind_to (count, Qnil);
+ }
+ unbind_to (count, Qnil);
+ }
/* Finally, check the predicate. */
if (!NILP (predicate))
return Qt;
}
+DEFUN ("internal-complete-buffer", Finternal_complete_buffer, Sinternal_complete_buffer, 3, 3, 0,
+ doc: /* Perform completion on buffer names.
+If the argument FLAG is nil, invoke `try-completion', if it's t, invoke
+`all-completions', otherwise invoke `test-completion'.
+
+The arguments STRING and PREDICATE are as in `try-completion',
+`all-completions', and `test-completion'. */)
+ (string, predicate, flag)
+ Lisp_Object string, predicate, flag;
+{
+ if (NILP (flag))
+ return Ftry_completion (string, Vbuffer_alist, predicate);
+ else if (EQ (flag, Qt))
+ return Fall_completions (string, Vbuffer_alist, predicate, Qt);
+ else /* assume `lambda' */
+ return Ftest_completion (string, Vbuffer_alist, predicate);
+}
+
/* returns:
* 0 no possible completion
* 1 was already an exact and unique completion
Lisp_Object last;
struct gcpro gcpro1, gcpro2;
- completion = Ftry_completion (minibuffer_completion_contents (),
+ completion = Ftry_completion (Fminibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
last = last_exact_completion;
return 1;
}
- string = minibuffer_completion_contents ();
+ string = Fminibuffer_completion_contents ();
/* COMPLETEDP should be true if some completion was done, which
doesn't include simply changing the case of the entered string.
last_exact_completion = completion;
if (!NILP (last))
{
- tem = minibuffer_completion_contents ();
+ tem = Fminibuffer_completion_contents ();
if (!NILP (Fequal (tem, last)))
Fminibuffer_completion_help ();
}
return make_number (1);
}
+EXFUN (Fexit_minibuffer, 0) NO_RETURN;
+
DEFUN ("minibuffer-complete-and-exit", Fminibuffer_complete_and_exit,
Sminibuffer_complete_and_exit, 0, 0, "",
doc: /* If the minibuffer contents is a valid completion then exit.
()
{
register int i;
- Lisp_Object val;
+ Lisp_Object val, tem;
/* Allow user to specify null string */
if (XINT (Fminibuffer_prompt_end ()) == ZV)
goto exit;
- if (!NILP (Ftest_completion (Fminibuffer_contents (),
+ val = Fminibuffer_contents ();
+ tem = Ftest_completion (val,
+ Vminibuffer_completion_table,
+ Vminibuffer_completion_predicate);
+ if (!NILP (tem))
+ {
+ if (completion_ignore_case)
+ { /* Fixup case of the field, if necessary. */
+ Lisp_Object compl
+ = Ftry_completion (val,
Vminibuffer_completion_table,
- Vminibuffer_completion_predicate)))
- goto exit;
+ Vminibuffer_completion_predicate);
+ if (STRINGP (compl)
+ /* If it weren't for this piece of paranoia, I'd replace
+ the whole thing with a call to do_completion. */
+ && EQ (Flength (val), Flength (compl)))
+ {
+ del_range (XINT (Fminibuffer_prompt_end ()), ZV);
+ Finsert (1, &compl);
+ }
+ }
+ goto exit;
+ }
/* Call do_completion, but ignore errors. */
SET_PT (ZV);
return Qnil;
}
exit:
- return Fthrow (Qexit, Qnil);
+ return Fexit_minibuffer ();
/* NOTREACHED */
}
{
Lisp_Object completion, tem, tem1;
register int i, i_byte;
- register const unsigned char *completion_string;
struct gcpro gcpro1, gcpro2;
int prompt_end_charpos = XINT (Fminibuffer_prompt_end ());
/* We keep calling Fbuffer_string rather than arrange for GC to
hold onto a pointer to one of the strings thus made. */
- completion = Ftry_completion (minibuffer_completion_contents (),
+ completion = Ftry_completion (Fminibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
if (NILP (completion))
int buffer_nchars, completion_nchars;
CHECK_STRING (completion);
- tem = minibuffer_completion_contents ();
+ tem = Fminibuffer_completion_contents ();
GCPRO2 (completion, tem);
/* If reading a file name,
expand any $ENVVAR refs in the buffer and in TEM. */
if (i == SCHARS (completion))
{
GCPRO1 (completion);
- tem = Ftry_completion (concat2 (minibuffer_completion_contents (),
+ tem = Ftry_completion (concat2 (Fminibuffer_completion_contents (),
build_string (" ")),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
{
GCPRO1 (completion);
tem =
- Ftry_completion (concat2 (minibuffer_completion_contents (),
+ Ftry_completion (concat2 (Fminibuffer_completion_contents (),
build_string ("-")),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
{
int len, c;
int bytes = SBYTES (completion);
- completion_string = SDATA (completion);
+ register const unsigned char *completion_string = SDATA (completion);
for (; i_byte < SBYTES (completion); i_byte += len, i++)
{
c = STRING_CHAR_AND_LENGTH (completion_string + i_byte,
}
\f
DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_list,
- 1, 1, 0,
+ 1, 2, 0,
doc: /* Display the list of completions, COMPLETIONS, using `standard-output'.
Each element may be just a symbol or string
or may be a list of two strings to be printed as if concatenated.
The actual completion alternatives, as inserted, are given `mouse-face'
properties of `highlight'.
At the end, this runs the normal hook `completion-setup-hook'.
-It can find the completion buffer in `standard-output'. */)
- (completions)
+It can find the completion buffer in `standard-output'.
+The optional second arg COMMON-SUBSTRING is a string.
+It is used to put faces, `completions-first-difference' and
+`completions-common-part' on the completion buffer. The
+`completions-common-part' face is put on the common substring
+specified by COMMON-SUBSTRING. If COMMON-SUBSTRING is nil
+and the current buffer is not the minibuffer, the faces are not put.
+Internally, COMMON-SUBSTRING is bound to `completion-common-substring'
+during running `completion-setup-hook'. */)
+ (completions, common_substring)
Lisp_Object completions;
+ Lisp_Object common_substring;
{
Lisp_Object tail, elt;
register int i;
int column = 0;
- struct gcpro gcpro1, gcpro2;
+ struct gcpro gcpro1, gcpro2, gcpro3;
struct buffer *old = current_buffer;
int first = 1;
except for ELT. ELT can be pointing to a string
when terpri or Findent_to calls a change hook. */
elt = Qnil;
- GCPRO2 (completions, elt);
+ GCPRO3 (completions, elt, common_substring);
if (BUFFERP (Vstandard_output))
set_buffer_internal (XBUFFER (Vstandard_output));
else
{
write_string ("Possible completions are:", -1);
- for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++)
+ for (tail = completions, i = 0; CONSP (tail); tail = XCDR (tail), i++)
{
Lisp_Object tem, string;
int length;
startpos = Qnil;
- elt = Fcar (tail);
+ elt = XCAR (tail);
if (SYMBOLP (elt))
elt = SYMBOL_NAME (elt);
/* Compute the length of this element. */
}
}
- UNGCPRO;
-
if (BUFFERP (Vstandard_output))
set_buffer_internal (old);
if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, intern ("completion-setup-hook"));
+ {
+ int count1 = SPECPDL_INDEX ();
+
+ specbind (intern ("completion-common-substring"), common_substring);
+ call1 (Vrun_hooks, intern ("completion-setup-hook"));
+
+ unbind_to (count1, Qnil);
+ }
+
+ UNGCPRO;
return Qnil;
}
+
+static Lisp_Object
+display_completion_list_1 (list)
+ Lisp_Object list;
+{
+ return Fdisplay_completion_list (list, Qnil);
+}
+
DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_completion_help,
0, 0, "",
doc: /* Display a list of possible completions of the current minibuffer contents. */)
Lisp_Object completions;
message ("Making completion list...");
- completions = Fall_completions (minibuffer_completion_contents (),
+ completions = Fall_completions (Fminibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate,
Qt);
temp_echo_area_glyphs (build_string (" [No completions]"));
}
else
- internal_with_output_to_temp_buffer ("*Completions*",
- Fdisplay_completion_list,
- Fsort (completions, Qstring_lessp));
+ {
+ /* Sort and remove duplicates. */
+ Lisp_Object tmp = completions = Fsort (completions, Qstring_lessp);
+ while (CONSP (tmp))
+ {
+ if (CONSP (XCDR (tmp))
+ && !NILP (Fequal (XCAR (tmp), XCAR (XCDR (tmp)))))
+ XSETCDR (tmp, XCDR (XCDR (tmp)));
+ else
+ tmp = XCDR (tmp);
+ }
+ internal_with_output_to_temp_buffer ("*Completions*",
+ display_completion_list_1,
+ completions);
+ }
return Qnil;
}
\f
else
bitch_at_user ();
- return Fthrow (Qexit, Qnil);
+ return Fexit_minibuffer ();
}
DEFUN ("exit-minibuffer", Fexit_minibuffer, Sexit_minibuffer, 0, 0, "",
doc: /* Terminate this minibuffer argument. */)
()
{
- return Fthrow (Qexit, Qnil);
+ /* If the command that uses this has made modifications in the minibuffer,
+ we don't want them to cause deactivation of the mark in the original
+ buffer.
+ A better solution would be to make deactivate-mark buffer-local
+ (or to turn it into a list of buffers, ...), but in the mean time,
+ this should do the trick in most cases. */
+ Vdeactivate_mark = Qnil;
+ Fthrow (Qexit, Qnil);
}
DEFUN ("minibuffer-depth", Fminibuffer_depth, Sminibuffer_depth, 0, 0, 0,
that has no possible completions, and other quick, unobtrusive
messages. */
+extern Lisp_Object Vminibuffer_message_timeout;
+
void
temp_echo_area_glyphs (string)
Lisp_Object string;
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);
+
+ if (NUMBERP (Vminibuffer_message_timeout))
+ sit_for (Vminibuffer_message_timeout, 0, 2);
+ else
+ sit_for (Qt, 0, 2);
+
del_range_both (osize, osize_byte, ZV, ZV_BYTE, 1);
SET_PT_BOTH (opoint, opoint_byte);
if (!NILP (Vquit_flag))
DEFUN ("minibuffer-message", Fminibuffer_message, Sminibuffer_message,
1, 1, 0,
doc: /* Temporarily display STRING at the end of the minibuffer.
-The text is displayed for two seconds,
+The text is displayed for a period controlled by `minibuffer-message-timeout',
or until the next input event arrives, whichever comes first. */)
(string)
Lisp_Object string;
Qcase_fold_search = intern ("case-fold-search");
staticpro (&Qcase_fold_search);
+ Qread_expression_history = intern ("read-expression-history");
+ staticpro (&Qread_expression_history);
+
DEFVAR_LISP ("read-buffer-function", &Vread_buffer_function,
doc: /* If this is non-nil, `read-buffer' does its work by calling this function. */);
Vread_buffer_function = Qnil;
DEFVAR_LISP ("history-length", &Vhistory_length,
doc: /* *Maximum length for history lists before truncation takes place.
A number means that length; t means infinite. Truncation takes place
-just after a new element is inserted. Setting the history-length
+just after a new element is inserted. Setting the `history-length'
property of a history variable overrides this default. */);
XSETFASTINT (Vhistory_length, 30);
+ DEFVAR_BOOL ("history-delete-duplicates", &history_delete_duplicates,
+ doc: /* *Non-nil means to delete duplicates in history.
+If set to t when adding a new history element, all previous identical
+elements are deleted from the history list. */);
+ history_delete_duplicates = 0;
+
+ DEFVAR_LISP ("history-add-new-input", &Vhistory_add_new_input,
+ doc: /* *Non-nil means to add new elements in history.
+If set to nil, minibuffer reading functions don't add new elements to the
+history list, so it is possible to do this afterwards by calling
+`add-to-history' explicitly. */);
+ Vhistory_add_new_input = Qt;
+
DEFVAR_LISP ("completion-auto-help", &Vcompletion_auto_help,
- doc: /* *Non-nil means automatically provide help for invalid completion input. */);
+ doc: /* *Non-nil means automatically provide help for invalid completion input.
+Under Partial Completion mode, a non-nil, non-t value has a special meaning;
+see the doc string of `partial-completion-mode' for more details. */);
Vcompletion_auto_help = Qt;
DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case,
- doc: /* Non-nil means don't consider case significant in completion. */);
+ doc: /* Non-nil means don't consider case significant in completion.
+
+For file-name completion, the variable `read-file-name-completion-ignore-case'
+controls the behavior, rather than this variable. */);
completion_ignore_case = 0;
DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers,
Vminibuffer_prompt_properties
= Fcons (intern ("read-only"), Fcons (Qt, Qnil));
+ DEFVAR_LISP ("read-expression-map", &Vread_expression_map,
+ doc: /* Minibuffer keymap used for reading Lisp expressions. */);
+ Vread_expression_map = Qnil;
+
defsubr (&Sset_minibuffer_window);
defsubr (&Sread_from_minibuffer);
defsubr (&Seval_minibuffer);
defsubr (&Sread_string);
defsubr (&Sread_command);
defsubr (&Sread_variable);
+ defsubr (&Sinternal_complete_buffer);
defsubr (&Sread_buffer);
defsubr (&Sread_no_blanks_input);
defsubr (&Sminibuffer_depth);
defsubr (&Sminibuffer_prompt_end);
defsubr (&Sminibuffer_contents);
defsubr (&Sminibuffer_contents_no_properties);
+ defsubr (&Sminibuffer_completion_contents);
defsubr (&Sdelete_minibuffer_contents);
defsubr (&Stry_completion);
initial_define_key (Vminibuffer_local_completion_map, '?',
"minibuffer-completion-help");
+ Fdefine_key (Vminibuffer_local_filename_completion_map,
+ build_string (" "), Qnil);
+
initial_define_key (Vminibuffer_local_must_match_map, Ctl ('m'),
"minibuffer-complete-and-exit");
initial_define_key (Vminibuffer_local_must_match_map, Ctl ('j'),
"minibuffer-complete-and-exit");
+
+ Fdefine_key (Vminibuffer_local_must_match_filename_map,
+ build_string (" "), Qnil);
}
/* arch-tag: 8f69b601-fba3-484c-a6dd-ceaee54a7a73