X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/18160b98ce2ce9f534a4aee6be181788322b6c01..19c4018eff6a9effc88578e8b3de26a82c3a85e6:/src/minibuf.c diff --git a/src/minibuf.c b/src/minibuf.c index b01d728864..c3209e6f93 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -29,6 +29,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define min(a, b) ((a) < (b) ? (a) : (b)) +extern int quit_char; + /* List of buffers for use as minibuffers. The first element of the list is used for the outermost minibuffer invocation, the next element is used for a recursive minibuffer invocation, etc. @@ -54,7 +56,7 @@ int minibuf_level; /* Nonzero means display completion help for invalid input */ int auto_help; -/* Fread_minibuffer leaves the input, as a string, here */ +/* Fread_minibuffer leaves the input here as a string. */ Lisp_Object last_minibuf_string; /* Nonzero means let functions called when within a minibuffer @@ -85,13 +87,17 @@ Lisp_Object Qminibuffer_setup_hook, Vminibuffer_setup_hook; int completion_ignore_case; +/* Nonzero means raise the minibuffer frame when the minibuffer + is entered. */ + +int minibuffer_auto_raise; + /* If last completion attempt reported "Complete but not unique" then this is the string completed then; otherwise this is nil. */ static Lisp_Object last_exact_completion; Lisp_Object Quser_variable_p; - /* Actual minibuffer invocation. */ @@ -105,7 +111,11 @@ Lisp_Object read_minibuf (); with initial position HISTPOS. (BACKUP_N should be <= 0.) Normally return the result as a string (the text that was read), - but if EXPFLAG is non-nil, read it and return the object read. */ + but if EXPFLAG is non-nil, read it and return the object read. + If HISTVAR is given, save the value read on that history only if it doesn't + match the front of that history list exactly. The value is pushed onto + the list as the string that was read, or as the object that resulted iff + EXPFLAG is non-nil. */ Lisp_Object read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos) @@ -164,6 +174,13 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos) if (XFRAME (mini_frame) != selected_frame) record_unwind_protect (Fset_window_configuration, Fcurrent_window_configuration (mini_frame)); + + /* If the minibuffer is on an iconified or invisible frame, + make it visible now. */ + Fmake_frame_visible (mini_frame); + + if (minibuffer_auto_raise) + Fraise_frame (mini_frame); #endif val = current_buffer->directory; @@ -232,7 +249,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos) /* 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. */ - if (!NILP (Vminibuffer_setup_hook) && !EQ (Vminibuffer_setup_hook, Qunbound)) + if (!NILP (Vminibuffer_setup_hook) && !EQ (Vminibuffer_setup_hook, Qunbound) + && !NILP (Vrun_hooks)) call1 (Vrun_hooks, Qminibuffer_setup_hook); /* ??? MCC did redraw_screen here if switching screens. */ @@ -252,24 +270,46 @@ read_minibuf (map, initial, prompt, backup_n, expflag, histvar, histpos) val = make_buffer_string (1, Z); bcopy (GAP_END_ADDR, XSTRING (val)->data + GPT - BEG, Z - GPT); + /* VAL is the string of minibuffer text. */ + last_minibuf_string = val; + /* Add the value to the appropriate history list. */ if (XTYPE (Vminibuffer_history_variable) == Lisp_Symbol && ! EQ (XSYMBOL (Vminibuffer_history_variable)->value, Qunbound)) - Fset (Vminibuffer_history_variable, - Fcons (val, Fsymbol_value (Vminibuffer_history_variable))); + { + /* 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; + histval = Fsymbol_value (Vminibuffer_history_variable); + + /* The value of the history variable must be a cons or nil. Other + values are unacceptable. We silently ignore these values. */ + if (NILP (histval) + || (CONSP (histval) + && NILP (Fequal (last_minibuf_string, Fcar (histval))))) + Fset (Vminibuffer_history_variable, + Fcons (last_minibuf_string, histval)); + } + + /* 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); + } unbind_to (count, Qnil); /* The appropriate frame will get selected in set-window-configuration. */ UNGCPRO; - /* VAL is the string of minibuffer text. */ - last_minibuf_string = val; - - /* If Lisp form desired instead of string, parse it */ - if (expflag) - val = Fread (val); - return val; } @@ -282,7 +322,7 @@ get_minibuffer (depth) int depth; { Lisp_Object tail, num, buf; - char name[14]; + char name[24]; extern Lisp_Object nconc2 (); XFASTINT (num) = depth; @@ -370,27 +410,27 @@ Fifth arg HIST, if non-nil, specifies a history list\n\ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 5, 0, 0 /* See immediately above */) - (prompt, initial_input, keymap, read, hist) - Lisp_Object prompt, initial_input, keymap, read, hist; + (prompt, initial_contents, keymap, read, hist) + Lisp_Object prompt, initial_contents, keymap, read, hist; { int pos = 0; Lisp_Object histvar, histpos, position; position = Qnil; CHECK_STRING (prompt, 0); - if (!NILP (initial_input)) + if (!NILP (initial_contents)) { - if (XTYPE (initial_input) == Lisp_Cons) + if (XTYPE (initial_contents) == Lisp_Cons) { - position = Fcdr (initial_input); - initial_input = Fcar (initial_input); + position = Fcdr (initial_contents); + initial_contents = Fcar (initial_contents); } - CHECK_STRING (initial_input, 1); + CHECK_STRING (initial_contents, 1); if (!NILP (position)) { CHECK_NUMBER (position, 0); /* Convert to distance from end of input. */ - pos = XINT (position) - 1 - XSTRING (initial_input)->size; + pos = XINT (position) - 1 - XSTRING (initial_contents)->size; } } @@ -414,7 +454,7 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, if (NILP (histpos)) XFASTINT (histpos) = 0; - return read_minibuf (keymap, initial_input, prompt, + return read_minibuf (keymap, initial_contents, prompt, make_number (pos), !NILP (read), histvar, histpos); } @@ -453,7 +493,7 @@ If non-nil second arg INITIAL-INPUT is a string to insert before reading.") return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil, Qnil); } -DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 2, 2, 0, +DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 1, 2, 0, "Args PROMPT and INIT, strings. Read a string from the terminal, not allowing blanks.\n\ Prompt with PROMPT, and provide INIT as an initial value of the input string.") (prompt, init) @@ -802,11 +842,14 @@ The argument given to PREDICATE is the alist element or the symbol from the obar /* Is this element a possible completion? */ - if (XTYPE (eltstring) == Lisp_String && - XSTRING (string)->size <= XSTRING (eltstring)->size && - XSTRING (eltstring)->data[0] != ' ' && - 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data, - XSTRING (string)->size)) + if (XTYPE (eltstring) == Lisp_String + && XSTRING (string)->size <= XSTRING (eltstring)->size + /* Reject alternatives that start with space + unless the input starts with space. */ + && ((XSTRING (string)->size > 0 && XSTRING (string)->data[0] == ' ') + || XSTRING (eltstring)->data[0] != ' ') + && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data, + XSTRING (string)->size)) { /* Yes. */ /* Ignore this element if there is a predicate @@ -943,7 +986,7 @@ temp_echo_area_glyphs (m) if (!NILP (Vquit_flag)) { Vquit_flag = Qnil; - unread_command_events = Fcons (make_number (Ctl ('g')), Qnil); + unread_command_events = Fcons (make_number (quit_char), Qnil); } Vinhibit_quit = oinhibit; } @@ -1071,7 +1114,8 @@ assoc_for_completion (key, list) } DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "", - "Complete the minibuffer contents as far as possible.") + "Complete the minibuffer contents as far as possible.\n\ +Return nil if there is no valid completion, else t.") () { register int i = do_completion (); @@ -1134,15 +1178,17 @@ DEFUN ("minibuffer-complete-word", Fminibuffer_complete_word, Sminibuffer_comple 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.") +is added, provided that matches some possible completion.\n\ +Return nil if there is no valid completion, else t.") () { Lisp_Object completion, tem; register int i; register unsigned char *completion_string; - /* We keep calling Fbuffer_string - rather than arrange for GC to hold onto a pointer to - one of the strings thus made. */ + struct gcpro gcpro1; + + /* 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 (), Vminibuffer_completion_table, @@ -1156,7 +1202,7 @@ is added, provided that matches some possible completion.") if (EQ (completion, Qt)) return Qnil; -#if 0 /* How the below code used to look, for reference */ +#if 0 /* How the below code used to look, for reference. */ tem = Fbuffer_string (); b = XSTRING (tem)->data; i = ZV - 1 - XSTRING (completion)->size; @@ -1187,7 +1233,7 @@ is added, provided that matches some possible completion.") { tem = substituted; Ferase_buffer (); - insert_from_string (tem, 0, XSTRING (tem)->size); + insert_from_string (tem, 0, XSTRING (tem)->size, 0); } } buffer_string = XSTRING (tem)->data; @@ -1213,19 +1259,26 @@ is added, provided that matches some possible completion.") i = ZV - BEGV; /* If completion finds next char not unique, - consider adding a space or a hyphen */ + consider adding a space or a hyphen. */ if (i == XSTRING (completion)->size) { + GCPRO1 (completion); tem = Ftry_completion (concat2 (Fbuffer_string (), build_string (" ")), Vminibuffer_completion_table, Vminibuffer_completion_predicate); + UNGCPRO; + if (XTYPE (tem) == Lisp_String) completion = tem; else { - tem = Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")), - Vminibuffer_completion_table, - Vminibuffer_completion_predicate); + GCPRO1 (completion); + tem = + Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")), + Vminibuffer_completion_table, + Vminibuffer_completion_predicate); + UNGCPRO; + if (XTYPE (tem) == Lisp_String) completion = tem; } @@ -1233,6 +1286,7 @@ is added, provided that matches some possible completion.") /* Now find first word-break in the stuff found by completion. i gets index in string of where to stop completing. */ + completion_string = XSTRING (completion)->data; for (; i < XSTRING (completion)->size; i++) @@ -1252,7 +1306,7 @@ is added, provided that matches some possible completion.") /* Otherwise insert in minibuffer the chars we got */ Ferase_buffer (); - insert_from_string (completion, 0, i); + insert_from_string (completion, 0, i, 1); return Qt; } @@ -1260,7 +1314,10 @@ DEFUN ("display-completion-list", Fdisplay_completion_list, Sdisplay_completion_ 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.") +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) Lisp_Object completions; { @@ -1331,11 +1388,12 @@ or may be a list of two strings to be printed as if concatenated.") } } + if (XTYPE (Vstandard_output) == Lisp_Buffer) + set_buffer_internal (old); + if (!NILP (Vrun_hooks)) call1 (Vrun_hooks, intern ("completion-setup-hook")); - if (XTYPE (Vstandard_output) == Lisp_Buffer) - set_buffer_internal (old); return Qnil; } @@ -1484,6 +1542,10 @@ Each minibuffer output is added with\n\ "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."); + minibuffer_auto_raise = 0; + defsubr (&Sread_from_minibuffer); defsubr (&Seval_minibuffer); defsubr (&Sread_minibuffer);