Annotation of 43BSD/contrib/emacs/src/minibuf.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.