Function: all-completions

all-completions is a byte-compiled function defined in minibuf.c.

Signature

(all-completions STRING COLLECTION &optional PREDICATE HIDE-SPACES)

Documentation

Search for partial matches of STRING in COLLECTION.

Test each possible completion specified by COLLECTION to see if it begins with STRING. The possible completions may be strings or symbols. Symbols are converted to strings before testing, by using symbol-name.

The value is a list of all the possible completions that match STRING.

If COLLECTION is an alist, the keys (cars of elements) are the possible completions. If an element is not a cons cell, then the element itself is the possible completion. If COLLECTION is a hash-table, all the keys that are strings or symbols are the possible completions. If COLLECTION is an obarray, the names of all symbols in the obarray are the possible completions.

COLLECTION can also be a function to do the completion itself. It receives three arguments: STRING, PREDICATE and t. Whatever it returns becomes the value of all-completions.

If optional third argument PREDICATE is non-nil, it must be a function of one or two arguments, and is used to test each possible completion. A possible completion is accepted only if PREDICATE returns non-nil.

The argument given to PREDICATE is either a string or a cons cell (whose car is a string) from the alist, or a symbol from the obarray. If COLLECTION is a hash-table, PREDICATE is called with two arguments: the string key and the associated value.

To be acceptable, a possible completion must also match all the regexps in completion-regexp-list (unless COLLECTION is a function, in which case that function should itself handle completion-regexp-list).

An obsolete optional fourth argument HIDE-SPACES is still accepted for backward compatibility. If non-nil, strings in COLLECTION that start with a space are ignored unless STRING itself starts with a space.

This function has :around advice: all-completions@llama.

View in manual

Probably introduced at or before Emacs version 19.23.

Source Code

// Defined in /usr/src/emacs/src/minibuf.c
{
  Lisp_Object tail, elt, eltstring;
  Lisp_Object allmatches;
  int type = HASH_TABLE_P (collection) ? 3
    : VECTORP (collection) ? 2
    : NILP (collection) || (CONSP (collection) && !FUNCTIONP (collection));
  ptrdiff_t idx = 0, obsize = 0;
  Lisp_Object bucket, tem, zero;

  CHECK_STRING (string);
  if (type == 0)
    return call3 (collection, string, predicate, Qt);
  allmatches = bucket = Qnil;
  zero = make_fixnum (0);

  /* If COLLECTION is not a list, set TAIL just for gc pro.  */
  tail = collection;
  if (type == 2)
    {
      collection = check_obarray (collection);
      obsize = ASIZE (collection);
      bucket = AREF (collection, idx);
    }

  while (1)
    {
      /* Get the next element of the alist, obarray, or hash-table.  */
      /* Exit the loop if the elements are all used up.  */
      /* elt gets the alist element or symbol.
	 eltstring gets the name to check as a completion.  */

      if (type == 1)
	{
	  if (!CONSP (tail))
	    break;
	  elt = XCAR (tail);
	  eltstring = CONSP (elt) ? XCAR (elt) : elt;
	  tail = XCDR (tail);
	}
      else if (type == 2)
	{
	  if (!EQ (bucket, zero))
	    {
	      if (!SYMBOLP (bucket))
		error ("Bad data in guts of obarray");
	      elt = bucket;
	      eltstring = elt;
	      if (XSYMBOL (bucket)->u.s.next)
		XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next);
	      else
		XSETFASTINT (bucket, 0);
	    }
	  else if (++idx >= obsize)
	    break;
	  else
	    {
	      bucket = AREF (collection, idx);
	      continue;
	    }
	}
      else /* if (type == 3) */
	{
	  while (idx < HASH_TABLE_SIZE (XHASH_TABLE (collection))
		 && BASE_EQ (HASH_KEY (XHASH_TABLE (collection), idx),
			     Qunbound))
	    idx++;
	  if (idx >= HASH_TABLE_SIZE (XHASH_TABLE (collection)))
	    break;
	  else
	    elt = eltstring = HASH_KEY (XHASH_TABLE (collection), idx++);
	}

      /* Is this element a possible completion?  */

      if (SYMBOLP (eltstring))
	eltstring = Fsymbol_name (eltstring);

      if (STRINGP (eltstring)
	  && SCHARS (string) <= SCHARS (eltstring)
	  /* If HIDE_SPACES, reject alternatives that start with space
	     unless the input starts with space.  */
	  && (NILP (hide_spaces)
	      || (SBYTES (string) > 0
		  && SREF (string, 0) == ' ')
	      || SREF (eltstring, 0) != ' ')
	  && (tem = Fcompare_strings (eltstring, zero,
				      make_fixnum (SCHARS (string)),
				      string, zero,
				      make_fixnum (SCHARS (string)),
				      completion_ignore_case ? Qt : Qnil),
	      EQ (Qt, tem)))
	{
	  /* Ignore this element if it fails to match all the regexps.  */
	  if (!match_regexps (eltstring, Vcompletion_regexp_list,
			      completion_ignore_case))
	    continue;

	  /* Ignore this element if there is a predicate
	     and the predicate doesn't like it.  */

	  if (!NILP (predicate))
	    {
	      if (EQ (predicate, Qcommandp))
		tem = Fcommandp (elt, Qnil);
	      else
		{
		  tem = type == 3
		    ? call2 (predicate, elt,
			     HASH_VALUE (XHASH_TABLE (collection), idx - 1))
		    : call1 (predicate, elt);
		}
	      if (NILP (tem)) continue;
	    }
	  /* Ok => put it on the list.  */
	  allmatches = Fcons (eltstring, allmatches);
	}
    }

  return Fnreverse (allmatches);
}