|
|
1.1 root 1: /* Minibuffer input and completion.
2: Copyright (C) 1985 Richard M. Stallman.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU Emacs General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU Emacs, but only under the conditions described in the
15: GNU Emacs General Public License. A copy of this license is
16: supposed to have been given to you along with GNU Emacs so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include <ctype.h>
23: #include "config.h"
24: #include "lisp.h"
25: #include "commands.h"
26: #include "buffer.h"
27: #include "window.h"
28: #include "syntax.h"
29: #include "dispextern.h"
30:
31: #define min(a, b) ((a) < (b) ? (a) : (b))
32:
33: /* List of buffers for use as minibuffers.
34: The first element of the list is used for the outermost minibuffer invocation,
35: the next element is used for a recursive minibuffer invocation, etc.
36: The list is extended at the end as deeped minibuffer recursions are encountered. */
37: Lisp_Object Vminibuffer_list;
38:
39: struct minibuf_save_data
40: {
41: char *prompt;
42: int prompt_width;
43: Lisp_Object help_form;
44: };
45:
46: int minibuf_save_vector_size;
47: struct minibuf_save_data *minibuf_save_vector;
48:
49: int auto_help; /* Nonzero means display completion help for invalid input */
50:
51: /* Fread_minibuffer leaves the input, as a string, here */
52: Lisp_Object last_minibuf_string;
53:
54: /* Nonzero means let functions called when within a minibuffer
55: invoke recursive minibuffers (to read arguments, or whatever) */
56: int enable_recursive_minibuffers;
57:
58: /* help-form is bound to this while in the minibuffer. */
59:
60: Lisp_Object Vminibuffer_help_form;
61:
62: /* Nonzero means completion ignores case. */
63:
64: int completion_ignore_case;
65:
66: Lisp_Object Quser_variable_p;
67:
68: /* Width in columns of current minibuffer prompt. */
69:
70: extern int minibuf_prompt_width;
71:
72: /* Actual minibuffer invocation. */
73:
74: void read_minibuf_string_unwind ();
75: Lisp_Object get_minibuffer ();
76: Lisp_Object read_minibuf ();
77:
78: Lisp_Object
79: read_minibuf_string (map, prefix, prompt)
80: Lisp_Object map;
81: Lisp_Object prefix;
82: Lisp_Object prompt;
83: {
84: return read_minibuf (map, prefix, prompt, 0);
85: }
86:
87:
88: Lisp_Object
89: read_minibuf (map, prefix, prompt, expflag)
90: Lisp_Object map;
91: Lisp_Object prefix;
92: Lisp_Object prompt;
93: int expflag;
94: {
95: Lisp_Object val;
96: int count = specpdl_ptr - specpdl;
97:
98: if (!enable_recursive_minibuffers &&
99: (EQ (selected_window, minibuf_window)))
100: error ("Command attempted to use minibuffer while in minibuffer");
101:
102: if (MinibufDepth == minibuf_save_vector_size)
103: minibuf_save_vector =
104: (struct minibuf_save_data *) xrealloc (minibuf_save_vector,
105: (minibuf_save_vector_size *= 2) * sizeof (struct minibuf_save_data));
106: minibuf_save_vector[MinibufDepth].prompt = minibuf_prompt;
107: minibuf_save_vector[MinibufDepth].help_form = Vhelp_form;
108: minibuf_save_vector[MinibufDepth].prompt_width = minibuf_prompt_width;
109: minibuf_prompt_width = 0;
110:
111: record_unwind_protect (save_window_restore, save_window_save ());
112:
113: val = bf_cur->directory;
114: Fset_buffer (get_minibuffer (MinibufDepth + 1));
115: bf_cur->directory = val;
116:
117: Fshow_buffer (minibuf_window, Fcurrent_buffer ());
118: Fselect_window (minibuf_window);
119: XFASTINT (XWINDOW (minibuf_window)->hscroll) = 0;
120:
121: Ferase_buffer ();
122: MinibufDepth++;
123: record_unwind_protect (read_minibuf_string_unwind, Qnil);
124:
125: if (!NULL (prefix))
126: Finsert (1, &prefix);
127:
128: minibuf_prompt = (char *) alloca (XSTRING (prompt)->size + 1);
129: bcopy (XSTRING (prompt)->data, minibuf_prompt, XSTRING (prompt)->size + 1);
130: minibuf_message = 0;
131:
132: Vhelp_form = Vminibuffer_help_form;
133: bf_cur->keymap = map;
134: Frecursive_edit ();
135:
136: /* If cursor is on the minibuffer line,
137: show the user we have exited by putting it in column 0. */
138: if (cursY >= XFASTINT (XWINDOW (minibuf_window)->top)
139: && !noninteractive)
140: {
141: cursX = 0;
142: update_screen (1, 1);
143: }
144:
145: /* Make minibuffer contents into a string */
146: val = make_string (&CharAt (1), bf_s1 + bf_s2);
147: bcopy (bf_p2 + bf_s1 + 1,
148: XSTRING (val)->data + bf_s1,
149: bf_s2);
150:
151: last_minibuf_string = val;
152:
153: /* If Lisp form desired instead of string, read buffer contents */
154: if (expflag)
155: {
156: SetPoint (1);
157: val = Fread (Fcurrent_buffer ());
158: }
159:
160: unbind_to (count);
161: return val;
162: }
163:
164: /* Return a buffer to be used as the minibuffer at depth `depth'.
165: depth = 0 is the lowest allowed argument, and that is the value
166: used for nonrecursive minibuffer invocations */
167:
168: Lisp_Object
169: get_minibuffer (depth)
170: int depth;
171: {
172: Lisp_Object tail, num, buf;
173: char name[14];
174: extern Lisp_Object nconc2 ();
175:
176: XFASTINT (num) = depth;
177: tail = Fnthcdr (num, Vminibuffer_list);
178: if (NULL (tail))
179: {
180: tail = Fcons (Qnil, Qnil);
181: Vminibuffer_list = nconc2 (Vminibuffer_list, tail);
182: }
183: buf = Fcar (tail);
184: if (NULL (buf) || NULL (XBUFFER (buf)->name))
185: {
186: sprintf (name, " *Minibuf-%d*", depth);
187: buf = Fget_buffer_create (build_string (name));
188: XCONS (tail)->car = buf;
189: }
190: else
191: reset_buffer (XBUFFER (buf));
192: return buf;
193: }
194:
195: /* This function is called on exiting minibuffer, whether normally or not,
196: and it restores the current window, buffer, etc. */
197:
198: void
199: read_minibuf_string_unwind ()
200: {
201: Ferase_buffer ();
202:
203: /* If this was a recursive minibuffer,
204: tie the minibuffer window back to the outer level minibuffer buffer */
205: MinibufDepth--;
206: /* Make sure minibuffer window is erased, not ignored */
207: windows_or_buffers_changed++;
208: XFASTINT (XWINDOW (minibuf_window)->last_modified) = 0;
209:
210: /* Restore prompt from outer minibuffer */
211: minibuf_prompt = minibuf_save_vector[MinibufDepth].prompt;
212: minibuf_prompt_width = minibuf_save_vector[MinibufDepth].prompt_width;
213: Vhelp_form = minibuf_save_vector[MinibufDepth].help_form;
214: }
215:
216: DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 4, 0,
217: "Read a string from the minibuffer, prompting with string PROMPT.\n\
218: If optional second arg INITIAL-CONTENTS is non-nil, it is a string\n\
219: to be inserted into the minibuffer before reading input.\n\
220: Third arg KEYMAP is a keymap to use whilst reading; the default is\n\
221: minibuffer-local-map.\n\
222: If fourth arg READ is non-nil, then interpret the result as a lisp object\n\
223: and return that object (ie (car (read-from-string <input-string>)))")
224: (prompt, initial_input, keymap, read)
225: Lisp_Object prompt, initial_input, keymap, read;
226: {
227: CHECK_STRING (prompt, 0);
228: if (!NULL (initial_input))
229: CHECK_STRING (initial_input, 1);
230: if (NULL (keymap))
231: keymap = Vminibuffer_local_map;
232: else
233: keymap = get_keymap (keymap,2);
234: return read_minibuf (keymap, initial_input, prompt, !NULL(read));
235: }
236:
237: DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
238: "Return a Lisp object read using the minibuffer.\n\
239: Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS\n\
240: is a string to insert in the minibuffer before reading.")
241: (prompt, initial_contents)
242: Lisp_Object prompt, initial_contents;
243: {
244: CHECK_STRING (prompt, 0);
245: if (!NULL (initial_contents))
246: CHECK_STRING (initial_contents, 1)
247: return read_minibuf (Vminibuffer_local_map, initial_contents, prompt, 1);
248: }
249:
250: DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
251: "Return value of Lisp expression read using the minibuffer.\n\
252: Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS\n\
253: is a string to insert in the minibuffer before reading.")
254: (prompt, initial_contents)
255: Lisp_Object prompt, initial_contents;
256: {
257: return Feval (Fread_minibuffer (prompt, initial_contents));
258: }
259:
260: /* Functions that use the minibuffer to read various things. */
261:
262: DEFUN ("read-string", Fread_string, Sread_string, 1, 2, 0,
263: "Read a string from the minibuffer, prompting with string PROMPT.\n\
264: If non-nil second arg INITIAL-INPUT is a string to insert before reading.")
265: (prompt, initial_input)
266: Lisp_Object prompt, initial_input;
267: {
268: return Fread_from_minibuffer (prompt, initial_input, Qnil, Qnil);
269: }
270:
271: DEFUN ("read-no-blanks-input", Fread_no_blanks_input, Sread_no_blanks_input, 2, 2, 0,
272: "Args PROMPT and INIT, strings. Read a string from the terminal, not allowing blanks.\n\
273: Prompt with PROMPT, and provide INIT as an initial value of the input string.")
274: (prompt, init)
275: Lisp_Object prompt, init;
276: {
277: CHECK_STRING (prompt, 0);
278: CHECK_STRING (init, 1);
279:
280: return read_minibuf_string (Vminibuffer_local_ns_map, init, prompt);
281: }
282:
283: DEFUN ("read-command", Fread_command, Sread_command, 1, 1, 0,
284: "One arg PROMPT, a string. Read the name of a command and return as a symbol.\n\
285: Prompts with PROMPT.")
286: (prompt)
287: Lisp_Object prompt;
288: {
289: return Fintern (Fcompleting_read (prompt, Vobarray, Qcommandp, Qt, Qnil),
290: Qnil);
291: }
292:
293: #ifdef NOTDEF
294: DEFUN ("read-function", Fread_function, Sread_function, 1, 1, 0,
295: "One arg PROMPT, a string. Read the name of a function and return as a symbol.\n\
296: Prompts with PROMPT.")
297: (prompt)
298: Lisp_Object prompt;
299: {
300: return Fintern (Fcompleting_read (prompt, Vobarray, Qfboundp, Qt, Qnil),
301: Qnil);
302: }
303: #endif /* NOTDEF */
304:
305: DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 1, 0,
306: "One arg PROMPT, a string. Read the name of a user variable and return\n\
307: it as a symbol. Prompts with PROMPT.\n\
308: A user variable is one whose documentation starts with a \"*\" character.")
309: (prompt)
310: Lisp_Object prompt;
311: {
312: return Fintern (Fcompleting_read (prompt, Vobarray,
313: Quser_variable_p, Qt, Qnil),
314: Qnil);
315: }
316:
317: DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 3, 0,
318: "One arg PROMPT, a string. Read the name of a buffer and return as a string.\n\
319: Prompts with PROMPT.\n\
320: Optional second arg is value to return if user enters an empty line.\n\
321: If optional third arg REQUIRE-MATCH is non-nil, only existing buffer names are allowed.")
322: (prompt, def, require_match)
323: Lisp_Object prompt, def, require_match;
324: {
325: Lisp_Object tem;
326: Lisp_Object args[3];
327: struct gcpro gcpro1;
328:
329: if (XTYPE (def) == Lisp_Buffer)
330: def = XBUFFER (def)->name;
331: if (!NULL (def))
332: {
333: args[0] = build_string ("%s(default %s) ");
334: args[1] = prompt;
335: args[2] = def;
336: prompt = Fformat (3, args);
337: }
338: GCPRO1 (def);
339: tem = Fcompleting_read (prompt, Vbuffer_alist, Qnil, require_match, Qnil);
340: UNGCPRO;
341: if (XSTRING (tem)->size)
342: return tem;
343: return def;
344: }
345:
346: DEFUN ("try-completion", Ftry_completion, Stry_completion, 2, 3, 0,
347: "Return common substring of all completions of STRING in ALIST.\n\
348: Each car of each element of ALIST is tested to see if it begins with STRING.\n\
349: All that match are compared together; the longest initial sequence\n\
350: common to all matches is returned as a string.\n\
351: If there is no match at all, nil is returned.\n\
352: For an exact match, t is returned.\n\
353: \n\
354: ALIST can be an obarray instead of an alist.\n\
355: Then the print names of all symbols in the obarray are the possible matches.\n\
356: \n\
357: If optional third argument PREDICATE is non-nil,\n\
358: it is used to test each possible match.\n\
359: The match is a candidate only if PREDICATE returns non-nil.\n\
360: The argument given to PREDICATE is the alist element or the symbol from the obarray.")
361: (string, alist, pred)
362: Lisp_Object string, alist, pred;
363: {
364: Lisp_Object bestmatch, tail, elt, eltstring;
365: int bestmatchsize;
366: int compare, matchsize;
367: int list = LISTP (alist);
368: int index, obsize;
369: int matchcount = 0;
370: Lisp_Object bucket, zero, end, tem;
371:
372: CHECK_STRING (string, 0);
373: if (!list && XTYPE (alist) != Lisp_Vector)
374: return call3 (alist, string, pred, Qnil);
375:
376: bestmatch = Qnil;
377:
378: if (list)
379: tail = alist;
380: else
381: {
382: index = 0;
383: obsize = XVECTOR (alist)->size;
384: bucket = XVECTOR (alist)->contents[index];
385: }
386:
387: while (1)
388: {
389: /* Get the next element of the alist or obarray. */
390: /* Exit the loop if the elements are all used up. */
391: /* elt gets the alist element or symbol.
392: eltstring gets the name to check as a completion. */
393:
394: if (list)
395: {
396: if (NULL (tail))
397: break;
398: elt = Fcar (tail);
399: eltstring = Fcar (elt);
400: tail = Fcdr (tail);
401: }
402: else
403: {
404: if (XSYMBOL (bucket))
405: {
406: elt = bucket;
407: eltstring = Fsymbol_name (elt);
408: XSETSYMBOL (bucket, XSYMBOL (bucket)->next);
409: }
410: else if (++index >= obsize)
411: break;
412: else
413: {
414: bucket = XVECTOR (alist)->contents[index];
415: continue;
416: }
417: }
418:
419: /* Is this element a possible completion? */
420:
421: if (XTYPE (eltstring) == Lisp_String &&
422: XSTRING (string)->size <= XSTRING (eltstring)->size &&
423: -1 == scmp (XSTRING (eltstring)->data, XSTRING (string)->data, XSTRING (string)->size))
424: {
425: /* Yes. */
426: /* Ignore this element if there is a predicate and the predicate doesn't like it. */
427:
428: if (!NULL (pred))
429: {
430: if (EQ (pred, Qcommandp))
431: tem = Fcommandp (elt);
432: else
433: {
434: tem = call1 (pred, elt);
435: }
436: if (NULL (tem)) continue;
437: }
438:
439: /* Update computation of how much all possible completions match */
440:
441: matchcount++;
442: if (NULL (bestmatch))
443: bestmatch = eltstring, bestmatchsize = XSTRING (eltstring)->size;
444: else
445: {
446: compare = min (bestmatchsize, XSTRING (eltstring)->size);
447: matchsize = scmp (XSTRING (bestmatch)->data,
448: XSTRING (eltstring)->data,
449: compare);
450: bestmatchsize = (matchsize >= 0) ? matchsize : compare;
451: }
452: }
453: }
454:
455: if (NULL (bestmatch))
456: return Qnil; /* No completions found */
457: if (matchcount == 1 && bestmatchsize == XSTRING (string)->size)
458: return Qt;
459:
460: XFASTINT (zero) = 0; /* Else extract the part in which */
461: XFASTINT (end) = bestmatchsize; /* all completions agree */
462: return Fsubstring (bestmatch, zero, end);
463: }
464:
465: /* Like strncmp but ignores case differences if appropriate.
466: Also return value is different:
467: -1 if strings match,
468: else number of chars that match at the beginning. */
469:
470: #define cvt(c) (islower (c) ? c + 'A' - 'a' : c)
471:
472: scmp (s1, s2, len)
473: register char *s1, *s2;
474: int len;
475: {
476: register int l = len;
477:
478: if (completion_ignore_case)
479: {
480: while (l && *s1 && cvt (*s1) == cvt (*s2))
481: {
482: l--;
483: s1++;
484: s2++;
485: }
486: }
487: else
488: {
489: while (l && *s1 && *s1 == *s2)
490: {
491: l--;
492: s1++;
493: s2++;
494: }
495: }
496: if (l == 0 || (*s1 == 0 && *s2 == 0))
497: return -1;
498: else return len - l;
499: }
500:
501: DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 3, 0,
502: "Search for partial matches to STRING in ALIST.\n\
503: Each car of each element of ALIST is tested to see if it begins with STRING.\n\
504: The value is a list of all the strings from ALIST that match.\n\
505: ALIST can be an obarray instead of an alist.\n\
506: Then the print names of all symbols in the obarray are the possible matches.\n\
507: \n\
508: If optional third argument PREDICATE is non-nil,\n\
509: it is used to test each possible match.\n\
510: The match is a candidate only if PREDICATE returns non-nil.\n\
511: The argument given to PREDICATE is the alist element or the symbol from the obarray.")
512: (string, alist, pred)
513: Lisp_Object string, alist, pred;
514: {
515: Lisp_Object tail, elt, eltstring;
516: Lisp_Object allmatches;
517: int list = LISTP (alist);
518: int index, obsize;
519: Lisp_Object bucket, tem;
520:
521: CHECK_STRING (string, 0);
522: if (!list && XTYPE (alist) != Lisp_Vector)
523: {
524: return call3 (alist, string, pred, Qt);
525: }
526: allmatches = Qnil;
527:
528: if (list)
529: tail = alist;
530: else
531: {
532: index = 0;
533: obsize = XVECTOR (alist)->size;
534: bucket = XVECTOR (alist)->contents[index];
535: }
536:
537: while (1)
538: {
539: /* Get the next element of the alist or obarray. */
540: /* Exit the loop if the elements are all used up. */
541: /* elt gets the alist element or symbol.
542: eltstring gets the name to check as a completion. */
543:
544: if (list)
545: {
546: if (NULL (tail))
547: break;
548: elt = Fcar (tail);
549: eltstring = Fcar (elt);
550: tail = Fcdr (tail);
551: }
552: else
553: {
554: if (XSYMBOL (bucket))
555: {
556: elt = bucket;
557: eltstring = Fsymbol_name (elt);
558: XSETSYMBOL (bucket, XSYMBOL (bucket)->next);
559: }
560: else if (++index >= obsize)
561: break;
562: else
563: {
564: bucket = XVECTOR (alist)->contents[index];
565: continue;
566: }
567: }
568:
569: /* Is this element a possible completion? */
570:
571: if (XTYPE (eltstring) == Lisp_String &&
572: XSTRING (string)->size <= XSTRING (eltstring)->size &&
573: XSTRING (eltstring)->data[0] != ' ' &&
574: -1 == scmp (XSTRING (eltstring)->data, XSTRING (string)->data, XSTRING (string)->size))
575: {
576: /* Yes. */
577: /* Ignore this element if there is a predicate and the predicate doesn't like it. */
578:
579: if (!NULL (pred))
580: {
581: if (EQ (pred, Qcommandp))
582: tem = Fcommandp (elt);
583: else
584: tem = call1 (pred, elt);
585: if (NULL (tem)) continue;
586: }
587: /* Ok => put it on the list. */
588: allmatches = Fcons (eltstring, allmatches);
589: }
590: }
591:
592: return Fnreverse (allmatches);
593: }
594:
595: Lisp_Object Vminibuffer_completion_table, Qminibuffer_completion_table;
596: Lisp_Object Vminibuffer_completion_predicate, Qminibuffer_completion_predicate;
597: Lisp_Object Vminibuffer_completion_confirm, Qminibuffer_completion_confirm;
598:
599: DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 5, 0,
600: "Read a string in the minibuffer, with completion.\n\
601: Args are PROMPT, TABLE, PREDICATE, REQUIRE-MATCH and INITIAL-INPUT.\n\
602: PROMPT is a string to prompt with; normally it ends in a colon and a space.\n\
603: TABLE is an alist whose elements' cars are strings, or an obarray (see try-completion).\n\
604: PREDICATE limits completion to a subset of TABLE; see try-completion for details.\n\
605: If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless\n\
606: the input is (or completes to) an element of TABLE.\n\
607: If it is also not t, Return does not exit if it does non-null completion.\n\
608: If INITIAL-INPUT is non-nil, insert it in the minibuffer initially.\n\
609: Case is ignored if ambient value of completion-ignore-case is non-nil.")
610: (prompt, table, pred, require_match, init)
611: Lisp_Object prompt, table, pred, require_match, init;
612: {
613: Lisp_Object val;
614: int count = specpdl_ptr - specpdl;
615: specbind (Qminibuffer_completion_table, table);
616: specbind (Qminibuffer_completion_predicate, pred);
617: specbind (Qminibuffer_completion_confirm,
618: EQ (require_match, Qt) ? Qnil : Qt);
619: val = read_minibuf_string (NULL (require_match)
620: ? Vminibuffer_local_completion_map
621: : Vminibuffer_local_must_match_map,
622: init, prompt);
623: unbind_to (count);
624: return val;
625: }
626:
627: temp_minibuf_message (m)
628: char *m;
629: {
630: int osize = NumCharacters + 1;
631: Lisp_Object oinhibit;
632: oinhibit = Vinhibit_quit;
633:
634: SetPoint (osize);
635: InsStr (m);
636: SetPoint (osize);
637: Vinhibit_quit = Qt;
638: Fsit_for (make_number (2));
639: del_range (point, NumCharacters + 1);
640: if (!NULL (Vquit_flag))
641: {
642: Vquit_flag = Qnil;
643: unread_command_char = Ctl ('g');
644: }
645: Vinhibit_quit = oinhibit;
646: }
647:
648: Lisp_Object Fminibuffer_completion_help ();
649:
650: /* returns:
651: * 0 no possible completion
652: * 1 was already an exact and unique completion
653: * 3 was already an exact completion
654: * 4 completed to an exact completion
655: * 5 some completion happened
656: * 6 no completion happened
657: */
658: int
659: do_completion ()
660: {
661: Lisp_Object completion, tem;
662: int completedp = 0;
663:
664: completion = Ftry_completion (Fbuffer_string (), Vminibuffer_completion_table,
665: Vminibuffer_completion_predicate);
666: if (NULL (completion))
667: {
668: Ding ();
669: temp_minibuf_message (" [No match]");
670: return 0;
671: }
672:
673: if (EQ (completion, Qt)) /* exact and unique match */
674: return 1;
675:
676: /* compiler bug */
677: tem = Fstring_equal (completion, Fbuffer_string());
678: if (completedp = NULL (tem))
679: {
680: Ferase_buffer (); /* Some completion happened */
681: Finsert (1, &completion);
682: }
683:
684: /* It did find a match. Do we match some possibility exactly now? */
685: if (LISTP (Vminibuffer_completion_table))
686: tem = Fassoc (Fbuffer_string (), Vminibuffer_completion_table);
687: else if (XTYPE (Vminibuffer_completion_table) == Lisp_Vector)
688: {
689: /* the primitive used by Fintern_soft */
690: extern Lisp_Object oblookup ();
691:
692: tem = Fbuffer_string ();
693: /* Bypass intern-soft as that loses for nil */
694: tem = oblookup (Vminibuffer_completion_table,
695: XSTRING (tem)->data, XSTRING (tem)->size);
696: if (XTYPE (tem) != Lisp_Symbol)
697: tem = Qnil;
698: else if (!NULL (Vminibuffer_completion_predicate))
699: tem = call1 (Vminibuffer_completion_predicate, tem);
700: else
701: tem = Qt;
702: }
703: else
704: tem = call3 (Vminibuffer_completion_table,
705: Fbuffer_string (),
706: Vminibuffer_completion_predicate,
707: Qlambda);
708:
709: if (NULL (tem))
710: { /* not an exact match */
711: if (completedp)
712: return 5;
713: else if (auto_help)
714: Fminibuffer_completion_help ();
715: else
716: temp_minibuf_message (" [Next char not unique]");
717: return 6;
718: }
719: else
720: return (completedp ? 4 : 3);
721: }
722:
723:
724: DEFUN ("minibuffer-complete", Fminibuffer_complete, Sminibuffer_complete, 0, 0, "",
725: "Complete the minibuffer contents as far as possible.")
726: ()
727: {
728: register int i = do_completion ();
729: switch (i)
730: {
731: case 0:
732: return Qnil;
733:
734: case 1:
735: temp_minibuf_message(" [Sole completion]");
736: break;
737:
738: case 3:
739: temp_minibuf_message(" [Complete, but not unique]");
740: break;
741: }
742: return Qt;
743: }
744:
745: DEFUN ("minibuffer-complete-and-exit", Fminibuffer_complete_and_exit,
746: Sminibuffer_complete_and_exit, 0, 0, "",
747: "Complete the minibuffer contents, and maybe exit.\n\
748: Exit if the name is valid with no completion needed.\n\
749: If name was completed to a valid match,\n\
750: a repetition of this command will exit.")
751: ()
752: {
753: register int i;
754:
755: /* Allow user to specify null string */
756: if (NumCharacters == 0)
757: goto exit;
758:
759: i = do_completion ();
760: switch (i)
761: {
762: case 1:
763: case 3:
764: goto exit;
765:
766: case 4:
767: if (!NULL (Vminibuffer_completion_confirm))
768: {
769: temp_minibuf_message(" [Confirm]");
770: return Qnil;
771: }
772: else
773: goto exit;
774:
775: default:
776: return Qnil;
777: }
778: exit:
779: Fthrow (Qexit, Qnil);
780: /* NOTREACHED */
781: }
782:
783: DEFUN ("minibuffer-complete-word", Fminibuffer_complete_word, Sminibuffer_complete_word,
784: 0, 0, "",
785: "Complete the minibuffer contents at most a single word.")
786: ()
787: {
788: Lisp_Object completion, tem;
789: register unsigned char *b;
790: register unsigned char *p;
791: register int i;
792:
793: /* We keep calling Fbuffer_string
794: rather than arrange for GC to hold onto a pointer to
795: one of the strings thus made. */
796:
797: completion = Ftry_completion (Fbuffer_string (),
798: Vminibuffer_completion_table,
799: Vminibuffer_completion_predicate);
800: if (NULL (completion))
801: {
802: Ding ();
803: temp_minibuf_message (" [No match]");
804: return Qnil;
805: }
806: if (EQ (completion, Qt))
807: return Qnil;
808:
809: tem = Fbuffer_string ();
810: b = XSTRING (tem)->data;
811: i = NumCharacters - XSTRING (completion)->size;
812: p = XSTRING (completion)->data;
813: if (i > 0 ||
814: 0 <= scmp (b, p, NumCharacters))
815: {
816: i = 1;
817: /* Set buffer to longest match of buffer tail and completion head. */
818: while (0 <= scmp (b + i, p, NumCharacters - i))
819: i++;
820: del_range (1, i + 1);
821: SetPoint (NumCharacters + 1);
822: }
823:
824: i = NumCharacters;
825:
826: /* If completion finds next char not unique,
827: consider adding a space or a hyphen */
828: if (i == XSTRING (completion)->size)
829: {
830: tem = Ftry_completion (concat2 (Fbuffer_string (), build_string (" ")),
831: Vminibuffer_completion_table,
832: Vminibuffer_completion_predicate);
833: if (XTYPE (tem) == Lisp_String)
834: completion = tem;
835: else
836: {
837: tem = Ftry_completion (concat2 (Fbuffer_string (), build_string ("-")),
838: Vminibuffer_completion_table,
839: Vminibuffer_completion_predicate);
840: if (XTYPE (tem) == Lisp_String)
841: completion = tem;
842: }
843: }
844:
845: /* Now find first word-break in the stuff found by completion.
846: i gets index in string of where to stop completing. */
847: p = XSTRING (completion)->data;
848:
849: for (; i < XSTRING (completion)->size; i++)
850: if (SYNTAX (p[i]) != Sword) break;
851: if (i < XSTRING (completion)->size)
852: i = i + 1;
853:
854: /* If got no characters, print help for user. */
855:
856: if (i == NumCharacters)
857: {
858: if (auto_help)
859: Fminibuffer_completion_help ();
860: return Qnil;
861: }
862:
863: /* Otherwise insert in minibuffer the chars we got */
864:
865: Ferase_buffer ();
866: InsCStr (p, i);
867: return Qt;
868: }
869:
870: Lisp_Object
871: minibuffer_completion_help_1 (completions)
872: Lisp_Object completions;
873: {
874: register Lisp_Object tail;
875: register int i;
876: struct buffer *old = bf_cur;
877: SetBfp (XBUFFER (Vstandard_output));
878:
879: if (NULL (completions))
880: InsStr ("There are no possible completions of what you have typed.");
881: else
882: {
883: InsStr ("Possible completions are:");
884: for (tail = completions, i = 0; !NULL (tail); tail = Fcdr (tail), i++)
885: {
886: /* this needs fixing for the case of long completions
887: and/or narrow windows */
888: /* Sadly, the window it will appear in is not known
889: until after the text has been made. */
890: if (i & 1)
891: Findent_to (make_number (35), make_number (1));
892: else
893: Fterpri (Qnil);
894: Fprinc (Fcar (tail), Qnil);
895: }
896: }
897: SetBfp (old);
898: return Qnil;
899: }
900:
901: DEFUN ("minibuffer-completion-help", Fminibuffer_completion_help, Sminibuffer_completion_help,
902: 0, 0, "",
903: "Display a list of possible completions of the current minibuffer contents.")
904: ()
905: {
906: Lisp_Object completions;
907: message ("Making completion list...");
908: completions = Fall_completions (Fbuffer_string (), Vminibuffer_completion_table,
909: Vminibuffer_completion_predicate);
910: minibuf_message = 0;
911: if (NULL (completions))
912: { Ding ();
913: temp_minibuf_message (" [No completions]"); }
914: else
915: internal_with_output_to_temp_buffer (" *Completions*",
916: minibuffer_completion_help_1,
917: Fsort (completions, Qstring_lessp));
918: return Qnil;
919: }
920:
921: DEFUN ("self-insert-and-exit", Fself_insert_and_exit, Sself_insert_and_exit, 0, 0, "",
922: "Terminate minibuffer input.")
923: ()
924: {
925: SelfInsert (last_command_char);
926: Fthrow (Qexit, Qnil);
927: }
928:
929: DEFUN ("exit-minibuffer", Fexit_minibuffer, Sexit_minibuffer, 0, 0, "",
930: "Terminate this minibuffer argument.")
931: ()
932: {
933: Fthrow (Qexit, Qnil);
934: }
935:
936: init_minibuf_once ()
937: {
938: Vminibuffer_list = Qnil;
939: staticpro (&Vminibuffer_list);
940: }
941:
942: syms_of_minibuf ()
943: {
944: MinibufDepth = 0;
945: minibuf_prompt = 0;
946: minibuf_save_vector_size = 5;
947: minibuf_save_vector = (struct minibuf_save_data *) malloc (5 * sizeof (struct minibuf_save_data));
948:
949: Qminibuffer_completion_table = intern ("minibuffer-completion-table");
950: staticpro (&Qminibuffer_completion_table);
951:
952: Qminibuffer_completion_confirm = intern ("minibuffer-completion-confirm");
953: staticpro (&Qminibuffer_completion_confirm);
954:
955: Qminibuffer_completion_predicate = intern ("minibuffer-completion-predicate");
956: staticpro (&Qminibuffer_completion_predicate);
957:
958: staticpro (&last_minibuf_string);
959: last_minibuf_string = Qnil;
960:
961: Quser_variable_p = intern ("user-variable-p");
962: staticpro (&Quser_variable_p);
963:
964:
965:
966: DefBoolVar ("completion-auto-help", &auto_help,
967: "*Non-nil means automatically provide help for invalid completion input.");
968: auto_help = 1;
969:
970: DefBoolVar ("completion-ignore-case", &completion_ignore_case,
971: "Non-nil means don't consider case significant in completion.");
972: completion_ignore_case = 0;
973:
974: DefBoolVar ("enable-recursive-minibuffers", &enable_recursive_minibuffers,
975: "*Non-nil means to allow minibuffers to invoke commands which use\n\
976: recursive minibuffers.");
977: enable_recursive_minibuffers = 0;
978:
979: DefLispVar ("minibuffer-completion-table", &Vminibuffer_completion_table,
980: "Alist or obarray used for completion in the minibuffer.");
981: Vminibuffer_completion_table = Qnil;
982:
983: DefLispVar ("minibuffer-completion-predicate", &Vminibuffer_completion_predicate,
984: "Holds PREDICATE argument to completing-read.");
985: Vminibuffer_completion_predicate = Qnil;
986:
987: DefLispVar ("minibuffer-completion-confirm", &Vminibuffer_completion_confirm,
988: "Non-nil => demand confirmation of completion before exiting minibuffer.");
989: Vminibuffer_completion_confirm = Qnil;
990:
991: DefLispVar ("minibuffer-help-form", &Vminibuffer_help_form,
992: "Value that help-form takes on inside the minibuffer.");
993: Vminibuffer_help_form = Qnil;
994:
995: defsubr (&Sread_from_minibuffer);
996: defsubr (&Seval_minibuffer);
997: defsubr (&Sread_minibuffer);
998: defsubr (&Sread_string);
999: defalias (&Sread_string, "read-input");
1000: defsubr (&Sread_command);
1001: defsubr (&Sread_variable);
1002: defsubr (&Sread_buffer);
1003: defsubr (&Sread_no_blanks_input);
1004:
1005: defsubr (&Stry_completion);
1006: defsubr (&Sall_completions);
1007: defsubr (&Scompleting_read);
1008: defsubr (&Sminibuffer_complete);
1009: defsubr (&Sminibuffer_complete_word);
1010: defsubr (&Sminibuffer_complete_and_exit);
1011: defsubr (&Sminibuffer_completion_help);
1012:
1013: defsubr (&Sself_insert_and_exit);
1014: defsubr (&Sexit_minibuffer);
1015:
1016: }
1017:
1018: keys_of_minibuf ()
1019: {
1020: ndefkey (Vminibuffer_local_map, Ctl ('g'), "abort-recursive-edit");
1021: ndefkey (Vminibuffer_local_map, Ctl ('m'), "exit-minibuffer");
1022: ndefkey (Vminibuffer_local_map, Ctl ('j'), "exit-minibuffer");
1023:
1024: ndefkey (Vminibuffer_local_ns_map, Ctl ('g'), "abort-recursive-edit");
1025: ndefkey (Vminibuffer_local_ns_map, Ctl ('m'), "exit-minibuffer");
1026: ndefkey (Vminibuffer_local_ns_map, Ctl ('j'), "exit-minibuffer");
1027:
1028: ndefkey (Vminibuffer_local_ns_map, ' ', "exit-minibuffer");
1029: ndefkey (Vminibuffer_local_ns_map, '\t', "exit-minibuffer");
1030: ndefkey (Vminibuffer_local_ns_map, '?', "self-insert-and-exit");
1031:
1032: ndefkey (Vminibuffer_local_completion_map, Ctl ('g'), "abort-recursive-edit");
1033: ndefkey (Vminibuffer_local_completion_map, Ctl ('m'), "exit-minibuffer");
1034: ndefkey (Vminibuffer_local_completion_map, Ctl ('j'), "exit-minibuffer");
1035: ndefkey (Vminibuffer_local_completion_map, '\t', "minibuffer-complete");
1036: ndefkey (Vminibuffer_local_completion_map, ' ', "minibuffer-complete-word");
1037: ndefkey (Vminibuffer_local_completion_map, '?', "minibuffer-completion-help");
1038:
1039: ndefkey (Vminibuffer_local_must_match_map, Ctl ('g'), "abort-recursive-edit");
1040: ndefkey (Vminibuffer_local_must_match_map, Ctl ('m'), "minibuffer-complete-and-exit");
1041: ndefkey (Vminibuffer_local_must_match_map, Ctl ('j'), "minibuffer-complete-and-exit");
1042: ndefkey (Vminibuffer_local_must_match_map, '\t', "minibuffer-complete");
1043: ndefkey (Vminibuffer_local_must_match_map, ' ', "minibuffer-complete-word");
1044: ndefkey (Vminibuffer_local_must_match_map, '?', "minibuffer-completion-help");
1045: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.