Lisp_Object last_minibuf_string;
-/* Nonzero means let functions called when within a minibuffer
+/* Nonzero means let functions called when within a minibuffer
invoke recursive minibuffers (to read arguments, or whatever) */
int enable_recursive_minibuffers;
Lisp_Object Qminibuffer_exit_hook, Vminibuffer_exit_hook;
/* Function to call to read a buffer name. */
-Lisp_Object Vread_buffer_function;
+Lisp_Object Vread_buffer_function;
/* Nonzero means completion ignores case. */
static Lisp_Object last_exact_completion;
-/* 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;
Lisp_Object Quser_variable_p;
{
struct frame *sf = XFRAME (selected_frame);
Lisp_Object buffer;
-
+
/* I don't think that any frames may validly have a null minibuffer
window anymore. */
if (NILP (sf->minibuffer_window))
struct gcpro gcpro1, gcpro2;
Lisp_Object expr_and_pos;
int pos;
-
+
GCPRO2 (val, defalt);
-
+
if (STRINGP (val) && XSTRING (val)->size == 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)
error ("Trailing garbage following expression");
}
}
-
+
val = Fcar (expr_and_pos);
RETURN_UNGCPRO (val);
}
if (s)
{
len = strlen (line);
-
+
if (len > 0 && line[len - 1] == '\n')
line[--len] = '\0';
-
+
val = build_string (line);
xfree (line);
}
xfree (line);
error ("Error reading from stdin");
}
-
+
/* If Lisp form desired instead of string, parse it. */
if (expflag)
val = string_to_object (val, defalt);
-
+
return val;
}
-
-
+\f
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);
-
+
if (XINT (end) == ZV && NILP (Fget_char_property (beg, Qfield, Qnil)))
return beg;
else
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 ());
+ return make_buffer_string (prompt_end, PT, 1);
+}
+\f
/* Read from the minibuffer using keymap MAP, initial contents INITIAL
(a string), putting point minus BACKUP_N bytes from the end of INITIAL,
prompting with PROMPT (a string), using history list HISTVAR
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;
GCPRO5 (map, initial, val, ambient_dir, input_method);
if (!STRINGP (prompt))
- prompt = build_string ("");
+ prompt = empty_string;
if (!enable_recursive_minibuffers
&& minibuf_level > 0)
if (inherit_input_method)
{
- /* `current-input-method' is buffer local. So, remeber it in
+ /* `current-input-method' is buffer local. So, remember it in
INPUT_METHOD before changing the current buffer. */
input_method = Fsymbol_value (Qcurrent_input_method);
enable_multibyte = current_buffer->enable_multibyte_characters;
Fredirect_frame_focus (selected_frame, mini_frame);
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);
XSETFASTINT (XWINDOW (minibuf_window)->hscroll, 0);
/* Erase the buffer. */
{
- int count1 = BINDING_STACK_SIZE ();
+ int count1 = SPECPDL_INDEX ();
specbind (Qinhibit_read_only, Qt);
specbind (Qinhibit_modification_hooks, Qt);
Ferase_buffer ();
Fadd_text_properties (make_number (BEG), make_number (PT),
Vminibuffer_prompt_properties, Qnil);
}
-
- minibuf_prompt_width = current_column ();
-
+
+ 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;
/* Run our hook, but not if it is empty.
(run-hooks would do nothing if it is empty,
- but it's important to save time here in the usual case). */
+ but it's important to save time here in the usual case.) */
if (!NILP (Vminibuffer_setup_hook) && !EQ (Vminibuffer_setup_hook, Qunbound)
&& !NILP (Vrun_hooks))
call1 (Vrun_hooks, Qminibuffer_setup_hook);
}
else
{
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
reset_buffer (XBUFFER (buf));
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
/* 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);
is STRING, but point is placed at position POSITION in the minibuffer.
Third arg KEYMAP is a keymap to use whilst reading;
if omitted or nil, the default is `minibuffer-local-map'.
-If fourth arg READ is non-nil, then interpret the result as a lisp object
+If fourth arg READ is non-nil, then interpret the result as a Lisp object
and return that object:
in other words, do `(car (read-from-string INPUT-STRING))'
Fifth arg HIST, if non-nil, specifies a history list
DEFUN ("read-command", Fread_command, Sread_command, 1, 2, 0,
doc: /* Read the name of a command and return as a symbol.
-Prompts with PROMPT. By default, return DEFAULT-VALUE. */)
+Prompt with PROMPT. By default, return DEFAULT-VALUE. */)
(prompt, default_value)
Lisp_Object prompt, default_value;
{
if (NILP (default_value))
default_string = Qnil;
else if (SYMBOLP (default_value))
- XSETSTRING (default_string, XSYMBOL (default_value)->name);
+ default_string = SYMBOL_NAME (default_value);
else
default_string = default_value;
-
+
name = Fcompleting_read (prompt, Vobarray, Qcommandp, Qt,
Qnil, Qnil, default_string, Qnil);
if (NILP (name))
#ifdef NOTDEF
DEFUN ("read-function", Fread_function, Sread_function, 1, 1, 0,
doc: /* One arg PROMPT, a string. Read the name of a function and return as a symbol.
-Prompts with PROMPT. */)
+Prompt with PROMPT. */)
(prompt)
Lisp_Object prompt;
{
DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0,
doc: /* Read the name of a user variable and return it as a symbol.
-Prompts with PROMPT. By default, return DEFAULT-VALUE.
+Prompt with PROMPT. By default, return DEFAULT-VALUE.
A user variable is one whose documentation starts with a `*' character. */)
(prompt, default_value)
Lisp_Object prompt, default_value;
if (NILP (default_value))
default_string = Qnil;
else if (SYMBOLP (default_value))
- XSETSTRING (default_string, XSYMBOL (default_value)->name);
+ default_string = SYMBOL_NAME (default_value);
else
default_string = default_value;
-
+
name = Fcompleting_read (prompt, Vobarray,
Quser_variable_p, Qt,
Qnil, Qnil, default_string, Qnil);
}
DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0,
- doc: /* One arg PROMPT, a string. Read the name of a buffer and return as a string.
-Prompts with PROMPT.
+ doc: /* Read the name of a buffer and return as a string.
+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. */)
+If optional third arg REQUIRE-MATCH is non-nil,
+ only existing buffer names are allowed. */)
(prompt, def, require_match)
Lisp_Object prompt, def, require_match;
{
Lisp_Object args[4];
-
+
if (BUFFERP (def))
def = XBUFFER (def)->name;
If there is no match at all, nil is returned.
For a unique match which is exact, t is returned.
-ALIST can be an obarray instead of an alist.
-Then the print names of all symbols in the obarray are the possible matches.
+If ALIST is a hash-table, all the string keys are the possible matches.
+If ALIST is an obarray, the names of all symbols in the obarray
+are the possible matches.
ALIST can also be a function to do the completion itself.
It receives three arguments: the values STRING, PREDICATE and nil.
it is used to test each possible match.
The match is a candidate only if PREDICATE returns non-nil.
The argument given to PREDICATE is the alist element
-or the symbol from the obarray.
+or the symbol from the obarray. If ALIST is a hash-table,
+predicate is called with two arguments: the key and the value.
Additionally to this predicate, `completion-regexp-list'
is used to further constrain the set of candidates. */)
(string, alist, predicate)
int bestmatchsize = 0;
/* These are in bytes, too. */
int compare, matchsize;
- int list = CONSP (alist) || NILP (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;
Lisp_Object bucket, zero, end, tem;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
CHECK_STRING (string);
- if (!list && !VECTORP (alist))
+ if (type == 0)
return call3 (alist, string, predicate, Qnil);
bestmatch = bucket = Qnil;
/* If ALIST is not a list, set TAIL just for gc pro. */
tail = alist;
- if (! list)
+ if (type == 2)
{
- index = 0;
obsize = XVECTOR (alist)->size;
bucket = XVECTOR (alist)->contents[index];
}
while (1)
{
- /* Get the next element of the alist or obarray. */
+ /* Get the next element of the alist, obarray, or hash-table. */
/* Exit the loop if the elements are all used up. */
/* elt gets the alist element or symbol.
eltstring gets the name to check as a completion. */
- if (list)
+ if (type == 1)
{
- if (NILP (tail))
+ if (!CONSP (tail))
break;
- elt = Fcar (tail);
- eltstring = Fcar (elt);
- tail = Fcdr (tail);
+ elt = XCAR (tail);
+ eltstring = CONSP (elt) ? XCAR (elt) : elt;
+ tail = XCDR (tail);
}
- else
+ else if (type == 2)
{
if (XFASTINT (bucket) != 0)
{
continue;
}
}
+ else /* if (type == 3) */
+ {
+ while (index < HASH_TABLE_SIZE (XHASH_TABLE (alist))
+ && NILP (HASH_HASH (XHASH_TABLE (alist), index)))
+ index++;
+ if (index >= HASH_TABLE_SIZE (XHASH_TABLE (alist)))
+ break;
+ else
+ elt = eltstring = HASH_KEY (XHASH_TABLE (alist), index++);
+ }
/* Is this element a possible completion? */
if (!NILP (predicate))
{
if (EQ (predicate, Qcommandp))
- tem = Fcommandp (elt);
+ tem = Fcommandp (elt, Qnil);
else
{
GCPRO4 (tail, string, eltstring, bestmatch);
- tem = call1 (predicate, elt);
+ tem = type == 3
+ ? call2 (predicate, elt,
+ HASH_VALUE (XHASH_TABLE (alist), index - 1))
+ : call1 (predicate, elt);
UNGCPRO;
}
if (NILP (tem)) continue;
/* Update computation of how much all possible completions match */
- matchcount++;
if (NILP (bestmatch))
{
+ matchcount = 1;
bestmatch = eltstring;
bestmatchsize = XSTRING (eltstring)->size;
}
matchsize = XINT (tem) - 1;
if (matchsize < 0)
+ /* When can this happen ? -stef */
matchsize = compare;
if (completion_ignore_case)
{
! EQ (Qt, tem))))
bestmatch = eltstring;
}
+ if (bestmatchsize != XSTRING (eltstring)->size
+ || bestmatchsize != matchsize)
+ /* Don't count the same string multiple times. */
+ matchcount++;
bestmatchsize = matchsize;
+ if (matchsize <= XSTRING (string)->size
+ && matchcount > 1)
+ /* No need to look any further. */
+ break;
}
}
}
Each car of each element of ALIST is tested to see if it begins with STRING.
The value is a list of all the strings from ALIST that match.
-ALIST can be an obarray instead of an alist.
-Then the print names of all symbols in the obarray are the possible matches.
+If ALIST is a hash-table, all the string keys are the possible matches.
+If ALIST is an obarray, the names of all symbols in the obarray
+are the possible matches.
ALIST can also be a function to do the completion itself.
It receives three arguments: the values STRING, PREDICATE and t.
it is used to test each possible match.
The match is a candidate only if PREDICATE returns non-nil.
The argument given to PREDICATE is the alist element
-or the symbol from the obarray.
+or the symbol from the obarray. If ALIST is a hash-table,
+predicate is called with two arguments: the key and the value.
Additionally to this predicate, `completion-regexp-list'
is used to further constrain the set of candidates.
{
Lisp_Object tail, elt, eltstring;
Lisp_Object allmatches;
- int list = CONSP (alist) || NILP (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;
Lisp_Object bucket, tem;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
CHECK_STRING (string);
- if (!list && !VECTORP (alist))
- {
- return call3 (alist, string, predicate, Qt);
- }
+ if (type == 0)
+ return call3 (alist, string, predicate, Qt);
allmatches = bucket = Qnil;
/* If ALIST is not a list, set TAIL just for gc pro. */
tail = alist;
- if (! list)
+ if (type == 2)
{
- index = 0;
obsize = XVECTOR (alist)->size;
bucket = XVECTOR (alist)->contents[index];
}
while (1)
{
- /* Get the next element of the alist or obarray. */
+ /* Get the next element of the alist, obarray, or hash-table. */
/* Exit the loop if the elements are all used up. */
/* elt gets the alist element or symbol.
eltstring gets the name to check as a completion. */
- if (list)
+ if (type == 1)
{
- if (NILP (tail))
+ if (!CONSP (tail))
break;
- elt = Fcar (tail);
- eltstring = Fcar (elt);
- tail = Fcdr (tail);
+ elt = XCAR (tail);
+ eltstring = CONSP (elt) ? XCAR (elt) : elt;
+ tail = XCDR (tail);
}
- else
+ else if (type == 2)
{
if (XFASTINT (bucket) != 0)
{
continue;
}
}
+ else /* if (type == 3) */
+ {
+ while (index < HASH_TABLE_SIZE (XHASH_TABLE (alist))
+ && NILP (HASH_HASH (XHASH_TABLE (alist), index)))
+ index++;
+ if (index >= HASH_TABLE_SIZE (XHASH_TABLE (alist)))
+ break;
+ else
+ elt = eltstring = HASH_KEY (XHASH_TABLE (alist), index++);
+ }
/* Is this element a possible completion? */
if (!NILP (predicate))
{
if (EQ (predicate, Qcommandp))
- tem = Fcommandp (elt);
+ tem = Fcommandp (elt, Qnil);
else
{
GCPRO4 (tail, eltstring, allmatches, string);
- tem = call1 (predicate, elt);
+ tem = type == 3
+ ? call2 (predicate, elt,
+ HASH_VALUE (XHASH_TABLE (alist), index - 1))
+ : call1 (predicate, elt);
UNGCPRO;
}
if (NILP (tem)) continue;
If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
the input is (or completes to) an element of TABLE or is null.
- If it is also not t, Return does not exit if it does non-null completion.
+ If it is also not t, typing RET does not exit if it does non-null completion.
If the input is null, `completing-read' returns an empty string,
regardless of the value of REQUIRE-MATCH.
If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.
If it is (STRING . POSITION), the initial input
is STRING, but point is placed POSITION characters into the string.
- This feature is deprecated--it is best to pass nil for INITIAL.
+ This feature is deprecated--it is best to pass nil for INITIAL-INPUT
+ and supply the default value DEF instead. The user can yank the
+ default value into the minibuffer easily using \\[next-history-element].
+
HIST, if non-nil, specifies a history list
and optionally the initial position in the list.
It can be a symbol, which is the history list variable to use,
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;
specbind (Qminibuffer_completion_table, table);
specbind (Qminibuffer_completion_predicate, predicate);
specbind (Qminibuffer_completion_confirm,
- EQ (require_match, Qt) ? Qnil : Qt);
+ EQ (require_match, Qt) ? Qnil : require_match);
last_exact_completion = Qnil;
position = Qnil;
}
\f
Lisp_Object Fminibuffer_completion_help ();
-Lisp_Object assoc_for_completion ();
+Lisp_Object Fassoc_string ();
/* Test whether TXT is an exact completion. */
-Lisp_Object
-test_completion (txt)
- Lisp_Object txt;
+DEFUN ("test-completion", Ftest_completion, Stest_completion, 2, 3, 0,
+ doc: /* Return non-nil if STRING is a valid completion.
+Takes the same arguments as `all-completions' and `try-completion'.
+If ALIST is a function, it is called with three arguments:
+the values STRING, PREDICATE and `lambda'. */)
+ (string, alist, predicate)
+ Lisp_Object string, alist, predicate;
{
- Lisp_Object tem;
+ Lisp_Object regexps, tem = Qnil;
+ int i = 0;
- if (CONSP (Vminibuffer_completion_table)
- || NILP (Vminibuffer_completion_table))
- return assoc_for_completion (txt, Vminibuffer_completion_table);
- else if (VECTORP (Vminibuffer_completion_table))
+ CHECK_STRING (string);
+
+ if ((CONSP (alist) && (!SYMBOLP (XCAR (alist)) || NILP (XCAR (alist))))
+ || NILP (alist))
+ {
+ tem = Fassoc_string (string, alist, completion_ignore_case ? Qt : Qnil);
+ if NILP (tem)
+ return Qnil;
+ }
+ else if (VECTORP (alist))
{
- /* Bypass intern-soft as that loses for nil */
- tem = oblookup (Vminibuffer_completion_table,
- XSTRING (txt)->data,
- XSTRING (txt)->size,
- STRING_BYTES (XSTRING (txt)));
+ /* Bypass intern-soft as that loses for nil. */
+ tem = oblookup (alist,
+ XSTRING (string)->data,
+ XSTRING (string)->size,
+ STRING_BYTES (XSTRING (string)));
if (!SYMBOLP (tem))
{
- if (STRING_MULTIBYTE (txt))
- txt = Fstring_make_unibyte (txt);
+ if (STRING_MULTIBYTE (string))
+ string = Fstring_make_unibyte (string);
else
- txt = Fstring_make_multibyte (txt);
+ string = Fstring_make_multibyte (string);
tem = oblookup (Vminibuffer_completion_table,
- XSTRING (txt)->data,
- XSTRING (txt)->size,
- STRING_BYTES (XSTRING (txt)));
+ XSTRING (string)->data,
+ XSTRING (string)->size,
+ STRING_BYTES (XSTRING (string)));
if (!SYMBOLP (tem))
return Qnil;
}
- if (!NILP (Vminibuffer_completion_predicate))
- return call1 (Vminibuffer_completion_predicate, tem);
+ }
+ else if (HASH_TABLE_P (alist))
+ {
+ i = hash_lookup (XHASH_TABLE (alist), string, NULL);
+ if (i >= 0)
+ tem = HASH_KEY (XHASH_TABLE (alist), i);
else
- return Qt;
+ return Qnil;
+ }
+ else
+ return call3 (alist, string, predicate, Qlambda);
+
+ /* Reject this element if it fails to match all the regexps. */
+ for (regexps = Vcompletion_regexp_list; CONSP (regexps);
+ regexps = XCDR (regexps))
+ {
+ if (NILP (Fstring_match (XCAR (regexps),
+ SYMBOLP (tem) ? string : tem,
+ Qnil)))
+ return Qnil;
}
+
+ /* Finally, check the predicate. */
+ if (!NILP (predicate))
+ return HASH_TABLE_P (alist)
+ ? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (alist), i))
+ : call1 (predicate, tem);
else
- return call3 (Vminibuffer_completion_table, txt,
- Vminibuffer_completion_predicate, Qlambda);
+ return Qt;
}
/* returns:
Lisp_Object last;
struct gcpro gcpro1, gcpro2;
- completion = Ftry_completion (Fminibuffer_contents (),
+ completion = Ftry_completion (minibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
last = last_exact_completion;
return 1;
}
- string = Fminibuffer_contents ();
+ string = minibuffer_completion_contents ();
/* COMPLETEDP should be true if some completion was done, which
doesn't include simply changing the case of the entered string.
if (!EQ (tem, Qt))
/* Rewrite the user's input. */
{
- Fdelete_minibuffer_contents (); /* Some completion happened */
+ int prompt_end = XINT (Fminibuffer_prompt_end ());
+ /* Some completion happened */
+
+ if (! NILP (Vminibuffer_completing_file_name)
+ && XSTRING (completion)->data[STRING_BYTES (XSTRING (completion)) - 1] == '/'
+ && PT < ZV
+ && FETCH_CHAR (PT_BYTE) == '/')
+ {
+ del_range (prompt_end, PT + 1);
+ }
+ else
+ del_range (prompt_end, PT);
+
Finsert (1, &completion);
if (! completedp)
}
/* It did find a match. Do we match some possibility exactly now? */
- tem = test_completion (Fminibuffer_contents ());
+ tem = Ftest_completion (Fminibuffer_contents (),
+ Vminibuffer_completion_table,
+ Vminibuffer_completion_predicate);
if (NILP (tem))
{
/* not an exact match */
last_exact_completion = completion;
if (!NILP (last))
{
- tem = Fminibuffer_contents ();
+ tem = minibuffer_completion_contents ();
if (!NILP (Fequal (tem, last)))
Fminibuffer_completion_help ();
}
/* Like assoc but assumes KEY is a string, and ignores case if appropriate. */
-Lisp_Object
-assoc_for_completion (key, list)
+DEFUN ("assoc-string", Fassoc_string, Sassoc_string, 2, 3, 0,
+ doc: /* Like `assoc' but specifically for strings.
+Unibyte strings are converted to multibyte for comparison.
+And case is ignored if CASE-FOLD is non-nil.
+As opposed to `assoc', it will also match an entry consisting of a single
+string rather than a cons cell whose car is a string. */)
+ (key, list, case_fold)
register Lisp_Object key;
- Lisp_Object list;
+ Lisp_Object list, case_fold;
{
register Lisp_Object tail;
{
register Lisp_Object elt, tem, thiscar;
elt = Fcar (tail);
- if (!CONSP (elt)) continue;
- thiscar = Fcar (elt);
+ thiscar = CONSP (elt) ? XCAR (elt) : elt;
if (!STRINGP (thiscar))
continue;
tem = Fcompare_strings (thiscar, make_number (0), Qnil,
key, make_number (0), Qnil,
- completion_ignore_case ? Qt : Qnil);
+ case_fold);
if (EQ (tem, Qt))
return elt;
QUIT;
if (XINT (Fminibuffer_prompt_end ()) == ZV)
goto exit;
- if (!NILP (test_completion (Fminibuffer_contents ())))
+ if (!NILP (Ftest_completion (Fminibuffer_contents (),
+ Vminibuffer_completion_table,
+ Vminibuffer_completion_predicate)))
goto exit;
/* Call do_completion, but ignore errors. */
+ SET_PT (ZV);
val = internal_condition_case (complete_and_exit_1, Qerror,
complete_and_exit_2);
register int i, i_byte;
register unsigned char *completion_string;
struct gcpro gcpro1, gcpro2;
- int prompt_end_charpos;
+ 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 (Fminibuffer_contents (),
+ completion = Ftry_completion (minibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
if (NILP (completion))
int buffer_nchars, completion_nchars;
CHECK_STRING (completion);
- tem = Fminibuffer_contents ();
+ tem = minibuffer_completion_contents ();
GCPRO2 (completion, tem);
/* If reading a file name,
expand any $ENVVAR refs in the buffer and in TEM. */
if (! EQ (substituted, tem))
{
tem = substituted;
- Fdelete_minibuffer_contents ();
- insert_from_string (tem, 0, 0, XSTRING (tem)->size,
- STRING_BYTES (XSTRING (tem)), 0);
+ del_range (prompt_end_charpos, PT);
+ Finsert (1, &tem);
}
}
- buffer_nchars = XSTRING (tem)->size; /* ie ZV - BEGV */
+ buffer_nchars = XSTRING (tem)->size; /* # chars in what we completed. */
completion_nchars = XSTRING (completion)->size;
i = buffer_nchars - completion_nchars;
if (i > 0
{
int start_pos;
- /* Set buffer to longest match of buffer tail and completion head. */
+ /* Make buffer (before point) contain the longest match
+ of TEM's tail and COMPLETION's head. */
if (i <= 0) i = 1;
start_pos= i;
buffer_nchars -= i;
buffer_nchars--;
}
del_range (1, i + 1);
- SET_PT_BOTH (ZV, ZV_BYTE);
}
UNGCPRO;
}
#endif /* Rewritten code */
-
- prompt_end_charpos = XINT (Fminibuffer_prompt_end ());
{
int prompt_end_bytepos;
prompt_end_bytepos = CHAR_TO_BYTE (prompt_end_charpos);
- i = ZV - prompt_end_charpos;
- i_byte = ZV_BYTE - prompt_end_bytepos;
+ i = PT - prompt_end_charpos;
+ i_byte = PT_BYTE - prompt_end_bytepos;
}
/* If completion finds next char not unique,
if (i == XSTRING (completion)->size)
{
GCPRO1 (completion);
- tem = Ftry_completion (concat2 (Fminibuffer_contents (), build_string (" ")),
+ tem = Ftry_completion (concat2 (minibuffer_completion_contents (),
+ build_string (" ")),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
UNGCPRO;
{
GCPRO1 (completion);
tem =
- Ftry_completion (concat2 (Fminibuffer_contents (), build_string ("-")),
+ Ftry_completion (concat2 (minibuffer_completion_contents (),
+ build_string ("-")),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate);
UNGCPRO;
if (STRINGP (tem))
completion = tem;
}
- }
+ }
/* Now find first word-break in the stuff found by completion.
i gets index in string of where to stop completing. */
/* If got no characters, print help for user. */
- if (i == ZV - prompt_end_charpos)
+ if (i == PT - prompt_end_charpos)
{
if (!NILP (Vcompletion_auto_help))
Fminibuffer_completion_help ();
/* Otherwise insert in minibuffer the chars we got */
- Fdelete_minibuffer_contents ();
+ if (! NILP (Vminibuffer_completing_file_name)
+ && XSTRING (completion)->data[STRING_BYTES (XSTRING (completion)) - 1] == '/'
+ && PT < ZV
+ && FETCH_CHAR (PT_BYTE) == '/')
+ {
+ del_range (prompt_end_charpos, PT + 1);
+ }
+ else
+ del_range (prompt_end_charpos, PT);
+
insert_from_string (completion, 0, 0, i, i_byte, 1);
return Qt;
}
if (BUFFERP (Vstandard_output))
{
tem = Findent_to (make_number (35), make_number (2));
-
+
column = XINT (tem);
}
else
Lisp_Object completions;
message ("Making completion list...");
- completions = Fall_completions (Fminibuffer_contents (),
+ completions = Fall_completions (minibuffer_completion_contents (),
Vminibuffer_completion_table,
Vminibuffer_completion_predicate,
Qt);
Vminibuffer_completion_predicate = Qnil;
DEFVAR_LISP ("minibuffer-completion-confirm", &Vminibuffer_completion_confirm,
- doc: /* Non-nil => demand confirmation of completion before exiting minibuffer. */);
+ doc: /* Non-nil means to demand confirmation of completion before exiting minibuffer. */);
Vminibuffer_completion_confirm = Qnil;
DEFVAR_LISP ("minibuffer-completing-file-name",
defsubr (&Stry_completion);
defsubr (&Sall_completions);
+ defsubr (&Stest_completion);
+ defsubr (&Sassoc_string);
defsubr (&Scompleting_read);
defsubr (&Sminibuffer_complete);
defsubr (&Sminibuffer_complete_word);