Function: test-completion

test-completion is a function defined in minibuf.c.

Signature

(test-completion STRING COLLECTION &optional PREDICATE)

Documentation

Return non-nil if STRING is a valid completion.

For instance, if COLLECTION is a list of strings, STRING is a valid completion if it appears in the list and PREDICATE is satisfied.

Takes the same arguments as all-completions and try-completion.

If COLLECTION is a function, it is called with three arguments: the values STRING, PREDICATE and lambda.

View in manual

Probably introduced at or before Emacs version 22.1.

Aliases

mh-test-completion (obsolete since 29.1)

Source Code

// Defined in /usr/src/emacs/src/minibuf.c
{
  Lisp_Object tail, tem = Qnil;
  ptrdiff_t i = 0;

  CHECK_STRING (string);

  if (NILP (collection) || (CONSP (collection) && !FUNCTIONP (collection)))
    {
      tem = Fassoc_string (string, collection, completion_ignore_case ? Qt : Qnil);
      if (NILP (tem))
	return Qnil;
    }
  else if (VECTORP (collection))
    {
      /* Bypass intern-soft as that loses for nil.  */
      tem = oblookup (collection,
		      SSDATA (string),
		      SCHARS (string),
		      SBYTES (string));
      if (completion_ignore_case && !SYMBOLP (tem))
	{
	  for (i = ASIZE (collection) - 1; i >= 0; i--)
	    {
	      tail = AREF (collection, i);
	      if (SYMBOLP (tail))
		while (1)
		  {
		    if (BASE_EQ (Fcompare_strings (string, make_fixnum (0),
						   Qnil,
						   Fsymbol_name (tail),
						   make_fixnum (0) , Qnil, Qt),
				 Qt))
		      {
			tem = tail;
			break;
		      }
		    if (XSYMBOL (tail)->u.s.next == 0)
		      break;
		    XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next);
		  }
	    }
	}

      if (!SYMBOLP (tem))
	return Qnil;
    }
  else if (HASH_TABLE_P (collection))
    {
      struct Lisp_Hash_Table *h = XHASH_TABLE (collection);
      i = hash_lookup (h, string, NULL);
      if (i >= 0)
        {
          tem = HASH_KEY (h, i);
          goto found_matching_key;
        }
      else
	for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
          {
            tem = HASH_KEY (h, i);
            if (BASE_EQ (tem, Qunbound)) continue;
            Lisp_Object strkey = (SYMBOLP (tem) ? Fsymbol_name (tem) : tem);
            if (!STRINGP (strkey)) continue;
            if (BASE_EQ (Fcompare_strings (string, Qnil, Qnil,
					   strkey, Qnil, Qnil,
					   completion_ignore_case ? Qt : Qnil),
                    Qt))
              goto found_matching_key;
          }
      return Qnil;
    found_matching_key: ;
    }
  else
    return call3 (collection, string, predicate, Qlambda);

  /* Reject this element if it fails to match all the regexps.  */
  if (!match_regexps (string, Vcompletion_regexp_list,
		      completion_ignore_case))
    return Qnil;

  /* Finally, check the predicate.  */
  if (!NILP (predicate))
    {
      return HASH_TABLE_P (collection)
	? call2 (predicate, tem, HASH_VALUE (XHASH_TABLE (collection), i))
	: call1 (predicate, tem);
    }
  else
    return Qt;
}