Mercurial > hg > xemacs-beta
diff src/minibuf.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 9ee227acff29 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/minibuf.c Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,920 @@ +/* Minibuffer input and completion. + Copyright (C) 1985, 1986, 1992-1995 Free Software Foundation, Inc. + Copyright (C) 1995 Sun Microsystems, Inc. + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Synched up with: Mule 2.0, FSF 19.28. Mule-ized except as noted. + Substantially different from FSF. */ + +#include <config.h> +#include "lisp.h" + +#include "buffer.h" +#include "commands.h" +#include "console-stream.h" +#include "events.h" +#include "frame.h" +#include "insdel.h" +#include "redisplay.h" +#include "window.h" + +/* Depth in minibuffer invocations. */ +int minibuf_level; + +Lisp_Object Qcompletion_ignore_case; + +/* Nonzero means completion ignores case. */ +int completion_ignore_case; + +/* List of regexps that should restrict possible completions. */ +Lisp_Object Vcompletion_regexp_list; + +/* The echo area buffer. */ +Lisp_Object Vecho_area_buffer; + +/* Prompt to display in front of the minibuffer contents */ +Lisp_Object Vminibuf_prompt; + +/* Hook to run just after entry to minibuffer. */ +Lisp_Object Qminibuffer_setup_hook, Vminibuffer_setup_hook; + +Lisp_Object Qappend_message, Qcurrent_message_label, + Qclear_message, Qdisplay_message; + + +DEFUN ("minibuffer-depth", Fminibuffer_depth, Sminibuffer_depth, 0, 0, 0 /* +Return current depth of activations of minibuffer, a nonnegative integer. +*/ ) + () +{ + return make_int (minibuf_level); +} + +/* The default buffer to use as the window-buffer of minibuffer windows */ +/* Note there is special code in kill-buffer to make this unkillable */ +Lisp_Object Vminibuffer_zero; + + +/* Actual minibuffer invocation. */ + +static Lisp_Object +read_minibuffer_internal_unwind (Lisp_Object unwind_data) +{ + Lisp_Object frame; + XWINDOW (minibuf_window)->last_modified[CURRENT_DISP] = Qzero; + XWINDOW (minibuf_window)->last_modified[DESIRED_DISP] = Qzero; + XWINDOW (minibuf_window)->last_modified[CMOTION_DISP] = Qzero; + XWINDOW (minibuf_window)->last_facechange[CURRENT_DISP] = Qzero; + XWINDOW (minibuf_window)->last_facechange[DESIRED_DISP] = Qzero; + XWINDOW (minibuf_window)->last_facechange[CMOTION_DISP] = Qzero; + Vminibuf_prompt = Felt (unwind_data, Qzero); + minibuf_level = XINT (Felt (unwind_data, make_int (1))); + while (CONSP (unwind_data)) + { + Lisp_Object victim = unwind_data; + unwind_data = XCDR (unwind_data); + free_cons (XCONS (victim)); + } + + /* If cursor is on the minibuffer line, + show the user we have exited by putting it in column 0. */ + frame = Fselected_frame (Qnil); + if (!noninteractive + && !NILP (frame) + && !NILP (XFRAME (frame)->minibuffer_window)) + { + struct window *w = XWINDOW (XFRAME (frame)->minibuffer_window); + redisplay_move_cursor (w, 0, 0); + } + + return Qnil; +} + +DEFUN ("read-minibuffer-internal", + Fread_minibuffer_internal, Sread_minibuffer_internal, + 1, 1, 0 /* +Lowest-level interface to minibuffers. Don't call this. +*/ ) + (prompt) + Lisp_Object prompt; +{ + /* This function can GC */ + int speccount = specpdl_depth (); + Lisp_Object val; + + CHECK_STRING (prompt); + + single_console_state (); + + record_unwind_protect (read_minibuffer_internal_unwind, + noseeum_cons + (Vminibuf_prompt, + noseeum_cons (make_int (minibuf_level), Qnil))); + Vminibuf_prompt = LISP_GETTEXT (prompt); + + /* NOTE: Here (or somewhere around here), in FSFmacs 19.30, + choose_minibuf_frame() is called. This is the only + place in FSFmacs that it's called any more -- there's + also a call in xterm.c, but commented out, and 19.28 + had the calls in different places. + + choose_minibuf_frame() does the following: + + if (!EQ (minibuf_window, selected_frame()->minibuffer_window)) + { + Fset_window_buffer (selected_frame()->minibuffer_window, + XWINDOW (minibuf_window)->buffer); + minibuf_window = selected_frame()->minibuffer_window; + } + + #### Note that we don't do the set-window-buffer. This call is + similar, but not identical, to a set-window-buffer call made + in `read-from-minibuffer' in minibuf.el. I hope it's close + enough, because minibuf_window isn't really exported to Lisp. + + The comment above choose_minibuf_frame() reads: + + Put minibuf on currently selected frame's minibuffer. + We do this whenever the user starts a new minibuffer + or when a minibuffer exits. */ + + minibuf_window = FRAME_MINIBUF_WINDOW (selected_frame ()); + + run_hook (Qminibuffer_setup_hook); + + minibuf_level++; + clear_echo_area (selected_frame (), Qnil, 0); + + val = call_command_loop (Qt); + + return (unbind_to (speccount, val)); +} + + + +/* Completion hair */ + +/* Compare exactly LEN chars of strings at S1 and S2, + ignoring case if appropriate. + Return -1 if strings match, + else number of chars that match at the beginning. */ + +/* Note that this function works in Charcounts, unlike most functions. + This is necessary for many reasons, one of which is that two + strings may match even if they have different numbers of bytes, + if IGNORE_CASE is true. */ + +Charcount +scmp_1 (CONST Bufbyte *s1, CONST Bufbyte *s2, Charcount len, + int ignore_case) +{ + Charcount l = len; + + if (ignore_case) + { + while (l) + { + Bufbyte c1 = DOWNCASE (current_buffer, charptr_emchar (s1)); + Bufbyte c2 = DOWNCASE (current_buffer, charptr_emchar (s2)); + + if (c1 == c2) + { + l--; + INC_CHARPTR (s1); + INC_CHARPTR (s2); + } + else + break; + } + } + else + { + while (l && charptr_emchar (s1) == charptr_emchar (s2)) + { + l--; + INC_CHARPTR (s1); + INC_CHARPTR (s2); + } + } + + if (l == 0) + return -1; + else return len - l; +} + + +int +regexp_ignore_completion_p (CONST Bufbyte *nonreloc, + Lisp_Object reloc, Bytecount offset, + Bytecount length) +{ + /* Ignore this element if it fails to match all the regexps. */ + if (!NILP (Vcompletion_regexp_list)) + { + Lisp_Object regexps; + for (regexps = Vcompletion_regexp_list; + CONSP (regexps); + regexps = XCDR (regexps)) + { + Lisp_Object re = XCAR (regexps); + if (STRINGP (re) + && (fast_string_match (re, nonreloc, reloc, offset, + length, 0, ERROR_ME, 0) >= 0)) + return (1); + } + } + return (0); +} + + +/* Callers should GCPRO, since this may call eval */ +static int +ignore_completion_p (Lisp_Object completion_string, + Lisp_Object pred, Lisp_Object completion) +{ + if (regexp_ignore_completion_p (0, completion_string, 0, -1)) + return (1); + + /* Ignore this element if there is a predicate + and the predicate doesn't like it. */ + if (!NILP (pred)) + { + Lisp_Object tem; + if (EQ (pred, Qcommandp)) + tem = Fcommandp (completion); + else + tem = call1 (pred, completion); + if (NILP (tem)) + return (1); + } + return (0); +} + + + + +DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0 /* +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 an exact match, 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. +*/ ) + (string, alist, pred) + Lisp_Object string, alist, pred; +{ + /* This function can GC */ + Lisp_Object bestmatch, tail; + Charcount bestmatchsize = 0; + int list; + int indice = 0; + int obsize = 0; + int matchcount = 0; + Lisp_Object bucket; + Charcount slength, blength; + + CHECK_STRING (string); + + if (CONSP (alist)) + { + Lisp_Object tem = XCAR (alist); + if (SYMBOLP (tem)) /* lambda, autoload, etc. Emacs-lisp sucks */ + return call3 (alist, string, pred, Qnil); + else + list = 1; + } + else if (VECTORP (alist)) + list = 0; + else if (NILP (alist)) + list = 1; + else + return call3 (alist, string, pred, Qnil); + + bestmatch = Qnil; + blength = 0; + slength = string_char_length (XSTRING (string)); + + /* If ALIST is not a list, set TAIL just for gc pro. */ + tail = alist; + if (!list) + { + obsize = vector_length (XVECTOR (alist)); + bucket = vector_data (XVECTOR (alist))[indice]; + } + + while (1) + { + /* Get the next element of the alist or obarray. */ + /* Exit the loop if the elements are all used up. */ + /* elt gets the alist element or symbol. + eltstring gets the name to check as a completion. */ + Lisp_Object elt; + Lisp_Object eltstring; + + if (list) + { + if (NILP (tail)) + break; + elt = Fcar (tail); + eltstring = Fcar (elt); + tail = Fcdr (tail); + } + else + { + if (!ZEROP (bucket)) + { + struct Lisp_Symbol *next = symbol_next (XSYMBOL (bucket)); + elt = bucket; + eltstring = Fsymbol_name (elt); + if (next) + XSETSYMBOL (bucket, next); + else + bucket = Qzero; + } + else if (++indice >= obsize) + break; + else + { + bucket = vector_data (XVECTOR (alist))[indice]; + continue; + } + } + + /* Is this element a possible completion? */ + + if (STRINGP (eltstring)) + { + Charcount eltlength = string_char_length (XSTRING (eltstring)); + if (slength <= eltlength + && (0 > scmp (string_data (XSTRING (eltstring)), + string_data (XSTRING (string)), + slength))) + { + { + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + int loser; + GCPRO4 (tail, string, eltstring, bestmatch); + loser = ignore_completion_p (eltstring, pred, elt); + UNGCPRO; + if (loser) /* reject this one */ + continue; + } + + /* Update computation of how much all possible + completions match */ + + matchcount++; + if (NILP (bestmatch)) + { + bestmatch = eltstring; + blength = eltlength; + bestmatchsize = eltlength; + } + else + { + Charcount compare = min (bestmatchsize, eltlength); + Charcount matchsize = + scmp (string_data (XSTRING (bestmatch)), + string_data (XSTRING (eltstring)), + compare); + if (matchsize < 0) + matchsize = compare; + if (completion_ignore_case) + { + /* If this is an exact match except for case, + use it as the best match rather than one that is not + an exact match. This way, we get the case pattern + of the actual match. */ + if ((matchsize == eltlength + && matchsize < blength) + || + /* If there is more than one exact match ignoring + case, and one of them is exact including case, + prefer that one. */ + /* If there is no exact match ignoring case, + prefer a match that does not change the case + of the input. */ + ((matchsize == eltlength) + == + (matchsize == blength) + && 0 > scmp_1 (string_data (XSTRING (eltstring)), + string_data (XSTRING (string)), + slength, 0) + && 0 <= scmp_1 (string_data (XSTRING (bestmatch)), + string_data (XSTRING (string)), + slength, 0))) + { + bestmatch = eltstring; + blength = eltlength; + } + } + bestmatchsize = matchsize; + } + } + } + } + + if (NILP (bestmatch)) + return Qnil; /* No completions found */ + /* If we are ignoring case, and there is no exact match, + and no additional text was supplied, + don't change the case of what the user typed. */ + if (completion_ignore_case + && bestmatchsize == slength + && blength > bestmatchsize) + return string; + + /* 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 == slength + && 0 > scmp_1 (string_data (XSTRING (bestmatch)), + string_data (XSTRING (string)), + bestmatchsize, 0)) + return Qt; + + /* Else extract the part in which all completions agree */ + return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize)); +} + + +DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 3, 0 /* +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. +*/ ) + (string, alist, pred) + Lisp_Object string, alist, pred; +{ + /* This function can GC */ + Lisp_Object tail; + Lisp_Object allmatches; + int list; + int indice = 0; + int obsize = 0; + Lisp_Object bucket; + Charcount slength; + + CHECK_STRING (string); + + if (CONSP (alist)) + { + Lisp_Object tem = XCAR (alist); + if (SYMBOLP (tem)) /* lambda, autoload, etc. Emacs-lisp sucks */ + return call3 (alist, string, pred, Qt); + else + list = 1; + } + else if (VECTORP (alist)) + list = 0; + else if (NILP (alist)) + list = 1; + else + return call3 (alist, string, pred, Qt); + + allmatches = Qnil; + slength = string_char_length (XSTRING (string)); + + /* If ALIST is not a list, set TAIL just for gc pro. */ + tail = alist; + if (!list) + { + obsize = vector_length (XVECTOR (alist)); + bucket = vector_data (XVECTOR (alist))[indice]; + } + + while (1) + { + /* Get the next element of the alist or obarray. */ + /* Exit the loop if the elements are all used up. */ + /* elt gets the alist element or symbol. + eltstring gets the name to check as a completion. */ + Lisp_Object elt; + Lisp_Object eltstring; + + if (list) + { + if (NILP (tail)) + break; + elt = Fcar (tail); + eltstring = Fcar (elt); + tail = Fcdr (tail); + } + else + { + if (!ZEROP (bucket)) + { + struct Lisp_Symbol *next = symbol_next (XSYMBOL (bucket)); + elt = bucket; + eltstring = Fsymbol_name (elt); + if (next) + XSETSYMBOL (bucket, next); + else + bucket = Qzero; + } + else if (++indice >= obsize) + break; + else + { + bucket = vector_data (XVECTOR (alist))[indice]; + continue; + } + } + + /* Is this element a possible completion? */ + + if (STRINGP (eltstring) + && (slength <= string_char_length (XSTRING (eltstring))) + /* Reject alternatives that start with space + unless the input starts with space. */ + && ((string_char_length (XSTRING (string)) > 0 && + string_char (XSTRING (string), 0) == ' ') + || string_char (XSTRING (eltstring), 0) != ' ') + && (0 > scmp (string_data (XSTRING (eltstring)), + string_data (XSTRING (string)), + slength))) + { + /* Yes. Now check whether predicate likes it. */ + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + int loser; + GCPRO4 (tail, eltstring, allmatches, string); + loser = ignore_completion_p (eltstring, pred, elt); + UNGCPRO; + if (!loser) + /* Ok => put it on the list. */ + allmatches = Fcons (eltstring, allmatches); + } + } + + return Fnreverse (allmatches); +} + +/* Useless FSFmacs functions */ +/* More than useless. I've nuked minibuf_prompt_width so they won't + function at all in XEmacs at the moment. They are used to + implement some braindamage in FSF which we aren't including. --cet */ + +#if 0 +xxDEFUN ("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.") + () +{ + return (Fcopy_sequence (Vminibuf_prompt)); +} + +xxDEFUN ("minibuffer-prompt-width", Fminibuffer_prompt_width, + Sminibuffer_prompt_width, 0, 0, 0, + "Return the display width of the minibuffer prompt.") + () +{ + return (make_int (minibuf_prompt_width)); +} +#endif + + +/************************************************************************/ +/* echo area */ +/************************************************************************/ + +extern int stdout_needs_newline; + +static Lisp_Object +clear_echo_area_internal (struct frame *f, Lisp_Object label, int from_print, + int no_restore) +{ + if (!NILP (Ffboundp (Qclear_message))) + { + Lisp_Object frame; + + XSETFRAME (frame, f); + return call4 (Qclear_message, label, frame, from_print ? Qt : Qnil, + no_restore ? Qt : Qnil); + } + else + { + write_string_to_stdio_stream (stderr, 0, (CONST Bufbyte *) "\n", 0, 1, + FORMAT_DISPLAY); + return Qnil; + } +} + +Lisp_Object +clear_echo_area (struct frame *f, Lisp_Object label, int no_restore) +{ + return clear_echo_area_internal (f, label, 0, no_restore); +} + +Lisp_Object +clear_echo_area_from_print (struct frame *f, Lisp_Object label, int no_restore) +{ + return clear_echo_area_internal (f, label, 1, no_restore); +} + +void +echo_area_append (struct frame *f, CONST Bufbyte *nonreloc, Lisp_Object reloc, + Bytecount offset, Bytecount length, + Lisp_Object label) +{ + Lisp_Object obj; + struct gcpro gcpro1; + Lisp_Object frame; + + /* some callers pass in a null string as a way of clearing the echo area. + check for length == 0 now; if this case, neither nonreloc nor reloc + may be valid. */ + if (length == 0) + return; + + fixup_internal_substring (nonreloc, reloc, offset, &length); + + /* also check it here, in case the string was really blank. */ + if (length == 0) + return; + + if (!NILP (Ffboundp (Qappend_message))) + { + if (STRINGP (reloc) && offset == 0 && + length == string_length (XSTRING (reloc))) + obj = reloc; + else + { + if (STRINGP (reloc)) + nonreloc = string_data (XSTRING (reloc)); + obj = make_string (nonreloc + offset, length); + } + + XSETFRAME (frame, f); + GCPRO1 (obj); + call4 (Qappend_message, label, obj, frame, + EQ (label, Qprint) ? Qt : Qnil); + UNGCPRO; + } + else + { + if (STRINGP (reloc)) + nonreloc = string_data (XSTRING (reloc)); + write_string_to_stdio_stream (stderr, 0, nonreloc, offset, length, + FORMAT_DISPLAY); + } +} + +void +echo_area_message (struct frame *f, CONST Bufbyte *nonreloc, + Lisp_Object reloc, Bytecount offset, Bytecount length, + Lisp_Object label) +{ + clear_echo_area (f, label, 1); + echo_area_append (f, nonreloc, reloc, offset, length, label); +} + +int +echo_area_active (struct frame *f) +{ + /* By definition, the echo area is active if the echo-area buffer + is not empty. No need to call Lisp code. (Anyway, this function + is called from redisplay.) */ + return (BUF_BEGV (XBUFFER (Vecho_area_buffer)) != + BUF_ZV (XBUFFER (Vecho_area_buffer))); +} + +Lisp_Object +echo_area_status (struct frame *f) +{ + if (!NILP (Ffboundp (Qcurrent_message_label))) + { + Lisp_Object frame; + + XSETFRAME (frame, f); + return (call1 (Qcurrent_message_label, frame)); + } + else + return stdout_needs_newline ? Qmessage : Qnil; +} + +Lisp_Object +echo_area_contents (struct frame *f) +{ + /* See above. By definition, the contents of the echo-area buffer + are the contents of the echo area. */ + return Fbuffer_substring (Qnil, Qnil, Vecho_area_buffer); +} + +/* Dump an informative message to the echo area. This function takes a + string in internal format. */ +void +message_internal (CONST Bufbyte *nonreloc, Lisp_Object reloc, + Bytecount offset, Bytecount length) +{ + /* This can GC! */ + if (NILP (Vexecuting_macro)) + echo_area_message (selected_frame (), nonreloc, reloc, offset, length, + Qmessage); +} + +void +message_append_internal (CONST Bufbyte *nonreloc, Lisp_Object reloc, + Bytecount offset, Bytecount length) +{ + /* This can GC! */ + if (NILP (Vexecuting_macro)) + echo_area_append (selected_frame (), nonreloc, reloc, offset, length, + Qmessage); +} + +/* The next three functions are interfaces to message_internal() that + take strings in external format. message() does I18N3 translating + on the format string; message_no_translate() does not. */ + +static void +message_1 (CONST char *fmt, va_list args) +{ + if (fmt) + { + struct gcpro gcpro1; + /* message_internal() might GC, e.g. if there are after-change-hooks + on the echo area buffer */ + Lisp_Object obj = emacs_doprnt_string_va ((CONST Bufbyte *) fmt, Qnil, + -1, args); + GCPRO1 (obj); + message_internal (0, obj, 0, -1); + UNGCPRO; + } + else + message_internal (0, Qnil, 0, 0); +} + +static void +message_append_1 (CONST char *fmt, va_list args) +{ + if (fmt) + { + struct gcpro gcpro1; + /* message_internal() might GC, e.g. if there are after-change-hooks + on the echo area buffer */ + Lisp_Object obj = emacs_doprnt_string_va ((CONST Bufbyte *) fmt, Qnil, + -1, args); + GCPRO1 (obj); + message_append_internal (0, obj, 0, -1); + UNGCPRO; + } + else + message_append_internal (0, Qnil, 0, 0); +} + +void +clear_message (void) +{ + message_internal (0, Qnil, 0, 0); +} + +void +message (CONST char *fmt, ...) +{ + /* I think it's OK to pass the data of Lisp strings as arguments to + this function. No GC'ing will occur until the data has already + been copied. */ + va_list args; + + va_start (args, fmt); + if (fmt) + fmt = GETTEXT (fmt); + message_1 (fmt, args); + va_end (args); +} + +void +message_append (CONST char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + if (fmt) + fmt = GETTEXT (fmt); + message_append_1 (fmt, args); + va_end (args); +} + +void +message_no_translate (CONST char *fmt, ...) +{ + /* I think it's OK to pass the data of Lisp strings as arguments to + this function. No GC'ing will occur until the data has already + been copied. */ + va_list args; + + va_start (args, fmt); + message_1 (fmt, args); + va_end (args); +} + + +/************************************************************************/ +/* initialization */ +/************************************************************************/ + +void +syms_of_minibuf (void) +{ + defsymbol (&Qminibuffer_setup_hook, "minibuffer-setup-hook"); + + defsymbol (&Qcompletion_ignore_case, "completion-ignore-case"); + + defsubr (&Sminibuffer_depth); +#if 0 + defsubr (&Sminibuffer_prompt); + defsubr (&Sminibuffer_prompt_width); +#endif + + defsubr (&Sread_minibuffer_internal); + + defsubr (&Stry_completion); + defsubr (&Sall_completions); + + defsymbol (&Qappend_message, "append-message"); + defsymbol (&Qclear_message, "clear-message"); + defsymbol (&Qdisplay_message, "display-message"); + defsymbol (&Qcurrent_message_label, "current-message-label"); +} + +void +vars_of_minibuf (void) +{ + minibuf_level = 0; + + staticpro (&Vminibuf_prompt); + Vminibuf_prompt = Qnil; + + DEFVAR_LISP ("minibuffer-setup-hook", &Vminibuffer_setup_hook /* +Normal hook run just after entry to minibuffer. +*/ ); + Vminibuffer_setup_hook = Qnil; + + DEFVAR_BOOL ("completion-ignore-case", &completion_ignore_case /* +Non-nil means don't consider case significant in completion. +*/ ); + completion_ignore_case = 0; + + /* Worthless doc string */ + DEFVAR_LISP ("completion-regexp-list", &Vcompletion_regexp_list /* +List of regexps that should restrict possible completions. +*/ ); + Vcompletion_regexp_list = Qnil; +} + +void +complex_vars_of_minibuf (void) +{ + /* This function can GC */ +#ifdef I18N3 + /* #### This needs to be fixed up so that the gettext() gets called + at runtime instead of at load time. */ +#endif + Vminibuffer_zero + = Fget_buffer_create + (Fpurecopy (build_string (DEFER_GETTEXT (" *Minibuf-0*")))); + Vecho_area_buffer + = Fget_buffer_create + (Fpurecopy (build_string (DEFER_GETTEXT (" *Echo Area*")))); +}