📄 minibuf.c
字号:
int bestmatchsize; int compare, matchsize; int list = CONSP (alist) || NULL (alist); int index, obsize; int matchcount = 0; Lisp_Object bucket, zero, end, tem; struct gcpro gcpro1, gcpro2, gcpro3; CHECK_STRING (string, 0); if (!list && XTYPE (alist) != Lisp_Vector) return call3 (alist, string, pred, Qnil); bestmatch = Qnil; if (list) tail = alist; else { index = 0; obsize = XVECTOR (alist)->size; bucket = XVECTOR (alist)->contents[index]; } 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. */ if (list) { if (NULL (tail)) break; elt = Fcar (tail); eltstring = Fcar (elt); tail = Fcdr (tail); } else { if (XFASTINT (bucket) != 0) { elt = bucket; eltstring = Fsymbol_name (elt); if (XSYMBOL (bucket)->next) XSETSYMBOL (bucket, XSYMBOL (bucket)->next); else XFASTINT (bucket) = 0; } else if (++index >= obsize) break; else { bucket = XVECTOR (alist)->contents[index]; continue; } } /* Is this element a possible completion? */ if (XTYPE (eltstring) == Lisp_String && XSTRING (string)->size <= XSTRING (eltstring)->size && 0 > scmp (XSTRING (eltstring)->data, XSTRING (string)->data, XSTRING (string)->size)) { /* Yes. */ /* Ignore this element if there is a predicate and the predicate doesn't like it. */ if (!NULL (pred)) { if (EQ (pred, Qcommandp)) tem = Fcommandp (elt); else { GCPRO3 (string, eltstring, bestmatch); tem = call1 (pred, elt); UNGCPRO; } if (NULL (tem)) continue; } /* Update computation of how much all possible completions match */ matchcount++; if (NULL (bestmatch)) bestmatch = eltstring, bestmatchsize = XSTRING (eltstring)->size; else { compare = min (bestmatchsize, XSTRING (eltstring)->size); matchsize = scmp (XSTRING (bestmatch)->data, XSTRING (eltstring)->data, compare); bestmatchsize = (matchsize >= 0) ? matchsize : compare; } } } if (NULL (bestmatch)) return Qnil; /* No completions found */ if (matchcount == 1 && bestmatchsize == XSTRING (string)->size) return Qt; XFASTINT (zero) = 0; /* Else extract the part in which */ XFASTINT (end) = bestmatchsize; /* all completions agree */ return Fsubstring (bestmatch, zero, end);}/* 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. */scmp (s1, s2, len) register char *s1, *s2; int len;{ register int l = len; if (completion_ignore_case) { while (l && downcase_table[*s1++] == downcase_table[*s2++]) l--; } else { while (l && *s1++ == *s2++) l--; } if (l == 0) return -1; else return len - l;}DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 3, 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\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\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 or the symbol from the obarray.") (string, alist, pred) Lisp_Object string, alist, pred;{ Lisp_Object tail, elt, eltstring; Lisp_Object allmatches; int list = CONSP (alist) || NULL (alist); int index, obsize; Lisp_Object bucket, tem; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; CHECK_STRING (string, 0); if (!list && XTYPE (alist) != Lisp_Vector) { return call3 (alist, string, pred, Qt); } allmatches = Qnil; /* If ALIST is not a list, set TAIL just for gc pro. */ tail = alist; if (! list) { index = 0; obsize = XVECTOR (alist)->size; bucket = XVECTOR (alist)->contents[index]; } 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. */ if (list) { if (NULL (tail)) break; elt = Fcar (tail); eltstring = Fcar (elt); tail = Fcdr (tail); } else { if (XFASTINT (bucket) != 0) { elt = bucket; eltstring = Fsymbol_name (elt); if (XSYMBOL (bucket)->next) XSETSYMBOL (bucket, XSYMBOL (bucket)->next); else XFASTINT (bucket) = 0; } else if (++index >= obsize) break; else { bucket = XVECTOR (alist)->contents[index]; continue; } } /* 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)) { /* Yes. */ /* Ignore this element if there is a predicate and the predicate doesn't like it. */ if (!NULL (pred)) { if (EQ (pred, Qcommandp)) tem = Fcommandp (elt); else { GCPRO4 (tail, eltstring, allmatches, string); tem = call1 (pred, elt); UNGCPRO; } if (NULL (tem)) continue; } /* Ok => put it on the list. */ allmatches = Fcons (eltstring, allmatches); } } return Fnreverse (allmatches);}Lisp_Object Vminibuffer_completion_table, Qminibuffer_completion_table;Lisp_Object Vminibuffer_completion_predicate, Qminibuffer_completion_predicate;Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 5, 0, "Read a string in the minibuffer, with completion.\n\Args are PROMPT, TABLE, PREDICATE, REQUIRE-MATCH and INITIAL-INPUT.\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 (see try-completion).\n\PREDICATE limits completion to a subset of TABLE; see try-completion for details.\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.\n\ If it is also not t, Return does not exit if it does non-null completion.\n\If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\n\Case is ignored if ambient value of completion-ignore-case is non-nil.") (prompt, table, pred, require_match, init) Lisp_Object prompt, table, pred, require_match, init;{ Lisp_Object val; int count = specpdl_ptr - specpdl; specbind (Qminibuffer_completion_table, table); specbind (Qminibuffer_completion_predicate, pred); specbind (Qminibuffer_completion_confirm, EQ (require_match, Qt) ? Qnil : Qt); val = read_minibuf (NULL (require_match) ? Vminibuffer_local_completion_map : Vminibuffer_local_must_match_map, init, prompt, 0); unbind_to (count); return val;}temp_echo_area_contents (m) char *m;{ int osize = ZV; Lisp_Object oinhibit; oinhibit = Vinhibit_quit; SET_PT (osize); InsStr (m); SET_PT (osize); Vinhibit_quit = Qt; Fsit_for (make_number (2), Qnil); del_range (point, ZV); if (!NULL (Vquit_flag)) { Vquit_flag = Qnil; unread_command_char = Ctl ('g'); } Vinhibit_quit = oinhibit;}Lisp_Object Fminibuffer_completion_help ();/* returns: * 0 no possible completion * 1 was already an exact and unique completion * 3 was already an exact completion * 4 completed to an exact completion * 5 some completion happened * 6 no completion happened */intdo_completion (){ Lisp_Object completion, tem; int completedp; completion = Ftry_completion (Fbuffer_string (), Vminibuffer_completion_table, Vminibuffer_completion_predicate); if (NULL (completion)) { bell (); temp_echo_area_contents (" [No match]"); return 0; } if (EQ (completion, Qt)) /* exact and unique match */ return 1; /* compiler bug */ tem = Fstring_equal (completion, Fbuffer_string()); if (completedp = NULL (tem)) { Ferase_buffer (); /* Some completion happened */ Finsert (1, &completion); } /* It did find a match. Do we match some possibility exactly now? */ if (CONSP (Vminibuffer_completion_table) || NULL (Vminibuffer_completion_table)) tem = Fassoc (Fbuffer_string (), Vminibuffer_completion_table); else if (XTYPE (Vminibuffer_completion_table) == Lisp_Vector) { /* the primitive used by Fintern_soft */ extern Lisp_Object oblookup (); tem = Fbuffer_string (); /* Bypass intern-soft as that loses for nil */ tem = oblookup (Vminibuffer_completion_table, XSTRING (tem)->data, XSTRING (tem)->size); if (XTYPE (tem) != Lisp_Symbol) tem = Qnil; else if (!NULL (Vminibuffer_completion_predicate)) tem = call1 (Vminibuffer_completion_predicate, tem); else tem = Qt; } else tem = call3 (Vminibuffer_completion_table, Fbuffer_string (), Vminibuffer_completion_predicate, Qlambda); if (NULL (tem)) { /* not an exact match */ if (completedp) return 5; else if (completion_auto_help) Fminibuffer_completion_help (); else temp_echo_area_contents (" [Next char not unique]"); return 6; } else return (completedp ? 4 : 3);} DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "", "Complete the minibuffer contents as far as possible.")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -