comparison src/minibuf.c @ 5634:2014ff433daf

Support hash COLLECTIONs, #'{all,try}-completion{s,}; add #'test-completion src/ChangeLog addition: 2012-01-01 Aidan Kehoe <kehoea@parhasard.net> Add #'test-completion, API from GNU. Accept hash table COLLECTIONs in it and in the other completion-oriented functions, #'try-completion, #'all-completions, and those Lisp functions implemented in terms of them. * lisp.h: Update the prototype of map_obarray(), making FN compatible with the FUNCTION argument of elisp_maphash(); * abbrev.c (abbrev_match_mapper): * abbrev.c (record_symbol): * doc.c (verify_doc_mapper): * symbols.c (mapatoms_1): * symbols.c (apropos_mapper): Update these mapper functions to reflect the new argument to map_obarray(). * symbols.c (map_obarray): Call FN with two arguments, the string name of the symbol, and the symbol itself, for API (mapper) compatibility with elisp_maphash(). * minibuf.c (map_completion): New. Map a maphash_function_t across a non function COLLECTION, as appropriate for #'try-completion and friends. * minibuf.c (map_completion_list): New. Map a maphash_function_t across a pseudo-alist, as appropriate for the completion functions. * minibuf.c (ignore_completion_p): PRED needs to be called with two args if and only if the collection is a hash table. Implement this. * minibuf.c (try_completion_mapper): New. The loop body of #'try-completion, refactored out. * minibuf.c (Ftry_completion): Use try_completion_mapper(), map_completion(). * minibuf.c (all_completions_mapper): New. The loop body of #'all-completions, refactored out. * minibuf.c (Fall_completions): Use all_completions_mapper(), map_completion(). * minibuf.c (test_completion_mapper): New. The loop body of #'test-completion. * minibuf.c (Ftest_completion): New, API from GNU. * minibuf.c (syms_of_minibuf): Make Ftest_completion available. tests/ChangeLog addition: 2012-01-01 Aidan Kehoe <kehoea@parhasard.net> * automated/completion-tests.el: New. Test #'try-completion, #'all-completion and #'test-completion with list, vector and hash-table COLLECTION arguments.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 01 Jan 2012 15:18:52 +0000
parents 56144c8593a8
children daf5accfe973
comparison
equal deleted inserted replaced
5633:49c36ed998b6 5634:2014ff433daf
33 #include "events.h" 33 #include "events.h"
34 #include "frame-impl.h" 34 #include "frame-impl.h"
35 #include "insdel.h" 35 #include "insdel.h"
36 #include "redisplay.h" 36 #include "redisplay.h"
37 #include "window-impl.h" 37 #include "window-impl.h"
38 #include "elhash.h"
38 39
39 /* Depth in minibuffer invocations. */ 40 /* Depth in minibuffer invocations. */
40 int minibuf_level; 41 int minibuf_level;
41 42
42 Lisp_Object Qcompletion_ignore_case; 43 Lisp_Object Qcompletion_ignore_case;
242 if (l == 0) 243 if (l == 0)
243 return -1; 244 return -1;
244 else return len - l; 245 else return len - l;
245 } 246 }
246 247
248 /* Map FUNCTION, a C function, across LISZT, a pseudo-alist, calling
249 it with three args, ELTSTRING (the car of the element if a cons,
250 otherwise the element itself), ELT (the element, always) and
251 EXTRA_ARG. Stop if FUNCTION returns non-zero. */
252 static void
253 map_completion_list (maphash_function_t function, Lisp_Object liszt,
254 void *extra_arg)
255 {
256 Lisp_Object eltstring;
257
258 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt)
259 {
260 eltstring = CONSP (elt) ? XCAR (elt) : elt;
261 if (function (eltstring, elt, extra_arg))
262 {
263 XUNGCPRO (elt);
264 return;
265 }
266 }
267 END_GC_EXTERNAL_LIST_LOOP (elt);
268 }
269
270 static void
271 map_completion (maphash_function_t function, Lisp_Object collection,
272 void *extra_arg, Lisp_Object predicate)
273 {
274 if (LISTP (collection))
275 {
276 map_completion_list (function, collection, extra_arg);
277 }
278 else if (VECTORP (collection))
279 {
280 map_obarray (collection, function, extra_arg);
281 }
282 else if (NILP (predicate))
283 {
284 /* This can't call Lisp, no need to copy and compress the hash
285 table entries. */
286 elisp_maphash_unsafe (function, collection, extra_arg);
287 }
288 else
289 {
290 elisp_maphash (function, collection, extra_arg);
291 }
292 }
247 293
248 int 294 int
249 regexp_ignore_completion_p (const Ibyte *nonreloc, 295 regexp_ignore_completion_p (const Ibyte *nonreloc,
250 Lisp_Object reloc, Bytecount offset, 296 Lisp_Object reloc, Bytecount offset,
251 Bytecount length) 297 Bytecount length)
262 } 308 }
263 } 309 }
264 return 0; 310 return 0;
265 } 311 }
266 312
267
268 /* Callers should GCPRO, since this may call eval */ 313 /* Callers should GCPRO, since this may call eval */
269 static int 314 static int
270 ignore_completion_p (Lisp_Object completion_string, 315 ignore_completion_p (Lisp_Object completion_string,
271 Lisp_Object pred, Lisp_Object completion) 316 Lisp_Object pred, Lisp_Object completion,
272 { 317 Boolint hash_tablep)
318 {
319 Lisp_Object tem;
320
273 if (regexp_ignore_completion_p (0, completion_string, 0, -1)) 321 if (regexp_ignore_completion_p (0, completion_string, 0, -1))
274 return 1; 322 return 1;
275 323
276 /* Ignore this element if there is a predicate 324 if (NILP (pred))
277 and the predicate doesn't like it. */ 325 {
278 if (!NILP (pred)) 326 return 0;
279 { 327 }
280 Lisp_Object tem; 328
281 if (EQ (pred, Qcommandp)) 329 /* Ignore this element if there is a predicate and the predicate doesn't
330 like it. */
331 if (hash_tablep)
332 {
333 tem = call2 (pred, completion_string, completion);
334 }
335 else if (EQ (pred, Qcommandp))
336 {
282 tem = Fcommandp (completion); 337 tem = Fcommandp (completion);
283 else 338 }
339 else
340 {
284 tem = call1 (pred, completion); 341 tem = call1 (pred, completion);
285 if (NILP (tem)) 342 }
286 return 1; 343
287 } 344 return NILP (tem);
345 }
346
347 struct try_completion_closure
348 {
349 Lisp_Object string;
350 Charcount slength;
351 Lisp_Object predicate;
352 Lisp_Object bestmatch;
353 Charcount blength;
354 Charcount bestmatchsize;
355 Boolint hash_tablep;
356 int matchcount;
357 };
358
359 static int
360 try_completion_mapper (Lisp_Object eltstring, Lisp_Object value,
361 void *arg)
362 {
363 struct try_completion_closure *tcc = (struct try_completion_closure *) arg;
364 Charcount eltlength;
365
366 if (SYMBOLP (eltstring))
367 {
368 eltstring = XSYMBOL_NAME (eltstring);
369 }
370
371 if (!STRINGP (eltstring))
372 {
373 return 0;
374 }
375
376 /* Is this element a possible completion? */
377 eltlength = string_char_length (eltstring);
378 if (tcc->slength <= eltlength
379 && (0 > scmp (XSTRING_DATA (eltstring), XSTRING_DATA (tcc->string),
380 tcc->slength)))
381 {
382 struct gcpro gcpro1, gcpro2, gcpro3;
383 int loser;
384 GCPRO3 (tcc->string, eltstring, tcc->bestmatch);
385 loser = ignore_completion_p (eltstring, tcc->predicate, value,
386 tcc->hash_tablep);
387 UNGCPRO;
388 if (loser) /* reject this one */
389 {
390 return 0;
391 }
392
393 /* Update computation of how much all possible completions
394 match */
395
396 tcc->matchcount++;
397 if (NILP (tcc->bestmatch))
398 {
399 tcc->bestmatch = eltstring;
400 tcc->blength = eltlength;
401 tcc->bestmatchsize = eltlength;
402 }
403 else
404 {
405 Charcount compare = min (tcc->bestmatchsize, eltlength);
406 Charcount matchsize =
407 scmp (XSTRING_DATA (tcc->bestmatch), XSTRING_DATA (eltstring),
408 compare);
409 if (matchsize < 0)
410 matchsize = compare;
411 if (completion_ignore_case)
412 {
413 /* If this is an exact match except for case, use it as
414 the best match rather than one that is not an exact
415 match. This way, we get the case pattern of the
416 actual match. */
417 if ((matchsize == eltlength
418 && matchsize < tcc->blength)
419 ||
420 /* If there is more than one exact match ignoring
421 case, and one of them is exact including case,
422 prefer that one. */
423 /* If there is no exact match ignoring case,
424 prefer a match that does not change the case of
425 the input. */
426 ((matchsize == eltlength)
427 ==
428 (matchsize == tcc->blength)
429 && 0 > scmp_1 (XSTRING_DATA (eltstring),
430 XSTRING_DATA (tcc->string),
431 tcc->slength, 0)
432 && 0 <= scmp_1 (XSTRING_DATA (tcc->bestmatch),
433 XSTRING_DATA (tcc->string),
434 tcc->slength, 0)))
435 {
436 tcc->bestmatch = eltstring;
437 tcc->blength = eltlength;
438 }
439 }
440 tcc->bestmatchsize = matchsize;
441 }
442 }
443
288 return 0; 444 return 0;
289 } 445 }
290
291
292 /* #### Maybe we should allow COLLECTION to be a hash table.
293 It is wrong for the use of obarrays to be better-rewarded than the
294 use of hash tables. By better-rewarded I mean that you can pass an
295 obarray to all of the completion functions, whereas you can't do
296 anything like that with a hash table.
297
298 To do so, there should probably be a
299 map_obarray_or_alist_or_hash_table function which would be used by
300 both Ftry_completion and Fall_completions. [[ But would the
301 additional funcalls slow things down? ]] Seriously doubtful. --ben */
302 446
303 DEFUN ("try-completion", Ftry_completion, 2, 3, 0, /* 447 DEFUN ("try-completion", Ftry_completion, 2, 3, 0, /*
304 Return common substring of all completions of STRING in COLLECTION. 448 Return common substring of all completions of STRING in COLLECTION.
305 COLLECTION must be an alist, an obarray, or a function. 449 COLLECTION must be a list, a hash table, an obarray, or a function.
306 Each string in COLLECTION is tested to see if it begins with STRING. 450
307 All that match are compared together; the longest initial sequence 451 Each string (or symbol) in COLLECTION is tested to see if it (or its
308 common to all matches is returned as a string. If there is no match 452 name) begins with STRING. All that match are compared together; the
309 at all, nil is returned. For an exact match, t is returned. 453 longest initial sequence common to all matches is returned as a
310 454 string. If there is no match at all, nil is returned. For an exact
311 If COLLECTION is list, the elements of the list that are not cons 455 match, t is returned.
456
457 If COLLECTION is a list, the elements of the list that are not cons
312 cells and the cars of the elements of the list that are cons cells 458 cells and the cars of the elements of the list that are cons cells
313 (which must be strings) form the set of possible completions. 459 \(which must be strings or symbols) form the set of possible
460 completions.
461
462 If COLLECTION is a hash table, all the keys that are strings or symbols
463 are the possible completions.
314 464
315 If COLLECTION is an obarray, the names of all symbols in the obarray 465 If COLLECTION is an obarray, the names of all symbols in the obarray
316 are the possible completions. 466 are the possible completions.
317 467
318 If COLLECTION is a function, it is called with three arguments: the 468 If COLLECTION is a function, it is called with three arguments: the
320 value of `try-completion'. 470 value of `try-completion'.
321 471
322 If optional third argument PREDICATE is non-nil, it is used to test 472 If optional third argument PREDICATE is non-nil, it is used to test
323 each possible match. The match is a candidate only if PREDICATE 473 each possible match. The match is a candidate only if PREDICATE
324 returns non-nil. The argument given to PREDICATE is the alist element 474 returns non-nil. The argument given to PREDICATE is the alist element
325 or the symbol from the obarray. 475 or the symbol from the obarray. If COLLECTION is a hash table,
476 PREDICATE is passed two arguments, the key and the value of the hash
477 table entry.
326 */ 478 */
327 (string, collection, predicate)) 479 (string, collection, predicate))
328 { 480 {
329 /* This function can GC */ 481 /* This function can GC */
330 Lisp_Object bestmatch, tail; 482 struct try_completion_closure tcc;
331 Charcount bestmatchsize = 0;
332 int list;
333 int indice = 0;
334 int matchcount = 0;
335 int obsize;
336 Lisp_Object bucket;
337 Charcount slength, blength;
338 483
339 CHECK_STRING (string); 484 CHECK_STRING (string);
340 485
341 if (CONSP (collection)) 486 if (!NILP (Ffunctionp (collection)))
342 { 487 {
343 Lisp_Object tem = XCAR (collection); 488 return call3 (collection, string, predicate, Qnil);
344 if (SYMBOLP (tem)) /* lambda, autoload, etc. Emacs-lisp sucks */ 489 }
345 return call3 (collection, string, predicate, Qnil); 490
346 else 491 if (!(LISTP (collection) || VECTORP (collection) || HASH_TABLEP (collection)))
347 list = 1; 492 {
348 } 493 signal_error (Qwrong_type_argument,
349 else if (VECTORP (collection)) 494 "must be a list, vector, hash table or function",
350 list = 0; 495 collection);
351 else if (NILP (collection)) 496 }
352 list = 1; 497
353 else 498 tcc.string = string;
354 return call3 (collection, string, predicate, Qnil); 499 tcc.slength = string_char_length (string);
355 500 tcc.bestmatch = Qnil;
356 bestmatch = Qnil; 501 tcc.blength = 0;
357 blength = 0; 502 tcc.bestmatchsize = 0;
358 slength = string_char_length (string); 503 tcc.predicate = predicate;
359 504 tcc.hash_tablep = HASH_TABLEP (collection);
360 /* If COLLECTION is not a list, set TAIL just for gc pro. */ 505 tcc.matchcount = 0;
361 tail = collection; 506
362 if (!list) 507 map_completion (try_completion_mapper, collection, &tcc, predicate);
363 { 508
364 obsize = XVECTOR_LENGTH (collection); 509 if (NILP (tcc.bestmatch))
365 bucket = XVECTOR_DATA (collection)[indice];
366 }
367 else /* warning suppression */
368 {
369 obsize = 0;
370 bucket = Qnil;
371 }
372
373 while (1)
374 {
375 /* Get the next element of the alist or obarray. */
376 /* Exit the loop if the elements are all used up. */
377 /* elt gets the alist element or symbol.
378 eltstring gets the name to check as a completion. */
379 Lisp_Object elt;
380 Lisp_Object eltstring;
381
382 if (list)
383 {
384 if (NILP (tail))
385 break;
386 elt = Fcar (tail);
387 if (CONSP (elt))
388 eltstring = Fcar (elt);
389 else
390 eltstring = elt;
391 tail = Fcdr (tail);
392 }
393 else
394 {
395 if (!ZEROP (bucket))
396 {
397 Lisp_Symbol *next;
398 if (!SYMBOLP (bucket))
399 {
400 invalid_argument ("Bad obarray passed to try-completions",
401 bucket);
402 }
403 next = symbol_next (XSYMBOL (bucket));
404 elt = bucket;
405 eltstring = Fsymbol_name (elt);
406 if (next)
407 bucket = wrap_symbol (next);
408 else
409 bucket = Qzero;
410 }
411 else if (++indice >= obsize)
412 break;
413 else
414 {
415 bucket = XVECTOR_DATA (collection)[indice];
416 continue;
417 }
418 }
419
420 /* Is this element a possible completion? */
421
422 if (STRINGP (eltstring))
423 {
424 Charcount eltlength = string_char_length (eltstring);
425 if (slength <= eltlength
426 && (0 > scmp (XSTRING_DATA (eltstring),
427 XSTRING_DATA (string),
428 slength)))
429 {
430 {
431 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
432 int loser;
433 GCPRO4 (tail, string, eltstring, bestmatch);
434 loser = ignore_completion_p (eltstring, predicate, elt);
435 UNGCPRO;
436 if (loser) /* reject this one */
437 continue;
438 }
439
440 /* Update computation of how much all possible
441 completions match */
442
443 matchcount++;
444 if (NILP (bestmatch))
445 {
446 bestmatch = eltstring;
447 blength = eltlength;
448 bestmatchsize = eltlength;
449 }
450 else
451 {
452 Charcount compare = min (bestmatchsize, eltlength);
453 Charcount matchsize =
454 scmp (XSTRING_DATA (bestmatch),
455 XSTRING_DATA (eltstring),
456 compare);
457 if (matchsize < 0)
458 matchsize = compare;
459 if (completion_ignore_case)
460 {
461 /* If this is an exact match except for case,
462 use it as the best match rather than one that is not
463 an exact match. This way, we get the case pattern
464 of the actual match. */
465 if ((matchsize == eltlength
466 && matchsize < blength)
467 ||
468 /* If there is more than one exact match ignoring
469 case, and one of them is exact including case,
470 prefer that one. */
471 /* If there is no exact match ignoring case,
472 prefer a match that does not change the case
473 of the input. */
474 ((matchsize == eltlength)
475 ==
476 (matchsize == blength)
477 && 0 > scmp_1 (XSTRING_DATA (eltstring),
478 XSTRING_DATA (string),
479 slength, 0)
480 && 0 <= scmp_1 (XSTRING_DATA (bestmatch),
481 XSTRING_DATA (string),
482 slength, 0)))
483 {
484 bestmatch = eltstring;
485 blength = eltlength;
486 }
487 }
488 bestmatchsize = matchsize;
489 }
490 }
491 }
492 }
493
494 if (NILP (bestmatch))
495 return Qnil; /* No completions found */ 510 return Qnil; /* No completions found */
496 /* If we are ignoring case, and there is no exact match, 511
497 and no additional text was supplied, 512 /* If we are ignoring case, and there is no exact match, and no
498 don't change the case of what the user typed. */ 513 additional text was supplied, don't change the case of what the
499 if (completion_ignore_case 514 user typed. */
500 && bestmatchsize == slength 515 if (completion_ignore_case && tcc.bestmatchsize == tcc.slength
501 && blength > bestmatchsize) 516 && tcc.blength > tcc.bestmatchsize)
502 return string; 517 return string;
503 518
504 /* Return t if the supplied string is an exact match (counting case); 519 /* Return t if the supplied string is an exact match (counting
505 it does not require any change to be made. */ 520 case); it does not require any change to be made. */
506 if (matchcount == 1 521 if (tcc.matchcount == 1 && tcc.bestmatchsize == tcc.slength
507 && bestmatchsize == slength 522 && 0 > scmp_1 (XSTRING_DATA (tcc.bestmatch), XSTRING_DATA (tcc.string),
508 && 0 > scmp_1 (XSTRING_DATA (bestmatch), 523 tcc.bestmatchsize, 0))
509 XSTRING_DATA (string),
510 bestmatchsize, 0))
511 return Qt; 524 return Qt;
512 525
513 /* Else extract the part in which all completions agree */ 526 /* Else extract the part in which all completions agree */
514 return Fsubseq (bestmatch, Qzero, make_fixnum (bestmatchsize)); 527 return Fsubseq (tcc.bestmatch, Qzero, make_fixnum (tcc.bestmatchsize));
515 } 528 }
516
517 529
530 struct all_completions_closure
531 {
532 Lisp_Object string;
533 Charcount slength;
534 Lisp_Object predicate;
535 Lisp_Object allmatches;
536 Boolint hash_tablep;
537 };
538
539 static int
540 all_completions_mapper (Lisp_Object eltstring, Lisp_Object value, void *arg)
541 {
542 struct all_completions_closure *acc = (struct all_completions_closure *) arg;
543 /* Is this element a possible completion? */
544
545 if (SYMBOLP (eltstring))
546 {
547 eltstring = XSYMBOL_NAME (eltstring);
548 }
549
550 if (STRINGP (eltstring) && (acc->slength <= string_char_length (eltstring))
551 /* Reject alternatives that start with space unless the input
552 starts with space. */
553 && ((acc->slength > 0 && string_ichar (acc->string, 0) == ' ')
554 || string_ichar (eltstring, 0) != ' ')
555 && (0 > scmp (XSTRING_DATA (eltstring), XSTRING_DATA (acc->string),
556 acc->slength)))
557 {
558 /* Yes. Now check whether predicate likes it. */
559 struct gcpro gcpro1, gcpro2;
560 int loser;
561 GCPRO2 (eltstring, acc->string);
562 loser = ignore_completion_p (eltstring, acc->predicate, value,
563 acc->hash_tablep);
564 UNGCPRO;
565 if (!loser)
566 {
567 /* Ok => put it on the list. */
568 XSETCDR (acc->allmatches, Fcons (eltstring, Qnil));
569 acc->allmatches = XCDR (acc->allmatches);
570 }
571 }
572
573 return 0;
574 }
575
518 DEFUN ("all-completions", Fall_completions, 2, 3, 0, /* 576 DEFUN ("all-completions", Fall_completions, 2, 3, 0, /*
519 Search for partial matches to STRING in COLLECTION. 577 Search for partial matches to STRING in COLLECTION.
520 COLLECTION must be an alist, an obarray, or a function. 578 COLLECTION must be an list, a hash table, an obarray, or a function.
521 Each string in COLLECTION is tested to see if it begins with STRING. 579
522 The value is a list of all the strings from COLLECTION that match. 580 Each string (or symbol) in COLLECTION is tested to see if it (or its
523 581 name) begins with STRING. The value is a list of all the strings from
524 If COLLECTION is an alist, the cars of the elements of the alist 582 COLLECTION that match.
525 \(which must be strings) form the set of possible completions. 583
584 If COLLECTION is a list, the elements of the list that are not cons
585 cells and the cars of the elements of the list that are cons cells
586 \(which must be strings or symbols) form the set of possible
587 completions.
588
589 If COLLECTION is a hash-table, all the keys that are strings or symbols
590 are the possible completions.
526 591
527 If COLLECTION is an obarray, the names of all symbols in the obarray 592 If COLLECTION is an obarray, the names of all symbols in the obarray
528 are the possible completions. 593 are the possible completions.
529 594
530 If COLLECTION is a function, it is called with three arguments: the 595 If COLLECTION is a function, it is called with three arguments: the
532 value of `all-completions'. 597 value of `all-completions'.
533 598
534 If optional third argument PREDICATE is non-nil, it is used to test 599 If optional third argument PREDICATE is non-nil, it is used to test
535 each possible match. The match is a candidate only if PREDICATE 600 each possible match. The match is a candidate only if PREDICATE
536 returns non-nil. The argument given to PREDICATE is the alist element 601 returns non-nil. The argument given to PREDICATE is the alist element
537 or the symbol from the obarray. 602 or the symbol from the obarray. If COLLECTION is a hash table,
603 PREDICATE is passed two arguments, the key and the value of the hash
604 table entry.
538 */ 605 */
539 (string, collection, predicate)) 606 (string, collection, predicate))
540 { 607 {
541 /* This function can GC */ 608 /* This function can GC */
542 Lisp_Object tail; 609 struct all_completions_closure acc;
543 Lisp_Object allmatches; 610 Lisp_Object allmatches = noseeum_cons (Qnil, Qnil);
544 int list; 611 struct gcpro gcpro1;
545 int indice = 0;
546 int obsize;
547 Lisp_Object bucket;
548 Charcount slength;
549 612
550 CHECK_STRING (string); 613 CHECK_STRING (string);
551 614
552 if (CONSP (collection)) 615 if (!NILP (Ffunctionp (collection)))
553 { 616 {
554 Lisp_Object tem = XCAR (collection); 617 return call3 (collection, string, predicate, Qt);
555 if (SYMBOLP (tem)) /* lambda, autoload, etc. Emacs-lisp sucks */ 618 }
556 return call3 (collection, string, predicate, Qt); 619
557 else 620 if (!(LISTP (collection) || VECTORP (collection) || HASH_TABLEP (collection)))
558 list = 1; 621 {
559 } 622 signal_error (Qwrong_type_argument,
560 else if (VECTORP (collection)) 623 "must be a list, vector, hash table or function",
561 list = 0; 624 collection);
562 else if (NILP (collection)) 625 }
563 list = 1; 626 GCPRO1 (allmatches);
627 acc.string = string;
628 acc.slength = string_char_length (string);
629 acc.predicate = predicate;
630 acc.allmatches = allmatches;
631 acc.hash_tablep = HASH_TABLEP (collection);
632
633 map_completion (all_completions_mapper, collection, &acc, predicate);
634
635 acc.allmatches = XCDR (allmatches);
636 free_cons (allmatches);
637 UNGCPRO;
638 return acc.allmatches;
639 }
640
641 struct test_completion_closure
642 {
643 Lisp_Object string;
644 Lisp_Object predicate;
645 Lisp_Object result;
646 Boolint hash_tablep;
647 };
648
649 static int
650 test_completion_mapper (Lisp_Object eltstring, Lisp_Object value, void *arg)
651 {
652 struct test_completion_closure *tcc = (struct test_completion_closure *) arg;
653
654 if (SYMBOLP (eltstring))
655 {
656 eltstring = XSYMBOL_NAME (eltstring);
657 }
658
659 if (!STRINGP (eltstring))
660 {
661 return 0;
662 }
663
664 if (completion_ignore_case ?
665 0 == qxetextcasecmp (XSTRING_DATA (tcc->string),
666 XSTRING_LENGTH (tcc->string),
667 XSTRING_DATA (eltstring),
668 XSTRING_LENGTH (eltstring))
669 : 0 == qxememcmp4 (XSTRING_DATA (tcc->string),
670 XSTRING_LENGTH (tcc->string),
671 XSTRING_DATA (eltstring),
672 XSTRING_LENGTH (eltstring)))
673 {
674 struct gcpro gcpro1, gcpro2, gcpro3;
675 int loser;
676 GCPRO3 (eltstring, tcc->string, tcc->predicate);
677 loser = ignore_completion_p (eltstring, tcc->predicate, value,
678 tcc->hash_tablep);
679 UNGCPRO;
680 if (!loser)
681 {
682 tcc->result = Qt;
683 return 1;
684 }
685 }
686
687 return 0;
688 }
689
690 DEFUN ("test-completion", Ftest_completion, 2, 3, 0, /*
691 Return non-nil if STRING is a valid completion in COLLECTION.
692
693 COLLECTION must be a list, a hash table, an obarray, or a function.
694
695 Each string (or symbol) in COLLECTION is tested to see if it (or its
696 name) begins with STRING. The value is a list of all the strings from
697 COLLECTION that match.
698
699 If COLLECTION is a list, the elements of the list that are not cons
700 cells and the cars of the elements of the list that are cons cells
701 \(which must be strings or symbols) form the set of possible
702 completions.
703
704 If COLLECTION is a hash-table, all the keys that are strings or symbols
705 are the possible completions.
706
707 If COLLECTION is an obarray, the names of all symbols in the obarray
708 are the possible completions.
709
710 If COLLECTION is a function, it is called with three arguments: the
711 values STRING, PREDICATE and the symbol `lambda'. Whatever it returns
712 is passed back by `test-completion'.
713
714 If optional third argument PREDICATE is non-nil, it is used to test
715 for possible matches. The match is a candidate only if PREDICATE
716 returns non-nil. The argument given to PREDICATE is the alist element
717 or the symbol from the obarray. If COLLECTION is a hash table,
718 PREDICATE is passed two arguments, the key and the value of the hash
719 table entry.
720 */
721 (string, collection, predicate))
722 {
723 struct test_completion_closure tcc;
724
725 CHECK_STRING (string);
726
727 if (!NILP (Ffunctionp (collection)))
728 {
729 return call3 (collection, string, predicate, Qlambda);
730 }
731
732 if (!(LISTP (collection) || VECTORP (collection) || HASH_TABLEP (collection)))
733 {
734 signal_error (Qwrong_type_argument,
735 "must be a list, vector, hash table or function",
736 collection);
737 }
738
739 tcc.string = string;
740 tcc.predicate = predicate;
741 tcc.result = Qnil;
742 tcc.hash_tablep = HASH_TABLEP (collection);
743
744 if (VECTORP (collection) && !completion_ignore_case)
745 {
746 /* We're case sensitive -> no need for a linear search. */
747 Lisp_Object lookup = Fintern_soft (string, collection, Qzero);
748
749 if (ZEROP (lookup))
750 {
751 return Qnil;
752 }
753
754 return ignore_completion_p (XSYMBOL_NAME (lookup), tcc.predicate,
755 lookup, 0) ? Qnil : Qt;
756
757 /* It would be reasonable to do something similar for the hash
758 tables, except, both symbol and string keys are vaild
759 completions there. So a negative #'gethash for the string
760 (with #'equal as the hash table tests) still means you have
761 to do the linear search, for any symbols with that string
762 name, which hash very differently; returning t is a little
763 quicker, but returning nil is just as slow, so our average
764 performance barely changes, at the cost of code
765 complexity. */
766 }
564 else 767 else
565 return call3 (collection, string, predicate, Qt); 768 {
566 769 map_completion (test_completion_mapper, collection, &tcc, predicate);
567 allmatches = Qnil; 770 }
568 slength = string_char_length (string); 771
569 772 return tcc.result;
570 /* If COLLECTION is not a list, set TAIL just for gc pro. */ 773 }
571 tail = collection; 774
572 if (!list)
573 {
574 obsize = XVECTOR_LENGTH (collection);
575 bucket = XVECTOR_DATA (collection)[indice];
576 }
577 else /* warning suppression */
578 {
579 obsize = 0;
580 bucket = Qnil;
581 }
582
583 while (1)
584 {
585 /* Get the next element of the alist or obarray. */
586 /* Exit the loop if the elements are all used up. */
587 /* elt gets the alist element or symbol.
588 eltstring gets the name to check as a completion. */
589 Lisp_Object elt;
590 Lisp_Object eltstring;
591
592 if (list)
593 {
594 if (NILP (tail))
595 break;
596 elt = Fcar (tail);
597 eltstring = Fcar (elt);
598 tail = Fcdr (tail);
599 }
600 else
601 {
602 if (!ZEROP (bucket))
603 {
604 Lisp_Symbol *next = symbol_next (XSYMBOL (bucket));
605 elt = bucket;
606 eltstring = Fsymbol_name (elt);
607 if (next)
608 bucket = wrap_symbol (next);
609 else
610 bucket = Qzero;
611 }
612 else if (++indice >= obsize)
613 break;
614 else
615 {
616 bucket = XVECTOR_DATA (collection)[indice];
617 continue;
618 }
619 }
620
621 /* Is this element a possible completion? */
622
623 if (STRINGP (eltstring)
624 && (slength <= string_char_length (eltstring))
625 /* Reject alternatives that start with space
626 unless the input starts with space. */
627 && ((string_char_length (string) > 0 &&
628 string_ichar (string, 0) == ' ')
629 || string_ichar (eltstring, 0) != ' ')
630 && (0 > scmp (XSTRING_DATA (eltstring),
631 XSTRING_DATA (string),
632 slength)))
633 {
634 /* Yes. Now check whether predicate likes it. */
635 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
636 int loser;
637 GCPRO4 (tail, eltstring, allmatches, string);
638 loser = ignore_completion_p (eltstring, predicate, elt);
639 UNGCPRO;
640 if (!loser)
641 /* Ok => put it on the list. */
642 allmatches = Fcons (eltstring, allmatches);
643 }
644 }
645
646 return Fnreverse (allmatches);
647 }
648 775
649 /* Useless FSFmacs functions */ 776 /* Useless FSFmacs functions */
650 /* More than useless. I've nuked minibuf_prompt_width so they won't 777 /* More than useless. I've nuked minibuf_prompt_width so they won't
651 function at all in XEmacs at the moment. They are used to 778 function at all in XEmacs at the moment. They are used to
652 implement some braindamage in FSF which we aren't including. --cet */ 779 implement some braindamage in FSF which we aren't including. --cet */
937 DEFSUBR (Fset_minibuffer_preprompt); 1064 DEFSUBR (Fset_minibuffer_preprompt);
938 DEFSUBR (Fread_minibuffer_internal); 1065 DEFSUBR (Fread_minibuffer_internal);
939 1066
940 DEFSUBR (Ftry_completion); 1067 DEFSUBR (Ftry_completion);
941 DEFSUBR (Fall_completions); 1068 DEFSUBR (Fall_completions);
1069 DEFSUBR (Ftest_completion);
942 1070
943 DEFSYMBOL (Qappend_message); 1071 DEFSYMBOL (Qappend_message);
944 DEFSYMBOL (Qclear_message); 1072 DEFSYMBOL (Qclear_message);
945 DEFSYMBOL (Qdisplay_message); 1073 DEFSYMBOL (Qdisplay_message);
946 DEFSYMBOL (Qcurrent_message_label); 1074 DEFSYMBOL (Qcurrent_message_label);