X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/0da4d471d931cc4454544fd64a18fcc6f1183a14..14b6e3bb481f4cb48f397c50ae8116b6fc39c937:/src/minibuf.c diff --git a/src/minibuf.c b/src/minibuf.c index 09e5675d68..46c54d8724 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1,6 +1,7 @@ /* Minibuffer input and completion. - Copyright (C) 1985,86,93,94,95,96,97,98,99,2000,01,03,04 - 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. @@ -16,8 +17,8 @@ GNU General Public License for more details. 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 @@ -65,6 +66,10 @@ Lisp_Object Qhistory_length, Vhistory_length; 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; @@ -127,7 +132,8 @@ int minibuffer_auto_raise; 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; @@ -137,6 +143,10 @@ Lisp_Object Qcurrent_input_method, Qactivate_input_method; 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; @@ -349,7 +359,7 @@ BUFFER can be a buffer or a buffer name. */) 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. */ @@ -388,6 +398,19 @@ The current buffer must be a minibuffer. */) 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. @@ -400,17 +423,6 @@ The current buffer must be 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); -} /* Read from the minibuffer using keymap MAP and initial contents INITIAL, putting point minus BACKUP_N bytes from the end of INITIAL, @@ -459,6 +471,9 @@ read_minibuf (map, initial, prompt, backup_n, expflag, /* 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; @@ -515,7 +530,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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), @@ -596,6 +611,10 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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 @@ -631,6 +650,23 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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); @@ -667,10 +703,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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)) { @@ -730,7 +762,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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, @@ -749,7 +782,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, 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; @@ -950,7 +983,7 @@ POSITION in the minibuffer. Any integer value less than or equal to 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; { @@ -993,7 +1026,7 @@ DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0, 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; { @@ -1008,11 +1041,13 @@ DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0, 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. */ @@ -1126,11 +1161,14 @@ DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0, 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; @@ -1139,14 +1177,33 @@ If optional third arg REQUIRE-MATCH is non-nil, { 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 @@ -1175,13 +1232,16 @@ minibuf_conform_representation (string, basis) 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. @@ -1205,11 +1265,11 @@ is used to further constrain the set of candidates. */) 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; @@ -1221,6 +1281,7 @@ is used to further constrain the set of candidates. */) 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; @@ -1247,10 +1308,10 @@ is used to further constrain the set of candidates. */) } 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 @@ -1277,18 +1338,19 @@ is used to further constrain the set of candidates. */) /* 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. */ { @@ -1342,9 +1404,9 @@ is used to further constrain the set of candidates. */) 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)) @@ -1375,15 +1437,15 @@ is used to further constrain the set of candidates. */) ((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)))) @@ -1435,10 +1497,13 @@ is used to further constrain the set of candidates. */) 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. @@ -1470,13 +1535,14 @@ are ignored unless STRING itself starts with a space. */) || NILP (XCAR (alist)))); int index = 0, obsize = 0; int bindcount = -1; - Lisp_Object bucket, tem; + 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; @@ -1503,10 +1569,10 @@ are ignored unless STRING itself starts with a space. */) } 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 @@ -1533,6 +1599,9 @@ are ignored unless STRING itself starts with a space. */) /* 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 @@ -1541,9 +1610,9 @@ are ignored unless STRING itself starts with a 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))) @@ -1707,8 +1776,12 @@ Completion ignores case if the ambient value of 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)); @@ -1740,7 +1813,7 @@ the values STRING, PREDICATE and `lambda'. */) || NILP (alist)) { tem = Fassoc_string (string, alist, completion_ignore_case ? Qt : Qnil); - if NILP (tem) + if (NILP (tem)) return Qnil; } else if (VECTORP (alist)) @@ -1839,6 +1912,24 @@ the values STRING, PREDICATE and `lambda'. */) 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 @@ -1855,7 +1946,7 @@ do_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; @@ -1877,7 +1968,7 @@ do_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. @@ -1944,7 +2035,7 @@ do_completion () last_exact_completion = completion; if (!NILP (last)) { - tem = minibuffer_completion_contents (); + tem = Fminibuffer_completion_contents (); if (!NILP (Fequal (tem, last))) Fminibuffer_completion_help (); } @@ -2062,6 +2153,8 @@ complete_and_exit_2 (ignore) 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. @@ -2070,16 +2163,35 @@ a repetition of this command will 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); @@ -2106,7 +2218,7 @@ a repetition of this command will exit. */) return Qnil; } exit: - return Fthrow (Qexit, Qnil); + return Fexit_minibuffer (); /* NOTREACHED */ } @@ -2120,14 +2232,13 @@ Return nil if there is no valid completion, else t. */) { 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)) @@ -2159,7 +2270,7 @@ Return nil if there is no valid completion, else t. */) 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. */ @@ -2223,7 +2334,7 @@ Return nil if there is no valid completion, else t. */) 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); @@ -2235,7 +2346,7 @@ Return nil if there is no valid completion, else t. */) { GCPRO1 (completion); tem = - Ftry_completion (concat2 (minibuffer_completion_contents (), + Ftry_completion (concat2 (Fminibuffer_completion_contents (), build_string ("-")), Vminibuffer_completion_table, Vminibuffer_completion_predicate); @@ -2251,7 +2362,7 @@ Return nil if there is no valid completion, else t. */) { 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, @@ -2292,7 +2403,7 @@ Return nil if there is no valid completion, else t. */) } 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. @@ -2302,14 +2413,23 @@ alternative, the second serves as annotation. 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; @@ -2318,7 +2438,7 @@ It can find the completion buffer in `standard-output'. */) 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)); @@ -2329,7 +2449,7 @@ It can find the completion buffer in `standard-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; @@ -2337,7 +2457,7 @@ It can find the completion buffer in `standard-output'. */) startpos = Qnil; - elt = Fcar (tail); + elt = XCAR (tail); if (SYMBOLP (elt)) elt = SYMBOL_NAME (elt); /* Compute the length of this element. */ @@ -2467,17 +2587,32 @@ It can find the completion buffer in `standard-output'. */) } } - 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. */) @@ -2486,7 +2621,7 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co 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); @@ -2498,9 +2633,21 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co 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; } @@ -2513,14 +2660,21 @@ DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0, 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, @@ -2545,6 +2699,8 @@ If no minibuffer is active, return nil. */) 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; @@ -2563,7 +2719,12 @@ temp_echo_area_glyphs (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)) @@ -2577,7 +2738,7 @@ temp_echo_area_glyphs (string) 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; @@ -2654,6 +2815,9 @@ syms_of_minibuf () 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; @@ -2669,25 +2833,34 @@ syms_of_minibuf () 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. */); +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. -See also `read-file-name-completion-ignore-case' concerning case significance -in completion when reading a file name. */); +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, @@ -2770,6 +2943,10 @@ properties. */); 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); @@ -2777,6 +2954,7 @@ properties. */); defsubr (&Sread_string); defsubr (&Sread_command); defsubr (&Sread_variable); + defsubr (&Sinternal_complete_buffer); defsubr (&Sread_buffer); defsubr (&Sread_no_blanks_input); defsubr (&Sminibuffer_depth); @@ -2786,6 +2964,7 @@ properties. */); defsubr (&Sminibuffer_prompt_end); defsubr (&Sminibuffer_contents); defsubr (&Sminibuffer_contents_no_properties); + defsubr (&Sminibuffer_completion_contents); defsubr (&Sdelete_minibuffer_contents); defsubr (&Stry_completion); @@ -2829,10 +3008,16 @@ keys_of_minibuf () 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