X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/6801b30063113396dc7731c99a564f6b39348156..5180cc015e2cca6f8cb635044ac4643cf83276cb:/src/minibuf.c diff --git a/src/minibuf.c b/src/minibuf.c index f54bea2a84..3fd3f98585 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1,6 +1,6 @@ /* Minibuffer input and completion. - Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. + Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -21,17 +21,19 @@ Boston, MA 02111-1307, USA. */ #include +#include + #include "lisp.h" #include "commands.h" #include "buffer.h" #include "charset.h" #include "dispextern.h" +#include "keyboard.h" #include "frame.h" #include "window.h" #include "syntax.h" -#include "keyboard.h" - -#define min(a, b) ((a) < (b) ? (a) : (b)) +#include "intervals.h" +#include "keymap.h" extern int quit_char; @@ -40,29 +42,37 @@ extern int quit_char; invocation, the next element is used for a recursive minibuffer invocation, etc. The list is extended at the end as deeper minibuffer recursions are encountered. */ + Lisp_Object Vminibuffer_list; /* Data to remember during recursive minibuffer invocations */ + Lisp_Object minibuf_save_list; /* Depth in minibuffer invocations. */ + int minibuf_level; /* Nonzero means display completion help for invalid input. */ -int auto_help; + +Lisp_Object Vcompletion_auto_help; /* The maximum length of a minibuffer history. */ + Lisp_Object Qhistory_length, Vhistory_length; /* Fread_minibuffer leaves the input here as a string. */ + Lisp_Object last_minibuf_string; /* Nonzero means let functions called when within a minibuffer invoke recursive minibuffers (to read arguments, or whatever) */ + int enable_recursive_minibuffers; /* Nonzero means don't ignore text properties in Fread_from_minibuffer. */ + int minibuffer_allow_text_properties; /* help-form is bound to this while in the minibuffer. */ @@ -77,7 +87,13 @@ Lisp_Object Vminibuffer_history_variable; Lisp_Object Vminibuffer_history_position; -Lisp_Object Qminibuffer_history; +/* Text properties that are added to minibuffer prompts. + These are in addition to the basic `field' property, and stickiness + properties. */ + +Lisp_Object Vminibuffer_prompt_properties; + +Lisp_Object Qminibuffer_history, Qbuffer_name_history; Lisp_Object Qread_file_name_internal; @@ -86,6 +102,9 @@ Lisp_Object Qread_file_name_internal; Lisp_Object Qminibuffer_setup_hook, Vminibuffer_setup_hook; Lisp_Object Qminibuffer_exit_hook, Vminibuffer_exit_hook; +/* Function to call to read a buffer name. */ +Lisp_Object Vread_buffer_function; + /* Nonzero means completion ignores case. */ int completion_ignore_case; @@ -104,18 +123,22 @@ int minibuffer_auto_raise; static Lisp_Object last_exact_completion; -Lisp_Object Quser_variable_p; - -Lisp_Object Qminibuffer_default; - /* 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; + +Lisp_Object Qminibuffer_default; + Lisp_Object Qcurrent_input_method, Qactivate_input_method; +extern Lisp_Object Qmouse_face; + +extern Lisp_Object Qfield; /* Put minibuf on currently selected frame's minibuffer. We do this whenever the user starts a new minibuffer @@ -124,17 +147,25 @@ Lisp_Object Qcurrent_input_method, Qactivate_input_method; void choose_minibuf_frame () { - if (selected_frame != 0 - && !EQ (minibuf_window, selected_frame->minibuffer_window)) + if (FRAMEP (selected_frame) + && FRAME_LIVE_P (XFRAME (selected_frame)) + && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) { + 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 (selected_frame->minibuffer_window)) + if (NILP (sf->minibuffer_window)) abort (); - Fset_window_buffer (selected_frame->minibuffer_window, - XWINDOW (minibuf_window)->buffer); - minibuf_window = selected_frame->minibuffer_window; + /* Under X, we come here with minibuf_window being the + minibuffer window of the unused termcap window created in + init_window_once. That window doesn't have a buffer. */ + buffer = XWINDOW (minibuf_window)->buffer; + if (BUFFERP (buffer)) + Fset_window_buffer (sf->minibuffer_window, buffer); + minibuf_window = sf->minibuffer_window; } /* Make sure no other frame has a minibuffer as its selected window, @@ -146,7 +177,7 @@ choose_minibuf_frame () FOR_EACH_FRAME (tail, frame) if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) - && !(XFRAME (frame) == selected_frame + && !(EQ (frame, selected_frame) && minibuf_level > 0)) Fset_frame_selected_window (frame, Fframe_first_window (frame)); } @@ -162,13 +193,13 @@ choose_minibuf_frame_1 (ignore) DEFUN ("set-minibuffer-window", Fset_minibuffer_window, Sset_minibuffer_window, 1, 1, 0, - "Specify which minibuffer window to use for the minibuffer.\n\ -This effects where the minibuffer is displayed if you put text in it\n\ -without invoking the usual minibuffer commands.") - (window) + doc: /* Specify which minibuffer window to use for the minibuffer. +This effects where the minibuffer is displayed if you put text in it +without invoking the usual minibuffer commands. */) + (window) Lisp_Object window; { - CHECK_WINDOW (window, 1); + CHECK_WINDOW (window); if (! MINI_WINDOW_P (XWINDOW (window))) error ("Window is not a minibuffer window"); @@ -180,12 +211,170 @@ without invoking the usual minibuffer commands.") /* Actual minibuffer invocation. */ -static void read_minibuf_unwind (); -Lisp_Object get_minibuffer (); -static Lisp_Object read_minibuf (); +static Lisp_Object read_minibuf_unwind P_ ((Lisp_Object)); +static Lisp_Object read_minibuf P_ ((Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object, + int, Lisp_Object, + Lisp_Object, Lisp_Object, + int, int)); +static Lisp_Object read_minibuf_noninteractive P_ ((Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object, + int, Lisp_Object, + Lisp_Object, Lisp_Object, + int, int)); +static Lisp_Object string_to_object P_ ((Lisp_Object, Lisp_Object)); + + +/* Read a Lisp object from VAL and return it. If VAL is an empty + string, and DEFALT is a string, read from DEFALT instead of VAL. */ + +static Lisp_Object +string_to_object (val, defalt) + Lisp_Object val, defalt; +{ + 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) + { + /* Ignore trailing whitespace; any other trailing junk + is an error. */ + int i; + pos = string_char_to_byte (val, pos); + for (i = pos; i < STRING_BYTES (XSTRING (val)); i++) + { + int c = XSTRING (val)->data[i]; + if (c != ' ' && c != '\t' && c != '\n') + error ("Trailing garbage following expression"); + } + } + + val = Fcar (expr_and_pos); + RETURN_UNGCPRO (val); +} + + +/* Like read_minibuf but reading from stdin. This function is called + from read_minibuf to do the job if noninteractive. */ + +static Lisp_Object +read_minibuf_noninteractive (map, initial, prompt, backup_n, expflag, + histvar, histpos, defalt, allow_props, + inherit_input_method) + Lisp_Object map; + Lisp_Object initial; + Lisp_Object prompt; + Lisp_Object backup_n; + int expflag; + Lisp_Object histvar; + Lisp_Object histpos; + Lisp_Object defalt; + int allow_props; + int inherit_input_method; +{ + int size, len; + char *line, *s; + Lisp_Object val; + + fprintf (stdout, "%s", XSTRING (prompt)->data); + fflush (stdout); + + val = Qnil; + size = 100; + len = 0; + line = (char *) xmalloc (size * sizeof *line); + while ((s = fgets (line + len, size - len, stdin)) != NULL + && (len = strlen (line), + len == size - 1 && line[len - 1] != '\n')) + { + size *= 2; + line = (char *) xrealloc (line, size); + } + + if (s) + { + len = strlen (line); + + if (len > 0 && line[len - 1] == '\n') + line[--len] = '\0'; + + val = build_string (line); + xfree (line); + } + else + { + 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; +} + + +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. */) + () +{ + /* 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 end; +} + +DEFUN ("minibuffer-contents", Fminibuffer_contents, + Sminibuffer_contents, 0, 0, 0, + doc: /* Return the user input in a minbuffer as a string. +The current buffer must be a minibuffer. */) + () +{ + int prompt_end = XINT (Fminibuffer_prompt_end ()); + return make_buffer_string (prompt_end, ZV, 1); +} + +DEFUN ("minibuffer-contents-no-properties", Fminibuffer_contents_no_properties, + Sminibuffer_contents_no_properties, 0, 0, 0, + doc: /* Return the user input in a minbuffer as a string, without text-properties. +The current buffer must be a minibuffer. */) + () +{ + int prompt_end = XINT (Fminibuffer_prompt_end ()); + return make_buffer_string (prompt_end, ZV, 0); +} + +DEFUN ("delete-minibuffer-contents", Fdelete_minibuffer_contents, + Sdelete_minibuffer_contents, 0, 0, 0, + doc: /* Delete all user input in a minibuffer. +The current buffer must be a minibuffer. */) + () +{ + int prompt_end = XINT (Fminibuffer_prompt_end ()); + if (prompt_end < ZV) + del_range (prompt_end, ZV); + return Qnil; +} + /* Read from the minibuffer using keymap MAP, initial contents INITIAL - (a string), putting point minus BACKUP_N chars from the end of INITIAL, + (a string), putting point minus BACKUP_N bytes from the end of INITIAL, prompting with PROMPT (a string), using history list HISTVAR with initial position HISTPOS. (BACKUP_N should be <= 0.) @@ -213,6 +402,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, Lisp_Object histvar; Lisp_Object histpos; Lisp_Object defalt; + int allow_props; int inherit_input_method; { Lisp_Object val; @@ -220,10 +410,16 @@ read_minibuf (map, initial, prompt, backup_n, expflag, Lisp_Object mini_frame, ambient_dir, minibuffer, input_method; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; Lisp_Object enable_multibyte; + extern Lisp_Object Qfront_sticky; + extern Lisp_Object Qrear_nonsticky; specbind (Qminibuffer_default, defalt); single_kboard_state (); +#ifdef HAVE_X_WINDOWS + if (display_hourglass_p) + cancel_hourglass (); +#endif val = Qnil; ambient_dir = current_buffer->directory; @@ -249,6 +445,14 @@ read_minibuf (map, initial, prompt, backup_n, expflag, build_string ("Command attempted to use minibuffer while in minibuffer")); } + if (noninteractive) + { + val = read_minibuf_noninteractive (map, initial, prompt, backup_n, + expflag, histvar, histpos, defalt, + allow_props, inherit_input_method); + return unbind_to (count, val); + } + /* Choose the minibuffer window and frame, and take action on them. */ choose_minibuf_frame (); @@ -261,7 +465,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, /* If the minibuffer window is on a different frame, save that frame's configuration too. */ mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); - if (XFRAME (mini_frame) != selected_frame) + if (!EQ (mini_frame, selected_frame)) record_unwind_protect (Fset_window_configuration, Fcurrent_window_configuration (mini_frame)); @@ -295,7 +499,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, /* Now that we can restore all those variables, start changing them. */ - minibuf_prompt_width = 0; /* xdisp.c puts in the right value. */ + minibuf_prompt_width = 0; minibuf_prompt = Fcopy_sequence (prompt); Vminibuffer_history_position = histpos; Vminibuffer_history_variable = histvar; @@ -330,11 +534,11 @@ read_minibuf (map, initial, prompt, backup_n, expflag, for (buf_list = Vbuffer_alist; CONSP (buf_list); - buf_list = XCONS (buf_list)->cdr) + buf_list = XCDR (buf_list)) { Lisp_Object other_buf; - other_buf = XCONS (XCONS (buf_list)->car)->cdr; + other_buf = XCDR (XCAR (buf_list)); if (STRINGP (XBUFFER (other_buf)->directory)) { current_buffer->directory = XBUFFER (other_buf)->directory; @@ -343,8 +547,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, } } - if (XFRAME (mini_frame) != selected_frame) - Fredirect_frame_focus (Fselected_frame (), mini_frame); + if (!EQ (mini_frame, selected_frame)) + Fredirect_frame_focus (selected_frame, mini_frame); Vminibuf_scroll_window = selected_window; Fset_window_buffer (minibuf_window, Fcurrent_buffer ()); @@ -356,34 +560,52 @@ read_minibuf (map, initial, prompt, backup_n, expflag, /* Erase the buffer. */ { - int count1 = specpdl_ptr - specpdl; + int count1 = BINDING_STACK_SIZE (); specbind (Qinhibit_read_only, Qt); + specbind (Qinhibit_modification_hooks, Qt); Ferase_buffer (); unbind_to (count1, Qnil); } + if (!NILP (current_buffer->enable_multibyte_characters) + && ! STRING_MULTIBYTE (minibuf_prompt)) + minibuf_prompt = Fstring_make_multibyte (minibuf_prompt); + + /* Insert the prompt, record where it ends. */ + Finsert (1, &minibuf_prompt); + if (PT > BEG) + { + Fput_text_property (make_number (BEG), make_number (PT), + Qfront_sticky, Qt, Qnil); + Fput_text_property (make_number (BEG), make_number (PT), + Qrear_nonsticky, Qt, Qnil); + Fput_text_property (make_number (BEG), make_number (PT), + Qfield, Qt, Qnil); + Fadd_text_properties (make_number (BEG), make_number (PT), + Vminibuffer_prompt_properties, Qnil); + } + + minibuf_prompt_width = current_column (); + + /* 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)) { Finsert (1, &initial); - if (!NILP (backup_n) && INTEGERP (backup_n)) - Fgoto_char (make_number (PT + XFASTINT (backup_n))); + if (INTEGERP (backup_n)) + Fforward_char (backup_n); } - echo_area_glyphs = 0; - /* This is in case the minibuffer-setup-hook calls Fsit_for. */ - previous_echo_glyphs = 0; - + clear_message (1, 1); current_buffer->keymap = map; /* Turn on an input method stored in INPUT_METHOD if any. */ if (STRINGP (input_method) && !NILP (Ffboundp (Qactivate_input_method))) call1 (Qactivate_input_method, input_method); - /* 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). */ @@ -391,38 +613,47 @@ read_minibuf (map, initial, prompt, backup_n, expflag, && !NILP (Vrun_hooks)) call1 (Vrun_hooks, Qminibuffer_setup_hook); -/* ??? MCC did redraw_screen here if switching screens. */ + /* Don't allow the user to undo past this point. */ + current_buffer->undo_list = Qnil; + recursive_edit_1 (); /* If cursor is on the minibuffer line, show the user we have exited by putting it in column 0. */ - if ((FRAME_CURSOR_Y (selected_frame) - >= XFASTINT (XWINDOW (minibuf_window)->top)) + if (XWINDOW (minibuf_window)->cursor.vpos >= 0 && !noninteractive) { - FRAME_CURSOR_X (selected_frame) - = FRAME_LEFT_SCROLL_BAR_WIDTH (selected_frame); - update_frame (selected_frame, 1, 1); + XWINDOW (minibuf_window)->cursor.hpos = 0; + XWINDOW (minibuf_window)->cursor.x = 0; + XWINDOW (minibuf_window)->must_be_updated_p = 1; + update_frame (XFRAME (selected_frame), 1, 1); + if (rif && rif->flush_display) + rif->flush_display (XFRAME (XWINDOW (minibuf_window)->frame)); } /* Make minibuffer contents into a string. */ Fset_buffer (minibuffer); - val = make_buffer_string (1, Z, allow_props); -#if 0 /* make_buffer_string should handle the gap. */ - bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT); -#endif + if (allow_props) + val = Fminibuffer_contents (); + else + val = Fminibuffer_contents_no_properties (); /* VAL is the string of minibuffer text. */ + last_minibuf_string = val; /* Add the value to the appropriate history list unless it is empty. */ if (XSTRING (val)->size != 0 - && SYMBOLP (Vminibuffer_history_variable) - && ! EQ (XSYMBOL (Vminibuffer_history_variable)->value, Qunbound)) + && SYMBOLP (Vminibuffer_history_variable)) { /* If the caller wanted to save the value read on a history list, then do so if the value is not already the front of the list. */ Lisp_Object histval; + + /* If variable is unbound, make it nil. */ + if (EQ (SYMBOL_VALUE (Vminibuffer_history_variable), Qunbound)) + Fset (Vminibuffer_history_variable, Qnil); + histval = Fsymbol_value (Vminibuffer_history_variable); /* The value of the history variable must be a cons or nil. Other @@ -456,17 +687,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, /* If Lisp form desired instead of string, parse it. */ if (expflag) - { - Lisp_Object expr_and_pos; - unsigned char *p; - - expr_and_pos = Fread_from_string (val, Qnil, Qnil); - /* Ignore trailing whitespace; any other trailing junk is an error. */ - for (p = XSTRING (val)->data + XINT (Fcdr (expr_and_pos)); *p; p++) - if (*p != ' ' && *p != '\t' && *p != '\n') - error ("Trailing garbage following expression"); - val = Fcar (expr_and_pos); - } + val = string_to_object (val, defalt); /* The appropriate frame will get selected in set-window-configuration. */ @@ -502,7 +723,7 @@ get_minibuffer (depth) enabled in it. */ Fbuffer_enable_undo (buf); - XCONS (tail)->car = buf; + XSETCAR (tail, buf); } else { @@ -518,10 +739,10 @@ get_minibuffer (depth) return buf; } -/* This function is called on exiting minibuffer, whether normally or not, - and it restores the current window, buffer, etc. */ +/* This function is called on exiting minibuffer, whether normally or + not, and it restores the current window, buffer, etc. */ -static void +static Lisp_Object read_minibuf_unwind (data) Lisp_Object data; { @@ -539,8 +760,8 @@ read_minibuf_unwind (data) minibuf_level--; window = minibuf_window; - /* To keep things predictable, in case it matters, let's be in the minibuffer - when we reset the relevant variables. */ + /* To keep things predictable, in case it matters, let's be in the + minibuffer when we reset the relevant variables. */ Fset_buffer (XWINDOW (window)->buffer); /* Restore prompt, etc, from outer minibuffer level. */ @@ -570,56 +791,54 @@ read_minibuf_unwind (data) int count = specpdl_ptr - specpdl; /* Prevent error in erase-buffer. */ specbind (Qinhibit_read_only, Qt); + specbind (Qinhibit_modification_hooks, Qt); old_deactivate_mark = Vdeactivate_mark; Ferase_buffer (); Vdeactivate_mark = old_deactivate_mark; unbind_to (count, Qnil); } + /* When we get to the outmost level, make sure we resize the + mini-window back to its normal size. */ + if (minibuf_level == 0) + resize_mini_window (XWINDOW (window), 0); + /* Make sure minibuffer window is erased, not ignored. */ windows_or_buffers_changed++; XSETFASTINT (XWINDOW (window)->last_modified, 0); XSETFASTINT (XWINDOW (window)->last_overlay_modified, 0); + return Qnil; } -/* 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, 7, 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 at position POSITION in the minibuffer.\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 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\ -Sixth arg DEFAULT-VALUE is the default value. If non-nil, it is used\n\ - for history commands, and as the value to return if the user enters\n\ - the empty string.\n\ -Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\ - the current input method and the setting of enable-multibyte-characters.\n\ -If the variable `minibuffer-allow-text-properties is non-nil,\n\ - then the string which is returned includes whatever text properties\n\ - were present in the minibuffer. Otherwise the value has no text properties.") - (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method) - */ - DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0, - 0 /* See immediately above */) - (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method) + doc: /* Read a string from the minibuffer, prompting with string PROMPT. +If optional second arg INITIAL-CONTENTS is non-nil, it is a string + to be inserted into the minibuffer before reading input. + If INITIAL-CONTENTS is (STRING . POSITION), the initial input + 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 + and return that object: + in other words, do `(car (read-from-string INPUT-STRING))' +Fifth arg 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, + or it can be a cons cell (HISTVAR . HISTPOS). + In that case, HISTVAR is the history list variable to use, + and HISTPOS is the initial position (the position in the list + which INITIAL-CONTENTS corresponds to). + Positions are counted starting from 1 at the beginning of the list. +Sixth arg DEFAULT-VALUE is the default value. If non-nil, it is available + for history commands; but `read-from-minibuffer' does NOT return DEFAULT-VALUE + if the user enters empty input! It returns the empty string. +Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits + the current input method and the setting of enable-multibyte-characters. +If the variable `minibuffer-allow-text-properties' is non-nil, + then the string which is returned includes whatever text properties + were present in the minibuffer. Otherwise the value has no text properties. */) + (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; { @@ -629,7 +848,7 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, position = Qnil; - CHECK_STRING (prompt, 0); + CHECK_STRING (prompt); if (!NILP (initial_contents)) { if (CONSP (initial_contents)) @@ -637,10 +856,10 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, position = Fcdr (initial_contents); initial_contents = Fcar (initial_contents); } - CHECK_STRING (initial_contents, 1); + CHECK_STRING (initial_contents); if (!NILP (position)) { - CHECK_NUMBER (position, 0); + CHECK_NUMBER (position); /* Convert to distance from end of input. */ if (XINT (position) < 1) /* A number too small means the beginning of the string. */ @@ -653,7 +872,7 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, if (NILP (keymap)) keymap = Vminibuffer_local_map; else - keymap = get_keymap (keymap); + keymap = get_keymap (keymap, 1, 0); if (SYMBOLP (hist)) { @@ -676,32 +895,30 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, histvar, histpos, default_value, minibuffer_allow_text_properties, !NILP (inherit_input_method)); - if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (default_value)) - val = default_value; UNGCPRO; return val; } DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0, - "Return a Lisp object read using the minibuffer.\n\ -Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS\n\ -is a string to insert in the minibuffer before reading.") - (prompt, initial_contents) + doc: /* Return a Lisp object read using the minibuffer. +Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS +is a string to insert in the minibuffer before reading. */) + (prompt, initial_contents) Lisp_Object prompt, initial_contents; { - CHECK_STRING (prompt, 0); + CHECK_STRING (prompt); if (!NILP (initial_contents)) - CHECK_STRING (initial_contents, 1); + CHECK_STRING (initial_contents); return read_minibuf (Vminibuffer_local_map, initial_contents, prompt, Qnil, 1, Qminibuffer_history, make_number (0), Qnil, 0, 0); } DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0, - "Return value of Lisp expression read using the minibuffer.\n\ -Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS\n\ -is a string to insert in the minibuffer before reading.") - (prompt, initial_contents) + doc: /* Return value of Lisp expression read using the minibuffer. +Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS +is a string to insert in the minibuffer before reading. */) + (prompt, initial_contents) Lisp_Object prompt, initial_contents; { return Feval (Fread_minibuffer (prompt, initial_contents)); @@ -710,55 +927,73 @@ is a string to insert in the minibuffer before reading.") /* Functions that use the minibuffer to read various things. */ DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, - "Read a string from the minibuffer, prompting with string PROMPT.\n\ -If non-nil, second arg INITIAL-INPUT is a string to insert before reading.\n\ -The third arg HISTORY, if non-nil, specifies a history list\n\ - and optionally the initial position in the list.\n\ -See `read-from-minibuffer' for details of HISTORY argument.\n\ -Fourth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\ - the current input method and the setting of enable-multibyte-characters.") - (prompt, initial_input, history, default_value, inherit_input_method) + doc: /* Read a string from the minibuffer, prompting with string PROMPT. +If non-nil, second arg INITIAL-INPUT is a string to insert before reading. +The third arg HISTORY, if non-nil, specifies a history list + and optionally the initial position in the list. +See `read-from-minibuffer' for details of HISTORY argument. +Fourth arg DEFAULT-VALUE is the default value. If non-nil, it is used + for history commands, and as the value to return if the user enters + the empty string. +Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits + the current input method and the setting of enable-multibyte-characters. */) + (prompt, initial_input, history, default_value, inherit_input_method) Lisp_Object prompt, initial_input, history, default_value; Lisp_Object inherit_input_method; { - return Fread_from_minibuffer (prompt, initial_input, Qnil, - Qnil, history, default_value, - inherit_input_method); + Lisp_Object val; + val = Fread_from_minibuffer (prompt, initial_input, Qnil, + Qnil, history, default_value, + inherit_input_method); + if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (default_value)) + val = default_value; + return val; } DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 3, 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.\n\ -Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits\n\ -the current input method and the setting of enable-multibyte-characters.") - (prompt, init, inherit_input_method) - Lisp_Object prompt, init, inherit_input_method; + doc: /* Read a string from the terminal, not allowing blanks. +Prompt with PROMPT, and provide INITIAL as an initial value of the input string. +Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits +the current input method and the setting of enable-multibyte-characters. */) + (prompt, initial, inherit_input_method) + Lisp_Object prompt, initial, inherit_input_method; { - CHECK_STRING (prompt, 0); - if (! NILP (init)) - CHECK_STRING (init, 1); + CHECK_STRING (prompt); + if (! NILP (initial)) + CHECK_STRING (initial); - return read_minibuf (Vminibuffer_local_ns_map, init, prompt, Qnil, + return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, Qnil, 0, Qminibuffer_history, make_number (0), Qnil, 0, !NILP (inherit_input_method)); } DEFUN ("read-command", Fread_command, Sread_command, 1, 2, 0, - "Read the name of a command and return as a symbol.\n\ -Prompts with PROMPT. By default, return DEFAULT-VALUE.") - (prompt, default_value) + doc: /* Read the name of a command and return as a symbol. +Prompts with PROMPT. By default, return DEFAULT-VALUE. */) + (prompt, default_value) Lisp_Object prompt, default_value; { - return Fintern (Fcompleting_read (prompt, Vobarray, Qcommandp, Qt, - Qnil, Qnil, default_value, Qnil), - Qnil); + Lisp_Object name, default_string; + + if (NILP (default_value)) + default_string = Qnil; + else if (SYMBOLP (default_value)) + XSETSTRING (default_string, XSYMBOL (default_value)->name); + else + default_string = default_value; + + name = Fcompleting_read (prompt, Vobarray, Qcommandp, Qt, + Qnil, Qnil, default_string, Qnil); + if (NILP (name)) + return name; + return Fintern (name, Qnil); } #ifdef NOTDEF DEFUN ("read-function", Fread_function, Sread_function, 1, 1, 0, - "One arg PROMPT, a string. Read the name of a function and return as a symbol.\n\ -Prompts with PROMPT.") - (prompt) + doc: /* One arg PROMPT, a string. Read the name of a function and return as a symbol. +Prompts with PROMPT. */) + (prompt) Lisp_Object prompt; { return Fintern (Fcompleting_read (prompt, Vobarray, Qfboundp, Qt, Qnil, Qnil, Qnil, Qnil), @@ -767,79 +1002,120 @@ Prompts with PROMPT.") #endif /* NOTDEF */ DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0, - "Read the name of a user variable and return it as a symbol.\n\ -Prompts with PROMPT. By default, return DEFAULT-VALUE.\n\ -A user variable is one whose documentation starts with a `*' character.") - (prompt, default_value) + doc: /* Read the name of a user variable and return it as a symbol. +Prompts 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; { - return Fintern (Fcompleting_read (prompt, Vobarray, - Quser_variable_p, Qt, - Qnil, Qnil, default_value, Qnil), - Qnil); + Lisp_Object name, default_string; + + if (NILP (default_value)) + default_string = Qnil; + else if (SYMBOLP (default_value)) + XSETSTRING (default_string, XSYMBOL (default_value)->name); + else + default_string = default_value; + + name = Fcompleting_read (prompt, Vobarray, + Quser_variable_p, Qt, + Qnil, Qnil, default_string, Qnil); + if (NILP (name)) + return name; + return Fintern (name, Qnil); } DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0, - "One arg PROMPT, a string. Read the name of a buffer and return as a string.\n\ -Prompts with PROMPT.\n\ -Optional second arg DEF is value to return if user enters an empty line.\n\ -If optional third arg REQUIRE-MATCH is non-nil, only existing buffer names are allowed.") - (prompt, def, require_match) + doc: /* One arg PROMPT, a string. Read the name of a buffer and return as a string. +Prompts 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. */) + (prompt, def, require_match) Lisp_Object prompt, def, require_match; { - Lisp_Object tem; - Lisp_Object args[3]; - + Lisp_Object args[4]; + if (BUFFERP (def)) def = XBUFFER (def)->name; - if (!NILP (def)) + + if (NILP (Vread_buffer_function)) + { + if (!NILP (def)) + { + 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, + def, Qnil); + } + else { - args[0] = build_string ("%s(default %s) "); + args[0] = Vread_buffer_function; args[1] = prompt; args[2] = def; - prompt = Fformat (3, args); + args[3] = require_match; + return Ffuncall(4, args); } - return Fcompleting_read (prompt, Vbuffer_alist, Qnil, - require_match, Qnil, Qnil, def, Qnil); } +static Lisp_Object +minibuf_conform_representation (string, basis) + Lisp_Object string, basis; +{ + if (STRING_MULTIBYTE (string) == STRING_MULTIBYTE (basis)) + return string; + + if (STRING_MULTIBYTE (string)) + return Fstring_make_unibyte (string); + else + return Fstring_make_multibyte (string); +} + DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0, - "Return common substring of all completions of STRING in ALIST.\n\ -Each car of each element of ALIST is tested to see if it begins with STRING.\n\ -All that match are compared together; the longest initial sequence\n\ -common to all matches is returned as a string.\n\ -If there is no match at all, nil is returned.\n\ -For an exact match, t is returned.\n\ -\n\ -ALIST can be an obarray instead of an alist.\n\ -Then the print names of all symbols in the obarray are the possible matches.\n\ -\n\ -ALIST can also be a function to do the completion itself.\n\ -It receives three arguments: the values STRING, PREDICATE and nil.\n\ -Whatever it returns becomes the value of `try-completion'.\n\ -\n\ -If optional third argument PREDICATE is non-nil,\n\ -it is used to test each possible match.\n\ -The match is a candidate only if PREDICATE returns non-nil.\n\ -The argument given to PREDICATE is the alist element\n\ -or the symbol from the obarray.") - (string, alist, predicate) + doc: /* Return common substring of all completions of STRING in ALIST. +Each car of each element of ALIST is tested to see if it begins with STRING. +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. + +ALIST can be an obarray instead of an alist. +Then the print 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. +Whatever it returns becomes the value of `try-completion'. + +If optional third argument PREDICATE is non-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. +Additionally to this predicate, `completion-regexp-list' +is used to further constrain the set of candidates. */) + (string, alist, predicate) Lisp_Object string, alist, predicate; { Lisp_Object bestmatch, tail, elt, eltstring; - int bestmatchsize; + /* Size in bytes of BESTMATCH. */ + int bestmatchsize = 0; + /* These are in bytes, too. */ int compare, matchsize; int list = CONSP (alist) || NILP (alist); - int index, obsize; + int index = 0, obsize = 0; int matchcount = 0; Lisp_Object bucket, zero, end, tem; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - CHECK_STRING (string, 0); + CHECK_STRING (string); if (!list && !VECTORP (alist)) return call3 (alist, string, predicate, Qnil); - bestmatch = Qnil; + bestmatch = bucket = Qnil; /* If ALIST is not a list, set TAIL just for gc pro. */ tail = alist; @@ -889,8 +1165,11 @@ or the symbol from the obarray.") if (STRINGP (eltstring) && XSTRING (string)->size <= XSTRING (eltstring)->size - && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data, - XSTRING (string)->size)) + && (tem = Fcompare_strings (eltstring, make_number (0), + make_number (XSTRING (string)->size), + string, make_number (0), Qnil, + completion_ignore_case ?Qt : Qnil), + EQ (Qt, tem))) { /* Yes. */ Lisp_Object regexps; @@ -899,9 +1178,9 @@ or the symbol from the obarray.") /* Ignore this element if it fails to match all the regexps. */ for (regexps = Vcompletion_regexp_list; CONSP (regexps); - regexps = XCONS (regexps)->cdr) + regexps = XCDR (regexps)) { - tem = Fstring_match (XCONS (regexps)->car, eltstring, zero); + tem = Fstring_match (XCAR (regexps), eltstring, zero); if (NILP (tem)) break; } @@ -928,13 +1207,25 @@ or the symbol from the obarray.") matchcount++; if (NILP (bestmatch)) - bestmatch = eltstring, bestmatchsize = XSTRING (eltstring)->size; + { + bestmatch = eltstring; + bestmatchsize = XSTRING (eltstring)->size; + } else { compare = min (bestmatchsize, XSTRING (eltstring)->size); - matchsize = scmp (XSTRING (bestmatch)->data, - XSTRING (eltstring)->data, - compare); + tem = Fcompare_strings (bestmatch, make_number (0), + make_number (compare), + eltstring, make_number (0), + make_number (compare), + completion_ignore_case ? Qt : Qnil); + if (EQ (tem, Qt)) + matchsize = compare; + else if (XINT (tem) < 0) + matchsize = - XINT (tem) - 1; + else + matchsize = XINT (tem) - 1; + if (matchsize < 0) matchsize = compare; if (completion_ignore_case) @@ -955,10 +1246,18 @@ or the symbol from the obarray.") ((matchsize == XSTRING (eltstring)->size) == (matchsize == XSTRING (bestmatch)->size) - && !bcmp (XSTRING (eltstring)->data, - XSTRING (string)->data, XSTRING (string)->size) - && bcmp (XSTRING (bestmatch)->data, - XSTRING (string)->data, XSTRING (string)->size))) + && (tem = Fcompare_strings (eltstring, make_number (0), + make_number (XSTRING (string)->size), + string, make_number (0), + Qnil, + Qnil), + EQ (Qt, tem)) + && (tem = Fcompare_strings (bestmatch, make_number (0), + make_number (XSTRING (string)->size), + string, make_number (0), + Qnil, + Qnil), + ! EQ (Qt, tem)))) bestmatch = eltstring; } bestmatchsize = matchsize; @@ -973,13 +1272,17 @@ or the symbol from the obarray.") don't change the case of what the user typed. */ if (completion_ignore_case && bestmatchsize == XSTRING (string)->size && XSTRING (bestmatch)->size > bestmatchsize) - return string; + return minibuf_conform_representation (string, bestmatch); /* Return t if the supplied string is an exact match (counting case); it does not require any change to be made. */ if (matchcount == 1 && bestmatchsize == XSTRING (string)->size - && !bcmp (XSTRING (bestmatch)->data, XSTRING (string)->data, - bestmatchsize)) + && (tem = Fcompare_strings (bestmatch, make_number (0), + make_number (bestmatchsize), + string, make_number (0), + make_number (bestmatchsize), + Qnil), + EQ (Qt, tem))) return Qt; XSETFASTINT (zero, 0); /* Else extract the part in which */ @@ -998,7 +1301,6 @@ scmp (s1, s2, len) int len; { register int l = len; - register unsigned char *start = s1; if (completion_ignore_case) { @@ -1025,42 +1327,44 @@ scmp (s1, s2, len) } DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 4, 0, - "Search for partial matches to STRING in ALIST.\n\ -Each car of each element of ALIST is tested to see if it begins with STRING.\n\ -The value is a list of all the strings from ALIST that match.\n\ -\n\ -ALIST can be an obarray instead of an alist.\n\ -Then the print names of all symbols in the obarray are the possible matches.\n\ -\n\ -ALIST can also be a function to do the completion itself.\n\ -It receives three arguments: the values STRING, PREDICATE and t.\n\ -Whatever it returns becomes the value of `all-completion'.\n\ -\n\ -If optional third argument PREDICATE is non-nil,\n\ -it is used to test each possible match.\n\ -The match is a candidate only if PREDICATE returns non-nil.\n\ -The argument given to PREDICATE is the alist element\n\ -or the symbol from the obarray.\n\ -\n\ -If the optional fourth argument HIDE-SPACES is non-nil,\n\ -strings in ALIST that start with a space\n\ -are ignored unless STRING itself starts with a space.") - (string, alist, predicate, hide_spaces) + doc: /* Search for partial matches to STRING in ALIST. +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. + +ALIST can also be a function to do the completion itself. +It receives three arguments: the values STRING, PREDICATE and t. +Whatever it returns becomes the value of `all-completions'. + +If optional third argument PREDICATE is non-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. +Additionally to this predicate, `completion-regexp-list' +is used to further constrain the set of candidates. + +If the optional fourth argument HIDE-SPACES is non-nil, +strings in ALIST that start with a space +are ignored unless STRING itself starts with a space. */) + (string, alist, predicate, hide_spaces) Lisp_Object string, alist, predicate, hide_spaces; { Lisp_Object tail, elt, eltstring; Lisp_Object allmatches; int list = CONSP (alist) || NILP (alist); - int index, obsize; + int index = 0, obsize = 0; Lisp_Object bucket, tem; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - CHECK_STRING (string, 0); + CHECK_STRING (string); if (!list && !VECTORP (alist)) { return call3 (alist, string, predicate, Qt); } - allmatches = Qnil; + allmatches = bucket = Qnil; /* If ALIST is not a list, set TAIL just for gc pro. */ tail = alist; @@ -1112,11 +1416,16 @@ are ignored unless STRING itself starts with a space.") && XSTRING (string)->size <= XSTRING (eltstring)->size /* If HIDE_SPACES, reject alternatives that start with space unless the input starts with space. */ - && ((XSTRING (string)->size > 0 && XSTRING (string)->data[0] == ' ') + && ((STRING_BYTES (XSTRING (string)) > 0 + && XSTRING (string)->data[0] == ' ') || XSTRING (eltstring)->data[0] != ' ' || NILP (hide_spaces)) - && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data, - XSTRING (string)->size)) + && (tem = Fcompare_strings (eltstring, make_number (0), + make_number (XSTRING (string)->size), + string, make_number (0), + make_number (XSTRING (string)->size), + completion_ignore_case ? Qt : Qnil), + EQ (Qt, tem))) { /* Yes. */ Lisp_Object regexps; @@ -1125,9 +1434,9 @@ are ignored unless STRING itself starts with a space.") /* Ignore this element if it fails to match all the regexps. */ for (regexps = Vcompletion_regexp_list; CONSP (regexps); - regexps = XCONS (regexps)->cdr) + regexps = XCDR (regexps)) { - tem = Fstring_match (XCONS (regexps)->car, eltstring, zero); + tem = Fstring_match (XCAR (regexps), eltstring, zero); if (NILP (tem)) break; } @@ -1160,56 +1469,53 @@ are ignored unless STRING itself starts with a space.") Lisp_Object Vminibuffer_completion_table, Qminibuffer_completion_table; 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. +Lisp_Object Vminibuffer_completing_file_name; DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0, - "Read a string in the minibuffer, with completion.\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\ + doc: /* Read a string in the minibuffer, with completion. +PROMPT is a string to prompt with; normally it ends in a colon and a space. +TABLE is an alist whose elements' cars are strings, or an obarray. +TABLE can also be a function to do the completion itself. +PREDICATE limits completion to a subset of TABLE. See `try-completion' and `all-completions' for more details - on completion, TABLE, and PREDICATE.\n\ -\n\ -If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless\n\ - the input is (or completes to) an element of TABLE or is null.\n\ - If it is also not t, Return does not exit if it does non-null completion.\n\ -If the input is null, `completing-read' returns an empty string,\n\ - regardless of the value of REQUIRE-MATCH.\n\ -\n\ -If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\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\ -DEF, if non-nil, is the default value.\n\ -\n\ -If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits\n\ - the current input method and the setting of enable-multibyte-characters.\n\ -\n\ -Completion ignores case if the ambient value of\n\ - `completion-ignore-case' is non-nil." -*/ -DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0, - 0 /* See immediately above */) - (prompt, table, predicate, require_match, init, hist, def, inherit_input_method) - Lisp_Object prompt, table, predicate, require_match, init, hist, def; - Lisp_Object inherit_input_method; + on completion, TABLE, and PREDICATE. + +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 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. +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, + or it can be a cons cell (HISTVAR . HISTPOS). + In that case, HISTVAR is the history list variable to use, + and HISTPOS is the initial position (the position in the list + which INITIAL-INPUT corresponds to). + Positions are counted starting from 1 at the beginning of the list. +DEF, if non-nil, is the default value. + +If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits + the current input method and the setting of enable-multibyte-characters. + +Completion ignores case if the ambient value of + `completion-ignore-case' is non-nil. */) + (prompt, table, predicate, require_match, initial_input, hist, def, inherit_input_method) + Lisp_Object prompt, table, predicate, require_match, initial_input; + Lisp_Object hist, def, inherit_input_method; { Lisp_Object val, histvar, histpos, position; + Lisp_Object init; int pos = 0; int count = specpdl_ptr - specpdl; struct gcpro gcpro1; - int disable_multibyte = EQ (table, Qread_file_name_internal); + init = initial_input; GCPRO1 (def); specbind (Qminibuffer_completion_table, table); @@ -1226,10 +1532,10 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0, position = Fcdr (init); init = Fcar (init); } - CHECK_STRING (init, 0); + CHECK_STRING (init); if (!NILP (position)) { - CHECK_NUMBER (position, 0); + CHECK_NUMBER (position); /* Convert to distance from end of input. */ pos = XINT (position) - XSTRING (init)->size; } @@ -1256,16 +1562,15 @@ DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0, init, prompt, make_number (pos), 0, histvar, histpos, def, 0, !NILP (inherit_input_method)); + if (STRINGP (val) && XSTRING (val)->size == 0 && ! NILP (def)) val = def; + RETURN_UNGCPRO (unbind_to (count, val)); } Lisp_Object Fminibuffer_completion_help (); Lisp_Object assoc_for_completion (); -/* A subroutine of Fintern_soft. */ -extern Lisp_Object oblookup (); - /* Test whether TXT is an exact completion. */ Lisp_Object @@ -1281,10 +1586,24 @@ test_completion (txt) { /* Bypass intern-soft as that loses for nil */ tem = oblookup (Vminibuffer_completion_table, - XSTRING (txt)->data, XSTRING (txt)->size); + XSTRING (txt)->data, + XSTRING (txt)->size, + STRING_BYTES (XSTRING (txt))); if (!SYMBOLP (tem)) - return Qnil; - else if (!NILP (Vminibuffer_completion_predicate)) + { + if (STRING_MULTIBYTE (txt)) + txt = Fstring_make_unibyte (txt); + else + txt = Fstring_make_multibyte (txt); + + tem = oblookup (Vminibuffer_completion_table, + XSTRING (txt)->data, + XSTRING (txt)->size, + STRING_BYTES (XSTRING (txt))); + if (!SYMBOLP (tem)) + return Qnil; + } + if (!NILP (Vminibuffer_completion_predicate)) return call1 (Vminibuffer_completion_predicate, tem); else return Qt; @@ -1305,12 +1624,13 @@ test_completion (txt) int do_completion () { - Lisp_Object completion, tem; + Lisp_Object completion, string, tem; int completedp; Lisp_Object last; struct gcpro gcpro1, gcpro2; - completion = Ftry_completion (Fbuffer_string (), Vminibuffer_completion_table, + completion = Ftry_completion (Fminibuffer_contents (), + Vminibuffer_completion_table, Vminibuffer_completion_predicate); last = last_exact_completion; last_exact_completion = Qnil; @@ -1331,23 +1651,43 @@ do_completion () return 1; } - /* compiler bug */ - tem = Fstring_equal (completion, Fbuffer_string()); - if (completedp = NILP (tem)) + string = Fminibuffer_contents (); + + /* COMPLETEDP should be true if some completion was done, which + doesn't include simply changing the case of the entered string. + However, for appearance, the string is rewritten if the case + changes. */ + tem = Fcompare_strings (completion, Qnil, Qnil, string, Qnil, Qnil, Qt); + completedp = !EQ (tem, Qt); + + tem = Fcompare_strings (completion, Qnil, Qnil, string, Qnil, Qnil, Qnil); + if (!EQ (tem, Qt)) + /* Rewrite the user's input. */ { - Ferase_buffer (); /* Some completion happened */ + Fdelete_minibuffer_contents (); /* Some completion happened */ Finsert (1, &completion); + + if (! completedp) + /* The case of the string changed, but that's all. We're not + sure whether this is a unique completion or not, so try again + using the real case (this shouldn't recurse again, because + the next time try-completion will return either `t' or the + exact string). */ + { + UNGCPRO; + return do_completion (); + } } /* It did find a match. Do we match some possibility exactly now? */ - tem = test_completion (Fbuffer_string ()); + tem = test_completion (Fminibuffer_contents ()); if (NILP (tem)) { /* not an exact match */ UNGCPRO; if (completedp) return 5; - else if (auto_help) + else if (!NILP (Vcompletion_auto_help)) Fminibuffer_completion_help (); else temp_echo_area_glyphs (" [Next char not unique]"); @@ -1364,7 +1704,7 @@ do_completion () last_exact_completion = completion; if (!NILP (last)) { - tem = Fbuffer_string (); + tem = Fminibuffer_contents (); if (!NILP (Fequal (tem, last))) Fminibuffer_completion_help (); } @@ -1381,9 +1721,6 @@ assoc_for_completion (key, list) { register Lisp_Object tail; - if (completion_ignore_case) - key = Fupcase (key); - for (tail = list; !NILP (tail); tail = Fcdr (tail)) { register Lisp_Object elt, tem, thiscar; @@ -1392,29 +1729,30 @@ assoc_for_completion (key, list) thiscar = Fcar (elt); if (!STRINGP (thiscar)) continue; - if (completion_ignore_case) - thiscar = Fupcase (thiscar); - tem = Fequal (thiscar, key); - if (!NILP (tem)) return elt; + tem = Fcompare_strings (thiscar, make_number (0), Qnil, + key, make_number (0), Qnil, + completion_ignore_case ? Qt : Qnil); + if (EQ (tem, Qt)) + return elt; QUIT; } return Qnil; } DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "", - "Complete the minibuffer contents as far as possible.\n\ -Return nil if there is no valid completion, else t.\n\ -If no characters can be completed, display a list of possible completions.\n\ -If you repeat this command after it displayed such a list,\n\ -scroll the window of possible completions.") - () + doc: /* Complete the minibuffer contents as far as possible. +Return nil if there is no valid completion, else t. +If no characters can be completed, display a list of possible completions. +If you repeat this command after it displayed such a list, +scroll the window of possible completions. */) + () { register int i; Lisp_Object window, tem; - /* If the previous command was not this, then mark the completion - buffer obsolete. */ - if (! EQ (current_kboard->Vlast_command, this_command)) + /* If the previous command was not this, + mark the completion buffer obsolete. */ + if (! EQ (current_kboard->Vlast_command, Vthis_command)) Vminibuf_scroll_window = Qnil; window = Vminibuf_scroll_window; @@ -1426,7 +1764,7 @@ scroll the window of possible completions.") struct buffer *obuf = current_buffer; Fset_buffer (XWINDOW (window)->buffer); - tem = Fpos_visible_in_window_p (make_number (ZV), window); + tem = Fpos_visible_in_window_p (make_number (ZV), window, Qnil); if (! NILP (tem)) /* If end is in view, scroll up to the beginning. */ Fset_window_start (window, make_number (BEGV), Qnil); @@ -1445,10 +1783,14 @@ scroll the window of possible completions.") return Qnil; case 1: + if (PT != ZV) + Fgoto_char (make_number (ZV)); temp_echo_area_glyphs (" [Sole completion]"); break; case 3: + if (PT != ZV) + Fgoto_char (make_number (ZV)); temp_echo_area_glyphs (" [Complete, but not unique]"); break; } @@ -1477,20 +1819,20 @@ complete_and_exit_2 (ignore) } DEFUN ("minibuffer-complete-and-exit", Fminibuffer_complete_and_exit, - Sminibuffer_complete_and_exit, 0, 0, "", - "If the minibuffer contents is a valid completion then exit.\n\ -Otherwise try to complete it. If completion leads to a valid completion,\n\ -a repetition of this command will exit.") - () + Sminibuffer_complete_and_exit, 0, 0, "", + doc: /* If the minibuffer contents is a valid completion then exit. +Otherwise try to complete it. If completion leads to a valid completion, +a repetition of this command will exit. */) + () { register int i; Lisp_Object val; /* Allow user to specify null string */ - if (BEGV == ZV) + if (XINT (Fminibuffer_prompt_end ()) == ZV) goto exit; - if (!NILP (test_completion (Fbuffer_string ()))) + if (!NILP (test_completion (Fminibuffer_contents ()))) goto exit; /* Call do_completion, but ignore errors. */ @@ -1517,27 +1859,28 @@ a repetition of this command will exit.") return Qnil; } exit: - Fthrow (Qexit, Qnil); + return Fthrow (Qexit, Qnil); /* NOTREACHED */ } DEFUN ("minibuffer-complete-word", Fminibuffer_complete_word, Sminibuffer_complete_word, - 0, 0, "", - "Complete the minibuffer contents at most a single word.\n\ -After one word is completed as much as possible, a space or hyphen\n\ -is added, provided that matches some possible completion.\n\ -Return nil if there is no valid completion, else t.") - () + 0, 0, "", + doc: /* Complete the minibuffer contents at most a single word. +After one word is completed as much as possible, a space or hyphen +is added, provided that matches some possible completion. +Return nil if there is no valid completion, else t. */) + () { - Lisp_Object completion, tem; - register int i; + Lisp_Object completion, tem, tem1; + register int i, i_byte; register unsigned char *completion_string; struct gcpro gcpro1, gcpro2; + int prompt_end_charpos; /* 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 (Fbuffer_string (), + completion = Ftry_completion (Fminibuffer_contents (), Vminibuffer_completion_table, Vminibuffer_completion_predicate); if (NILP (completion)) @@ -1550,7 +1893,7 @@ Return nil if there is no valid completion, else t.") return Qnil; #if 0 /* How the below code used to look, for reference. */ - tem = Fbuffer_string (); + tem = Fminibuffer_contents (); b = XSTRING (tem)->data; i = ZV - 1 - XSTRING (completion)->size; p = XSTRING (completion)->data; @@ -1566,54 +1909,77 @@ Return nil if there is no valid completion, else t.") } #else /* Rewritten code */ { - register unsigned char *buffer_string; - int buffer_length, completion_length; + int buffer_nchars, completion_nchars; - CHECK_STRING (completion, 0); - tem = Fbuffer_string (); + CHECK_STRING (completion); + tem = Fminibuffer_contents (); GCPRO2 (completion, tem); /* If reading a file name, expand any $ENVVAR refs in the buffer and in TEM. */ - if (EQ (Vminibuffer_completion_table, Qread_file_name_internal)) + if (! NILP (Vminibuffer_completing_file_name)) { Lisp_Object substituted; substituted = Fsubstitute_in_file_name (tem); if (! EQ (substituted, tem)) { tem = substituted; - Ferase_buffer (); - insert_from_string (tem, 0, XSTRING (tem)->size, 0); + Fdelete_minibuffer_contents (); + insert_from_string (tem, 0, 0, XSTRING (tem)->size, + STRING_BYTES (XSTRING (tem)), 0); } } - buffer_string = XSTRING (tem)->data; - completion_string = XSTRING (completion)->data; - buffer_length = XSTRING (tem)->size; /* ie ZV - BEGV */ - completion_length = XSTRING (completion)->size; - i = buffer_length - completion_length; - /* Mly: I don't understand what this is supposed to do AT ALL */ - if (i > 0 || - 0 <= scmp (buffer_string, completion_string, buffer_length)) + buffer_nchars = XSTRING (tem)->size; /* ie ZV - BEGV */ + completion_nchars = XSTRING (completion)->size; + i = buffer_nchars - completion_nchars; + if (i > 0 + || + (tem1 = Fcompare_strings (tem, make_number (0), + make_number (buffer_nchars), + completion, make_number (0), + make_number (buffer_nchars), + completion_ignore_case ? Qt : Qnil), + ! EQ (tem1, Qt))) { - /* Set buffer to longest match of buffer tail and completion head. */ + int start_pos; + + /* Set buffer to longest match of buffer tail and completion head. */ if (i <= 0) i = 1; - buffer_string += i; - buffer_length -= i; - while (0 <= scmp (buffer_string++, completion_string, buffer_length--)) - i++; + start_pos= i; + buffer_nchars -= i; + while (i > 0) + { + tem1 = Fcompare_strings (tem, make_number (start_pos), Qnil, + completion, make_number (0), + make_number (buffer_nchars), + completion_ignore_case ? Qt : Qnil); + start_pos++; + if (EQ (tem1, Qt)) + break; + i++; + buffer_nchars--; + } del_range (1, i + 1); - SET_PT (ZV); + SET_PT_BOTH (ZV, ZV_BYTE); } UNGCPRO; } #endif /* Rewritten code */ - i = ZV - BEGV; + + 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; + } /* If completion finds next char not unique, consider adding a space or a hyphen. */ if (i == XSTRING (completion)->size) { GCPRO1 (completion); - tem = Ftry_completion (concat2 (Fbuffer_string (), build_string (" ")), + tem = Ftry_completion (concat2 (Fminibuffer_contents (), build_string (" ")), Vminibuffer_completion_table, Vminibuffer_completion_predicate); UNGCPRO; @@ -1624,7 +1990,7 @@ Return nil if there is no valid completion, else t.") { GCPRO1 (completion); tem = - Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")), + Ftry_completion (concat2 (Fminibuffer_contents (), build_string ("-")), Vminibuffer_completion_table, Vminibuffer_completion_predicate); UNGCPRO; @@ -1638,16 +2004,17 @@ Return nil if there is no valid completion, else t.") i gets index in string of where to stop completing. */ { int len, c; - + int bytes = STRING_BYTES (XSTRING (completion)); completion_string = XSTRING (completion)->data; - for (; i < XSTRING (completion)->size; i += len) + for (; i_byte < STRING_BYTES (XSTRING (completion)); i_byte += len, i++) { - c = STRING_CHAR_AND_LENGTH (completion_string + i, - XSTRING (completion)->size - i, + c = STRING_CHAR_AND_LENGTH (completion_string + i_byte, + bytes - i_byte, len); if (SYNTAX (c) != Sword) { - i += len; + i_byte += len; + i++; break; } } @@ -1655,29 +2022,31 @@ Return nil if there is no valid completion, else t.") /* If got no characters, print help for user. */ - if (i == ZV - BEGV) + if (i == ZV - prompt_end_charpos) { - if (auto_help) + if (!NILP (Vcompletion_auto_help)) Fminibuffer_completion_help (); return Qnil; } /* Otherwise insert in minibuffer the chars we got */ - Ferase_buffer (); - insert_from_string (completion, 0, i, 1); + Fdelete_minibuffer_contents (); + insert_from_string (completion, 0, 0, i, i_byte, 1); return Qt; } DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_list, 1, 1, 0, - "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.\n\ -`standard-output' must be a buffer.\n\ -At the end, run the normal hook `completion-setup-hook'.\n\ -It can find the completion buffer in `standard-output'.") - (completions) + 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. +`standard-output' must be a buffer. +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) Lisp_Object completions; { Lisp_Object tail, elt; @@ -1705,25 +2074,27 @@ It can find the completion buffer in `standard-output'.") write_string ("Possible completions are:", -1); for (tail = completions, i = 0; !NILP (tail); tail = Fcdr (tail), i++) { - Lisp_Object tem; + Lisp_Object tem, string; int length; Lisp_Object startpos, endpos; + startpos = Qnil; + elt = Fcar (tail); /* Compute the length of this element. */ if (CONSP (elt)) { tem = XCAR (elt); - CHECK_STRING (tem, 0); + CHECK_STRING (tem); length = XSTRING (tem)->size; tem = Fcar (XCDR (elt)); - CHECK_STRING (tem, 0); + CHECK_STRING (tem); length += XSTRING (tem)->size; } else { - CHECK_STRING (elt, 0); + CHECK_STRING (elt); length = XSTRING (elt)->size; } @@ -1739,7 +2110,7 @@ It can find the completion buffer in `standard-output'.") don't put another on the same line. */ if (column > 33 || first /* If this is really wide, don't put it second on a line. */ - || column > 0 && length > 45) + || (column > 0 && length > 45)) { Fterpri (Qnil); column = 0; @@ -1771,15 +2142,58 @@ It can find the completion buffer in `standard-output'.") Qnil, Vstandard_output); } - /* Output this element and update COLUMN. */ + /* Output this element. + If necessary, convert it to unibyte or to multibyte first. */ if (CONSP (elt)) + string = Fcar (elt); + else + string = elt; + if (NILP (current_buffer->enable_multibyte_characters) + && STRING_MULTIBYTE (string)) + string = Fstring_make_unibyte (string); + else if (!NILP (current_buffer->enable_multibyte_characters) + && !STRING_MULTIBYTE (string)) + string = Fstring_make_multibyte (string); + + if (BUFFERP (Vstandard_output)) { - Fprinc (Fcar (elt), Qnil); - Fprinc (Fcar (Fcdr (elt)), Qnil); + XSETINT (startpos, BUF_PT (XBUFFER (Vstandard_output))); + + Fprinc (string, Qnil); + + XSETINT (endpos, BUF_PT (XBUFFER (Vstandard_output))); + + Fput_text_property (startpos, endpos, + Qmouse_face, intern ("highlight"), + Vstandard_output); } else - Fprinc (elt, Qnil); + { + Fprinc (string, Qnil); + } + + /* Output the annotation for this element. */ + if (CONSP (elt)) + { + if (BUFFERP (Vstandard_output)) + { + XSETINT (startpos, BUF_PT (XBUFFER (Vstandard_output))); + + Fprinc (Fcar (Fcdr (elt)), Qnil); + XSETINT (endpos, BUF_PT (XBUFFER (Vstandard_output))); + + Fset_text_properties (startpos, endpos, Qnil, + Vstandard_output); + } + else + { + Fprinc (Fcar (Fcdr (elt)), Qnil); + } + } + + + /* Update COLUMN for what we have output. */ column += length; /* If output is to a buffer, recompute COLUMN in a way @@ -1806,18 +2220,18 @@ It can find the completion buffer in `standard-output'.") } DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_completion_help, - 0, 0, "", - "Display a list of possible completions of the current minibuffer contents.") - () + 0, 0, "", + doc: /* Display a list of possible completions of the current minibuffer contents. */) + () { Lisp_Object completions; message ("Making completion list..."); - completions = Fall_completions (Fbuffer_string (), + completions = Fall_completions (Fminibuffer_contents (), Vminibuffer_completion_table, Vminibuffer_completion_predicate, Qt); - echo_area_glyphs = 0; + clear_message (1, 0); if (NILP (completions)) { @@ -1832,48 +2246,39 @@ DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_co } DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0, 0, "", - "Terminate minibuffer input.") - () + doc: /* Terminate minibuffer input. */) + () { if (INTEGERP (last_command_char)) - internal_self_insert (last_command_char, 0); + internal_self_insert (XINT (last_command_char), 0); else bitch_at_user (); - Fthrow (Qexit, Qnil); + return Fthrow (Qexit, Qnil); } DEFUN ("exit-minibuffer", Fexit_minibuffer, Sexit_minibuffer, 0, 0, "", - "Terminate this minibuffer argument.") - () + doc: /* Terminate this minibuffer argument. */) + () { - Fthrow (Qexit, Qnil); + return Fthrow (Qexit, Qnil); } DEFUN ("minibuffer-depth", Fminibuffer_depth, Sminibuffer_depth, 0, 0, 0, - "Return current depth of activations of minibuffer, a nonnegative integer.") - () + doc: /* Return current depth of activations of minibuffer, a nonnegative integer. */) + () { return make_number (minibuf_level); } DEFUN ("minibuffer-prompt", Fminibuffer_prompt, Sminibuffer_prompt, 0, 0, 0, - "Return the prompt string of the currently-active minibuffer.\n\ -If no minibuffer is active, return nil.") - () + doc: /* Return the prompt string of the currently-active minibuffer. +If no minibuffer is active, return nil. */) + () { return Fcopy_sequence (minibuf_prompt); } -DEFUN ("minibuffer-prompt-width", Fminibuffer_prompt_width, - Sminibuffer_prompt_width, 0, 0, 0, - "Return the display width of the minibuffer prompt.") - () -{ - Lisp_Object width; - XSETFASTINT (width, minibuf_prompt_width); - return width; -} /* Temporarily display the string M at the end of the current minibuffer contents. This is used to display things like @@ -1881,24 +2286,27 @@ DEFUN ("minibuffer-prompt-width", Fminibuffer_prompt_width, that has no possible completions, and other quick, unobtrusive messages. */ +void temp_echo_area_glyphs (m) char *m; { int osize = ZV; + int osize_byte = ZV_BYTE; int opoint = PT; + int opoint_byte = PT_BYTE; Lisp_Object oinhibit; oinhibit = Vinhibit_quit; /* Clear out any old echo-area message to make way for our new thing. */ message (0); - SET_PT (osize); + SET_PT_BOTH (osize, osize_byte); insert_string (m); - SET_PT (opoint); + SET_PT_BOTH (opoint, opoint_byte); Vinhibit_quit = Qt; Fsit_for (make_number (2), Qnil, Qnil); - del_range (osize, ZV); - SET_PT (opoint); + del_range_both (osize, osize_byte, ZV, ZV_BYTE, 1); + SET_PT_BOTH (opoint, opoint_byte); if (!NILP (Vquit_flag)) { Vquit_flag = Qnil; @@ -1908,23 +2316,25 @@ temp_echo_area_glyphs (m) } DEFUN ("minibuffer-message", Fminibuffer_message, Sminibuffer_message, - 1, 1, 0, - "Temporarily display STRING at the end of the minibuffer.\n\ -The text is displayed for two seconds,\n\ -or until the next input event arrives, whichever comes first.") - (string) + 1, 1, 0, + doc: /* Temporarily display STRING at the end of the minibuffer. +The text is displayed for two seconds, +or until the next input event arrives, whichever comes first. */) + (string) Lisp_Object string; { temp_echo_area_glyphs (XSTRING (string)->data); return Qnil; } +void init_minibuf_once () { Vminibuffer_list = Qnil; staticpro (&Vminibuffer_list); } +void syms_of_minibuf () { minibuf_level = 0; @@ -1962,6 +2372,10 @@ syms_of_minibuf () Qminibuffer_history = intern ("minibuffer-history"); staticpro (&Qminibuffer_history); + Qbuffer_name_history = intern ("buffer-name-history"); + staticpro (&Qbuffer_name_history); + Fset (Qbuffer_name_history, Qnil); + Qminibuffer_setup_hook = intern ("minibuffer-setup-hook"); staticpro (&Qminibuffer_setup_hook); @@ -1977,91 +2391,107 @@ syms_of_minibuf () Qactivate_input_method = intern ("activate-input-method"); staticpro (&Qactivate_input_method); - DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook, - "Normal hook run just after entry to minibuffer."); + 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 ("minibuffer-setup-hook", &Vminibuffer_setup_hook, + doc: /* Normal hook run just after entry to minibuffer. */); Vminibuffer_setup_hook = Qnil; DEFVAR_LISP ("minibuffer-exit-hook", &Vminibuffer_exit_hook, - "Normal hook run just after exit from minibuffer."); + doc: /* Normal hook run just after exit from minibuffer. */); Vminibuffer_exit_hook = Qnil; DEFVAR_LISP ("history-length", &Vhistory_length, - "*Maximum length for history lists before truncation takes place.\n\ -A number means that length; t means infinite. Truncation takes place\n\ -just after a new element is inserted. Setting the history-length\n\ -property of a history variable overrides this default."); + 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 +property of a history variable overrides this default. */); XSETFASTINT (Vhistory_length, 30); - DEFVAR_BOOL ("completion-auto-help", &auto_help, - "*Non-nil means automatically provide help for invalid completion input."); - auto_help = 1; + DEFVAR_LISP ("completion-auto-help", &Vcompletion_auto_help, + doc: /* *Non-nil means automatically provide help for invalid completion input. */); + Vcompletion_auto_help = Qt; DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case, - "Non-nil means don't consider case significant in completion."); + doc: /* Non-nil means don't consider case significant in completion. */); completion_ignore_case = 0; DEFVAR_BOOL ("enable-recursive-minibuffers", &enable_recursive_minibuffers, - "*Non-nil means to allow minibuffer commands while in the minibuffer.\n\ -More precisely, this variable makes a difference when the minibuffer window\n\ -is the selected window. If you are in some other window, minibuffer commands\n\ -are allowed even if a minibuffer is active."); + doc: /* *Non-nil means to allow minibuffer commands while in the minibuffer. +This variable makes a difference whenever the minibuffer window is active. */); enable_recursive_minibuffers = 0; DEFVAR_LISP ("minibuffer-completion-table", &Vminibuffer_completion_table, - "Alist or obarray used for completion in the minibuffer.\n\ -This becomes the ALIST argument to `try-completion' and `all-completion'.\n\ -\n\ -The value may alternatively be a function, which is given three arguments:\n\ - STRING, the current buffer contents;\n\ - PREDICATE, the predicate for filtering possible matches;\n\ - CODE, which says what kind of things to do.\n\ -CODE can be nil, t or `lambda'.\n\ -nil means to return the best completion of STRING, or nil if there is none.\n\ -t means to return a list of all possible completions of STRING.\n\ -`lambda' means to return t if STRING is a valid completion as it stands."); + doc: /* Alist or obarray used for completion in the minibuffer. +This becomes the ALIST argument to `try-completion' and `all-completion'. + +The value may alternatively be a function, which is given three arguments: + STRING, the current buffer contents; + PREDICATE, the predicate for filtering possible matches; + CODE, which says what kind of things to do. +CODE can be nil, t or `lambda'. +nil means to return the best completion of STRING, or nil if there is none. +t means to return a list of all possible completions of STRING. +`lambda' means to return t if STRING is a valid completion as it stands. */); Vminibuffer_completion_table = Qnil; DEFVAR_LISP ("minibuffer-completion-predicate", &Vminibuffer_completion_predicate, - "Within call to `completing-read', this holds the PREDICATE argument."); + doc: /* Within call to `completing-read', this holds the PREDICATE argument. */); Vminibuffer_completion_predicate = Qnil; DEFVAR_LISP ("minibuffer-completion-confirm", &Vminibuffer_completion_confirm, - "Non-nil => demand confirmation of completion before exiting minibuffer."); + doc: /* Non-nil => demand confirmation of completion before exiting minibuffer. */); Vminibuffer_completion_confirm = Qnil; + DEFVAR_LISP ("minibuffer-completing-file-name", + &Vminibuffer_completing_file_name, + doc: /* Non-nil means completing file names. */); + Vminibuffer_completing_file_name = Qnil; + DEFVAR_LISP ("minibuffer-help-form", &Vminibuffer_help_form, - "Value that `help-form' takes on inside the minibuffer."); + doc: /* 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 string of minibuffer input, as it appears on exit from the minibuffer,\n\ -is added with\n\ - (set minibuffer-history-variable\n\ - (cons STRING (symbol-value minibuffer-history-variable)))"); + doc: /* History list symbol to add minibuffer values to. +Each string of minibuffer input, as it appears on exit from the minibuffer, +is added with + (set minibuffer-history-variable + (cons STRING (symbol-value minibuffer-history-variable))) */); XSETFASTINT (Vminibuffer_history_variable, 0); DEFVAR_LISP ("minibuffer-history-position", &Vminibuffer_history_position, - "Current position of redoing in the history list."); + doc: /* Current position of redoing in the history list. */); Vminibuffer_history_position = Qnil; DEFVAR_BOOL ("minibuffer-auto-raise", &minibuffer_auto_raise, - "*Non-nil means entering the minibuffer raises the minibuffer's frame.\n\ -Some uses of the echo area also raise that frame (since they use it too)."); + doc: /* *Non-nil means entering the minibuffer raises the minibuffer's frame. +Some uses of the echo area also raise that frame (since they use it too). */); minibuffer_auto_raise = 0; DEFVAR_LISP ("completion-regexp-list", &Vcompletion_regexp_list, - "List of regexps that should restrict possible completions."); + doc: /* List of regexps that should restrict possible completions. */); Vcompletion_regexp_list = Qnil; DEFVAR_BOOL ("minibuffer-allow-text-properties", &minibuffer_allow_text_properties, - "Non-nil means `read-from-miniffer' should not discard text properties.\n\ -This also affects `read-string', but it does not affect `read-minibuffer',\n\ -`read-no-blanks-input', or any of the functions that do minibuffer input\n\ -with completion; they always discard text properties."); + doc: /* Non-nil means `read-from-minibuffer' should not discard text properties. +This also affects `read-string', but it does not affect `read-minibuffer', +`read-no-blanks-input', or any of the functions that do minibuffer input +with completion; they always discard text properties. */); minibuffer_allow_text_properties = 0; + DEFVAR_LISP ("minibuffer-prompt-properties", &Vminibuffer_prompt_properties, + doc: /* Text properties that are added to minibuffer prompts. +These are in addition to the basic `field' property, and stickiness +properties. */); + /* We use `intern' here instead of Qread_only to avoid + initialization-order problems. */ + Vminibuffer_prompt_properties + = Fcons (intern ("read-only"), Fcons (Qt, Qnil)); + defsubr (&Sset_minibuffer_window); defsubr (&Sread_from_minibuffer); defsubr (&Seval_minibuffer); @@ -2073,7 +2503,11 @@ with completion; they always discard text properties."); defsubr (&Sread_no_blanks_input); defsubr (&Sminibuffer_depth); defsubr (&Sminibuffer_prompt); - defsubr (&Sminibuffer_prompt_width); + + defsubr (&Sminibuffer_prompt_end); + defsubr (&Sminibuffer_contents); + defsubr (&Sminibuffer_contents_no_properties); + defsubr (&Sdelete_minibuffer_contents); defsubr (&Stry_completion); defsubr (&Sall_completions); @@ -2090,6 +2524,7 @@ with completion; they always discard text properties."); defsubr (&Sminibuffer_message); } +void keys_of_minibuf () { initial_define_key (Vminibuffer_local_map, Ctl ('g'), @@ -2099,13 +2534,6 @@ keys_of_minibuf () initial_define_key (Vminibuffer_local_map, Ctl ('j'), "exit-minibuffer"); - initial_define_key (Vminibuffer_local_ns_map, Ctl ('g'), - "abort-recursive-edit"); - initial_define_key (Vminibuffer_local_ns_map, Ctl ('m'), - "exit-minibuffer"); - initial_define_key (Vminibuffer_local_ns_map, Ctl ('j'), - "exit-minibuffer"); - initial_define_key (Vminibuffer_local_ns_map, ' ', "exit-minibuffer"); initial_define_key (Vminibuffer_local_ns_map, '\t', @@ -2113,13 +2541,6 @@ keys_of_minibuf () initial_define_key (Vminibuffer_local_ns_map, '?', "self-insert-and-exit"); - initial_define_key (Vminibuffer_local_completion_map, Ctl ('g'), - "abort-recursive-edit"); - initial_define_key (Vminibuffer_local_completion_map, Ctl ('m'), - "exit-minibuffer"); - initial_define_key (Vminibuffer_local_completion_map, Ctl ('j'), - "exit-minibuffer"); - initial_define_key (Vminibuffer_local_completion_map, '\t', "minibuffer-complete"); initial_define_key (Vminibuffer_local_completion_map, ' ', @@ -2127,16 +2548,8 @@ keys_of_minibuf () initial_define_key (Vminibuffer_local_completion_map, '?', "minibuffer-completion-help"); - initial_define_key (Vminibuffer_local_must_match_map, Ctl ('g'), - "abort-recursive-edit"); 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"); - initial_define_key (Vminibuffer_local_must_match_map, '\t', - "minibuffer-complete"); - initial_define_key (Vminibuffer_local_must_match_map, ' ', - "minibuffer-complete-word"); - initial_define_key (Vminibuffer_local_must_match_map, '?', - "minibuffer-completion-help"); }