Asynchronous search
Consult has support for asynchronous generation of candidate lists. This feature is used for search commands like ‘consult-grep’, where the list of matches is generated dynamically while the user is typing a regular expression. The grep process is executed in the background. When modifying the regular expression, the background process is terminated and a new process is started with the modified regular expression.
The matches, which have been found, can then be narrowed using the installed Emacs completion-style. This can be powerful if you are using for example the ‘orderless’ completion style.
This two-level filtering is possible by splitting the input string. Part of the input string is treated as input to grep and part of the input is used for filtering. There are multiple splitting styles available, configured in consult-async-split-styles-alist: ‘nil’, ‘comma’, ‘semicolon’ and ‘perl’. The default splitting style is configured with the variable consult-async-split-style.
With the ‘comma’ and ‘semicolon’ splitting styles, the first word before the comma or semicolon is passed to grep, the remaining string is used for filtering. The ‘nil’ splitting style does not perform any splitting, the whole input is passed to grep.
The ‘perl’ splitting style splits the input string at a punctuation character, using a similar syntax as Perl regular expressions.
Examples:
- ‘
#defun’: Search for "defun" using grep. - ‘
#consult embark’: Search for both "consult" and "embark" using grep in any order. - ‘
#first.*second’: Search for "first" followed by "second" using grep. - ‘
#\(consult\|embark\)’: Search for "consult" or "embark" using grep. Note the usage of Emacs-style regular expressions. - ‘
#defun#consult’: Search for "defun" using grep, filter with the word "consult". - ‘
/defun/consult’: It is also possible to use other punctuation characters. - ‘
#to#’: Force searching for "to" using grep, since the grep pattern must be longer than ‘consult-async-min-input’ characters by default.
You can pass options to the underlying command. The following examples apply to ripgrep:
- ‘
#foo bar --invert-match’ or ‘#foo bar -v’: Invert matching. - ‘
#foo bar --context=2’ or ‘#foo bar -C2’: Include two lines of context. - ‘
#foo bar --hidden’ or ‘#foo bar -.’: Search hidden files. - ‘
#foo bar --glob=*.org’ or ‘#foo bar -g *.org’: Search files matching the glob pattern. - ‘
#foo bar --type=elisp’ or ‘#foo bar -t elisp’: Search only Elisp files. - ‘
#.* -F’: Treat input as fixed string, and not as regular expression. - ‘
#foo bar -s’: Treat input as case sensitive (‘-s’), insensitive (‘-i’), or smart case (‘-S’).
Input can come after the options and the dash can be escaped:
- ‘
#\-foo bar’: Search for ‘-foo’ and ‘bar’ with escaped dash. - ‘
#-v -- foo bar’: Inverted search, words come after options.
The asynchronous processes create an error log buffer ‘_*consult-async*’ (note the leading space), which you can inspect for troubleshooting. The prompt has a small indicator showing the process status:
- ‘
:’ the usual prompt colon, before input is provided. - ‘
*’ with warning face, the process is running. - ‘
:’ with success face, success, process exited with an error code of zero. - ‘
!’ with error face, failure, process exited with a nonzero error code. - ‘
;’ with error face, interrupted, for example if more input is provided.