Creating asynchronous completion commands
If you have a completion source that’s both dynamic and expensive to generate, ‘completing-read’ may not be the best choice. Instead, ‘consult--read’ serves as a thin wrapper around ‘completing-read’ that provides this functionality. For example, consider the following slow script that splits its input on space:
#!/usr/bin/env bash
# simulate work
sleep .1
# generate completion candidates
printf "%s\n" "$*" | tr " " "\n" | sortLet’s assume this script is callable as ‘testibus hello world’. To have Consult use it for completion, use ‘consult--process-collection’:
(consult--read
(consult--process-collection
(lambda (input) (list "testibus" (string-trim input))))
:prompt "run testibus: ")If the completion candidates are generated by Lisp instead, use ‘consult--dynamic-collection’:
(consult--read
(consult--dynamic-collection
(lambda (input)
(sleep-for 0.1) ;; Simulate work
(split-string input nil t)))
:prompt "run testibus: ")‘consult--dynamic-collection’ can take a function with a callback such that the completion UI can update for long running computations.
(consult--read
(consult--dynamic-collection
(lambda (input callback)
(dotimes (i 3)
(sleep-for 0.1) ;; Simulate work
(funcall callback (mapcar (lambda (s) (format "%s%s" s i))
(split-string input nil t))))))
:prompt "run testibus: ")The asynchronous completion collections ‘consult--dynamic-collection’ and ‘consult--process-collection’ can be used for ‘consult--multi’ sources. Specify them as ‘:async’ field of the source plist.