X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/034086489cff2a23cb4d9f8c536e18456be617ef..0766b489e1b34964bb43db221fe967d54ac5ec5e:/src/minibuf.c diff --git a/src/minibuf.c b/src/minibuf.c index 4adf665f8f..ca2f22df9e 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -43,9 +43,9 @@ along with GNU Emacs. If not, see . */ Lisp_Object Vminibuffer_list; -/* Data to remember during recursive minibuffer invocations */ +/* Data to remember during recursive minibuffer invocations. */ -Lisp_Object minibuf_save_list; +static Lisp_Object minibuf_save_list; /* Depth in minibuffer invocations. */ @@ -53,35 +53,35 @@ int minibuf_level; /* The maximum length of a minibuffer history. */ -Lisp_Object Qhistory_length; +static Lisp_Object Qhistory_length; -/* Fread_minibuffer leaves the input here as a string. */ +/* Fread_minibuffer leaves the input here as a string. */ Lisp_Object last_minibuf_string; -Lisp_Object Qminibuffer_history, Qbuffer_name_history; +static Lisp_Object Qminibuffer_history, Qbuffer_name_history; -Lisp_Object Qread_file_name_internal; +static Lisp_Object Qread_file_name_internal; /* Normal hooks for entry to and exit from minibuffer. */ -Lisp_Object Qminibuffer_setup_hook; -Lisp_Object Qminibuffer_exit_hook; +static Lisp_Object Qminibuffer_setup_hook; +static Lisp_Object Qminibuffer_exit_hook; Lisp_Object Qcompletion_ignore_case; -Lisp_Object Qminibuffer_completion_table; -Lisp_Object Qminibuffer_completion_predicate; -Lisp_Object Qminibuffer_completion_confirm; -Lisp_Object Qcompleting_read_default; -Lisp_Object Quser_variable_p; +static Lisp_Object Qminibuffer_completion_table; +static Lisp_Object Qminibuffer_completion_predicate; +static Lisp_Object Qminibuffer_completion_confirm; +static Lisp_Object Qcompleting_read_default; +static Lisp_Object Quser_variable_p; -Lisp_Object Qminibuffer_default; +static Lisp_Object Qminibuffer_default; -Lisp_Object Qcurrent_input_method, Qactivate_input_method; +static Lisp_Object Qcurrent_input_method, Qactivate_input_method; -Lisp_Object Qcase_fold_search; +static Lisp_Object Qcase_fold_search; -Lisp_Object Qread_expression_history; +static Lisp_Object Qread_expression_history; /* Prompt to display in front of the mini-buffer contents. */ @@ -97,7 +97,7 @@ static EMACS_INT minibuf_prompt_width; We do this whenever the user starts a new minibuffer or when a minibuffer exits. */ -void +static void choose_minibuf_frame (void) { if (FRAMEP (selected_frame) @@ -143,6 +143,14 @@ choose_minibuf_frame_1 (Lisp_Object ignore) return Qnil; } +DEFUN ("active-minibuffer-window", Factive_minibuffer_window, + Sactive_minibuffer_window, 0, 0, 0, + doc: /* Return the currently active minibuffer window, or nil if none. */) + (void) +{ + return minibuf_level ? minibuf_window : Qnil; +} + DEFUN ("set-minibuffer-window", Fset_minibuffer_window, Sset_minibuffer_window, 1, 1, 0, doc: /* Specify which minibuffer window to use for the minibuffer. @@ -160,7 +168,7 @@ without invoking the usual minibuffer commands. */) } -/* Actual minibuffer invocation. */ +/* Actual minibuffer invocation. */ static Lisp_Object read_minibuf_unwind (Lisp_Object); static Lisp_Object run_exit_minibuf_hook (Lisp_Object); @@ -229,7 +237,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial, Lisp_Object defalt, int allow_props, int inherit_input_method) { - int size, len; + size_t size, len; char *line, *s; Lisp_Object val; @@ -244,6 +252,8 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial, && (len = strlen (line), len == size - 1 && line[len - 1] != '\n')) { + if ((size_t) -1 / 2 < size) + memory_full (SIZE_MAX); size *= 2; line = (char *) xrealloc (line, size); } @@ -264,7 +274,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial, error ("Error reading from stdin"); } - /* If Lisp form desired instead of string, parse it. */ + /* If Lisp form desired instead of string, parse it. */ if (expflag) val = string_to_object (val, CONSP (defalt) ? XCAR (defalt) : defalt); @@ -586,7 +596,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* Empty out the minibuffers of all frames other than the one where we are going to display one now. Set them to point to ` *Minibuf-0*', which is always empty. */ - empty_minibuf = Fget_buffer (build_string (" *Minibuf-0*")); + empty_minibuf = get_minibuffer (0); FOR_EACH_FRAME (dummy, frame) { @@ -741,7 +751,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, } } - /* If Lisp form desired instead of string, parse it. */ + /* If Lisp form desired instead of string, parse it. */ if (expflag) val = string_to_object (val, defalt); @@ -753,7 +763,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, /* Return a buffer to be used as the minibuffer at depth `depth'. depth = 0 is the lowest allowed argument, and that is the value - used for nonrecursive minibuffer invocations */ + used for nonrecursive minibuffer invocations. */ Lisp_Object get_minibuffer (int depth) @@ -791,7 +801,10 @@ get_minibuffer (int depth) reset_buffer (XBUFFER (buf)); record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); Fset_buffer (buf); - Fkill_all_local_variables (); + if (!NILP (Ffboundp (intern ("minibuffer-inactive-mode")))) + call0 (intern ("minibuffer-inactive-mode")); + else + Fkill_all_local_variables (); unbind_to (count, Qnil); } @@ -806,7 +819,7 @@ run_exit_minibuf_hook (Lisp_Object data) } /* This function is called on exiting minibuffer, whether normally or - not, and it restores the current window, buffer, etc. */ + not, and it restores the current window, buffer, etc. */ static Lisp_Object read_minibuf_unwind (Lisp_Object data) @@ -866,11 +879,18 @@ read_minibuf_unwind (Lisp_Object data) windows_or_buffers_changed++; XSETFASTINT (XWINDOW (window)->last_modified, 0); XSETFASTINT (XWINDOW (window)->last_overlay_modified, 0); + + /* In case the previous minibuffer displayed in this miniwindow is + dead, we may keep displaying this buffer (tho it's inactive), so reset it, + to make sure we don't leave around bindings and stuff which only + made sense during the read_minibuf invocation. */ + call0 (intern ("minibuffer-inactive-mode")); return Qnil; } -DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0, +DEFUN ("read-from-minibuffer", Fread_from_minibuffer, + Sread_from_minibuffer, 1, 7, 0, doc: /* Read a string from the minibuffer, prompting with string PROMPT. The optional second arg INITIAL-CONTENTS is an obsolete alternative to DEFAULT-VALUE. It normally should be nil in new code, except when @@ -975,7 +995,7 @@ Such arguments are used as in `read-from-minibuffer'.) */) Qnil); } -/* Functions that use the minibuffer to read various things. */ +/* Functions that use the minibuffer to read various things. */ DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, doc: /* Read a string from the minibuffer, prompting with string PROMPT. @@ -1095,7 +1115,7 @@ function, instead of the usual behavior. */) { Lisp_Object args[4], result; char *s; - int len; + ptrdiff_t len; int count = SPECPDL_INDEX (); if (BUFFERP (def)) @@ -1117,7 +1137,7 @@ function, instead of the usual behavior. */) if (STRINGP (prompt)) { s = SSDATA (prompt); - len = strlen (s); + len = SBYTES (prompt); if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ') len = len - 2; else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' ')) @@ -1134,8 +1154,8 @@ function, instead of the usual behavior. */) } result = Fcompleting_read (prompt, intern ("internal-complete-buffer"), - Qnil, require_match, Qnil, Qbuffer_name_history, - def, Qnil); + Qnil, require_match, Qnil, + Qbuffer_name_history, def, Qnil); } else { @@ -1143,7 +1163,7 @@ function, instead of the usual behavior. */) args[1] = prompt; args[2] = def; args[3] = require_match; - result = Ffuncall(4, args); + result = Ffuncall (4, args); } return unbind_to (count, result); } @@ -1206,7 +1226,7 @@ is used to further constrain the set of candidates. */) && (!SYMBOLP (XCAR (collection)) || NILP (XCAR (collection))))) ? list_table : function_table)); - int idx = 0, obsize = 0; + EMACS_INT idx = 0, obsize = 0; int matchcount = 0; int bindcount = -1; Lisp_Object bucket, zero, end, tem; @@ -1224,16 +1244,16 @@ is used to further constrain the set of candidates. */) if (type == obarray_table) { collection = check_obarray (collection); - obsize = XVECTOR (collection)->size; + obsize = ASIZE (collection); bucket = XVECTOR (collection)->contents[idx]; } while (1) { - /* Get the next element of the alist, obarray, or hash-table. */ - /* Exit the loop if the elements are all used up. */ + /* Get the next element of the alist, obarray, or hash-table. */ + /* Exit the loop if the elements are all used up. */ /* elt gets the alist element or symbol. - eltstring gets the name to check as a completion. */ + eltstring gets the name to check as a completion. */ if (type == list_table) { @@ -1275,7 +1295,7 @@ is used to further constrain the set of candidates. */) elt = eltstring = HASH_KEY (XHASH_TABLE (collection), idx++); } - /* Is this element a possible completion? */ + /* Is this element a possible completion? */ if (SYMBOLP (eltstring)) eltstring = Fsymbol_name (eltstring); @@ -1288,7 +1308,7 @@ is used to further constrain the set of candidates. */) completion_ignore_case ? Qt : Qnil), EQ (Qt, tem))) { - /* Yes. */ + /* Yes. */ Lisp_Object regexps; /* Ignore this element if it fails to match all the regexps. */ @@ -1310,7 +1330,7 @@ is used to further constrain the set of candidates. */) } /* Ignore this element if there is a predicate - and the predicate doesn't like it. */ + and the predicate doesn't like it. */ if (!NILP (predicate)) { @@ -1412,7 +1432,7 @@ is used to further constrain the set of candidates. */) } if (NILP (bestmatch)) - return Qnil; /* No completions found */ + 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. */ @@ -1426,7 +1446,7 @@ is used to further constrain the set of candidates. */) return Qt; XSETFASTINT (zero, 0); /* Else extract the part in which */ - XSETFASTINT (end, bestmatchsize); /* all completions agree */ + XSETFASTINT (end, bestmatchsize); /* all completions agree. */ return Fsubstring (bestmatch, zero, end); } @@ -1471,7 +1491,7 @@ with a space are ignored unless STRING itself starts with a space. */) : NILP (collection) || (CONSP (collection) && (!SYMBOLP (XCAR (collection)) || NILP (XCAR (collection)))); - int idx = 0, obsize = 0; + EMACS_INT idx = 0, obsize = 0; int bindcount = -1; Lisp_Object bucket, tem, zero; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; @@ -1487,16 +1507,16 @@ with a space are ignored unless STRING itself starts with a space. */) if (type == 2) { collection = check_obarray (collection); - obsize = XVECTOR (collection)->size; + obsize = ASIZE (collection); bucket = XVECTOR (collection)->contents[idx]; } while (1) { - /* Get the next element of the alist, obarray, or hash-table. */ - /* Exit the loop if the elements are all used up. */ + /* Get the next element of the alist, obarray, or hash-table. */ + /* Exit the loop if the elements are all used up. */ /* elt gets the alist element or symbol. - eltstring gets the name to check as a completion. */ + eltstring gets the name to check as a completion. */ if (type == 1) { @@ -1538,7 +1558,7 @@ with a space are ignored unless STRING itself starts with a space. */) elt = eltstring = HASH_KEY (XHASH_TABLE (collection), idx++); } - /* Is this element a possible completion? */ + /* Is this element a possible completion? */ if (SYMBOLP (eltstring)) eltstring = Fsymbol_name (eltstring); @@ -1558,7 +1578,7 @@ with a space are ignored unless STRING itself starts with a space. */) completion_ignore_case ? Qt : Qnil), EQ (Qt, tem))) { - /* Yes. */ + /* Yes. */ Lisp_Object regexps; /* Ignore this element if it fails to match all the regexps. */ @@ -1580,7 +1600,7 @@ with a space are ignored unless STRING itself starts with a space. */) } /* Ignore this element if there is a predicate - and the predicate doesn't like it. */ + and the predicate doesn't like it. */ if (!NILP (predicate)) { @@ -1601,7 +1621,7 @@ with a space are ignored unless STRING itself starts with a space. */) } if (NILP (tem)) continue; } - /* Ok => put it on the list. */ + /* Ok => put it on the list. */ allmatches = Fcons (eltstring, allmatches); } } @@ -1767,7 +1787,7 @@ the values STRING, PREDICATE and `lambda'. */) (Lisp_Object string, Lisp_Object collection, Lisp_Object predicate) { Lisp_Object regexps, tail, tem = Qnil; - int i = 0; + EMACS_INT i = 0; CHECK_STRING (string); @@ -1801,15 +1821,15 @@ the values STRING, PREDICATE and `lambda'. */) if (completion_ignore_case && !SYMBOLP (tem)) { - for (i = XVECTOR (collection)->size - 1; i >= 0; i--) + for (i = ASIZE (collection) - 1; i >= 0; i--) { tail = XVECTOR (collection)->contents[i]; if (SYMBOLP (tail)) while (1) { - if (EQ((Fcompare_strings (string, make_number (0), Qnil, + if (EQ (Fcompare_strings (string, make_number (0), Qnil, Fsymbol_name (tail), - make_number (0) , Qnil, Qt)), + make_number (0) , Qnil, Qt), Qt)) { tem = tail; @@ -1833,11 +1853,11 @@ the values STRING, PREDICATE and `lambda'. */) tem = HASH_KEY (h, i); else for (i = 0; i < HASH_TABLE_SIZE (h); ++i) - if (!NILP (HASH_HASH (h, i)) && - EQ (Fcompare_strings (string, make_number (0), Qnil, - HASH_KEY (h, i), make_number (0) , Qnil, - completion_ignore_case ? Qt : Qnil), - Qt)) + if (!NILP (HASH_HASH (h, i)) + && EQ (Fcompare_strings (string, make_number (0), Qnil, + HASH_KEY (h, i), make_number (0) , Qnil, + completion_ignore_case ? Qt : Qnil), + Qt)) { tem = HASH_KEY (h, i); break; @@ -1875,13 +1895,16 @@ the values STRING, PREDICATE and `lambda'. */) return Qt; } +static Lisp_Object Qmetadata; +extern Lisp_Object Qbuffer; + DEFUN ("internal-complete-buffer", Finternal_complete_buffer, Sinternal_complete_buffer, 3, 3, 0, doc: /* Perform completion on buffer names. If the argument FLAG is nil, invoke `try-completion', if it's t, invoke `all-completions', otherwise invoke `test-completion'. The arguments STRING and PREDICATE are as in `try-completion', -`all-completions', and `test-completion'. */) +`all-completions', and `test-completion'. */) (Lisp_Object string, Lisp_Object predicate, Lisp_Object flag) { if (NILP (flag)) @@ -1909,8 +1932,12 @@ The arguments STRING and PREDICATE are as in `try-completion', return res; } } - else /* assume `lambda' */ + else if (EQ (flag, Qlambda)) return Ftest_completion (string, Vbuffer_alist, predicate); + else if (EQ (flag, Qmetadata)) + return Fcons (Qmetadata, Fcons (Fcons (Qcategory, Qbuffer), Qnil)); + else + return Qnil; } /* Like assoc but assumes KEY is a string, and ignores case if appropriate. */ @@ -1986,66 +2013,38 @@ syms_of_minibuf (void) minibuf_save_list = Qnil; staticpro (&minibuf_save_list); - Qcompleting_read_default = intern_c_string ("completing-read-default"); - staticpro (&Qcompleting_read_default); - - Qcompletion_ignore_case = intern_c_string ("completion-ignore-case"); - staticpro (&Qcompletion_ignore_case); - - Qread_file_name_internal = intern_c_string ("read-file-name-internal"); - staticpro (&Qread_file_name_internal); - - Qminibuffer_default = intern_c_string ("minibuffer-default"); - staticpro (&Qminibuffer_default); + DEFSYM (Qcompleting_read_default, "completing-read-default"); + DEFSYM (Qcompletion_ignore_case, "completion-ignore-case"); + DEFSYM (Qread_file_name_internal, "read-file-name-internal"); + DEFSYM (Qminibuffer_default, "minibuffer-default"); Fset (Qminibuffer_default, Qnil); - Qminibuffer_completion_table = intern_c_string ("minibuffer-completion-table"); - staticpro (&Qminibuffer_completion_table); - - Qminibuffer_completion_confirm = intern_c_string ("minibuffer-completion-confirm"); - staticpro (&Qminibuffer_completion_confirm); - - Qminibuffer_completion_predicate = intern_c_string ("minibuffer-completion-predicate"); - staticpro (&Qminibuffer_completion_predicate); + DEFSYM (Qminibuffer_completion_table, "minibuffer-completion-table"); + DEFSYM (Qminibuffer_completion_confirm, "minibuffer-completion-confirm"); + DEFSYM (Qminibuffer_completion_predicate, "minibuffer-completion-predicate"); staticpro (&last_minibuf_string); last_minibuf_string = Qnil; - Quser_variable_p = intern_c_string ("user-variable-p"); - staticpro (&Quser_variable_p); - - Qminibuffer_history = intern_c_string ("minibuffer-history"); - staticpro (&Qminibuffer_history); - - Qbuffer_name_history = intern_c_string ("buffer-name-history"); - staticpro (&Qbuffer_name_history); + DEFSYM (Quser_variable_p, "user-variable-p"); + DEFSYM (Qminibuffer_history, "minibuffer-history"); + DEFSYM (Qbuffer_name_history, "buffer-name-history"); Fset (Qbuffer_name_history, Qnil); - Qminibuffer_setup_hook = intern_c_string ("minibuffer-setup-hook"); - staticpro (&Qminibuffer_setup_hook); - - Qminibuffer_exit_hook = intern_c_string ("minibuffer-exit-hook"); - staticpro (&Qminibuffer_exit_hook); - - Qhistory_length = intern_c_string ("history-length"); - staticpro (&Qhistory_length); - - Qcurrent_input_method = intern_c_string ("current-input-method"); - staticpro (&Qcurrent_input_method); - - Qactivate_input_method = intern_c_string ("activate-input-method"); - staticpro (&Qactivate_input_method); - - Qcase_fold_search = intern_c_string ("case-fold-search"); - staticpro (&Qcase_fold_search); + DEFSYM (Qminibuffer_setup_hook, "minibuffer-setup-hook"); + DEFSYM (Qminibuffer_exit_hook, "minibuffer-exit-hook"); + DEFSYM (Qhistory_length, "history-length"); + DEFSYM (Qcurrent_input_method, "current-input-method"); + DEFSYM (Qactivate_input_method, "activate-input-method"); + DEFSYM (Qcase_fold_search, "case-fold-search"); + DEFSYM (Qmetadata, "metadata"); DEFVAR_LISP ("read-expression-history", Vread_expression_history, doc: /* A history list for arguments that are Lisp expressions to evaluate. For example, `eval-expression' uses this. */); Vread_expression_history = Qnil; - Qread_expression_history = intern_c_string ("read-expression-history"); - staticpro (&Qread_expression_history); + DEFSYM (Qread_expression_history, "read-expression-history"); DEFVAR_LISP ("read-buffer-function", Vread_buffer_function, doc: /* If this is non-nil, `read-buffer' does its work by calling this function. @@ -2190,6 +2189,7 @@ properties. */); doc: /* Minibuffer keymap used for reading Lisp expressions. */); Vread_expression_map = Qnil; + defsubr (&Sactive_minibuffer_window); defsubr (&Sset_minibuffer_window); defsubr (&Sread_from_minibuffer); defsubr (&Seval_minibuffer);