Query syntax

The query syntax of neogrok is controlled by zoekt, the code search engine for which neogrok is a frontend. Because zoekt does not have good documentation covering this syntax, we describe it here.

Everything is regex

In zoekt, all queries are parsed by Go's regexp package, the syntax of which is documented here. There is no way to disable this functionality; queries that want to use regex control characters literally must escape them.

Queries cannot control the regex flags that zoekt uses; they are hardcoded. As can be seen here, the flags are ClassNL, PerlX, and UnicodeGroups. Together, these flags notably allow multiline regex matches using character classes like [[:space:]], but not using the dot.

Queries are composed of one or more space-separated expressions

If your query contains no spaces, its behavior is pretty intuitive. foo displays all matches for the regex /foo/. That query contains a single expression, namely a regex expression. (We'll introduce more kinds of expressions below.)

But what about foo bar? This query has two expressions, which makes its behavior more complicated: it returns all matches for the regex /foo/ or the regex /bar/, but only in files that have matches for both /foo/ and /bar/.

First of all, if you wanted this query to behave as if it had only one expression, literally matching /foo bar/, you can either wrap it in double quotes, like "foo bar", or by escaping the space, like foo\ bar; both of those queries are equivalent. (Single quotes have no special meaning in this regard. 'foo bar' contains two expressions, the first being /'foo/ and the second being /bar'/.)

Multiple expressions are combined with boolean logic

As described above, expressions are conjunctive by default: a file must have at least one match for each expression to be included in the query results. Expressions may be made disjunctive by joining them with the special expression infix operator or. foo or bar returns all matches for /foo/ or /bar/ in all files that have matches for at least one of /foo/ or /bar/. (To use or as a literal expression and not as an operator, double quote it: foo "or" bar has three conjunctive expressions.)

Expressions can be logically grouped with parentheses: foo (bar or baz) produces results from files with matches for both /foo/ and at least one of /bar/ or /baz/. These groupings can be nested arbitrarily.

To complete the boolean logic, expressions can be negated with a leading dash. foo -bar returns all matches for /foo/ in files that do not have matches for /bar/. foo -(bar or baz) returns all matches for /foo/ in files that do not have matches for either /bar/ or /baz/. foo -(bar baz) returns all matches for /foo/ in files that do not have matches for both /bar/ and /baz/.

Certain prefixes have special effects on expressions

In addition to the default regex expressions you've already seen, special kinds of expressions can be created by prefixing them with certain flags, which are themselves composed of a few characters ending with a colon.

Consider that regex expressions can produce matches both in the content of a file and in the name of the file: README matches both file names and file contents (though the search engine tends to rank files containing file name matches higher than those containing only content matches, so you may have to scroll down or increase the number of files displayed to see the content matches for this query). If you only want the expression to match file names, use an expression prefixed with file:, like file:README. ( f: is an equivalent abbreviation for file:).

The inverse of file:'s specialization of regex expressions is content: or c:. content:README produces only matches that occur in the content of files.

There are a few more kinds of prefix expressions than those two. They're all tabulated below.

Finally, note that the boolean logic described above applies to prefix expressions just like normal ones: -f:test assert shows matches for /assert/ except for those in files whose names match /test/.

Available prefixes
Prefix(es) Description Examples
file:, f: Regex match file names only, instead of the default file names and file contents f:README
f:README neogrok
f:"evil file with spaces"
content:, c: Regex match file contents only, instead of the default file names and file contents c:README
repo:, r: Regex match repository names; by default all repositories are searched r:linux driver
branch:, b: Regex match branch names; by default all branches are searched b:prerelease foo
lang: Constrain files to those in the given language (or language alias) as defined by linguist and computed probabilistically from file name and contents at index time by go-enry. This is not a regex or a substring, though it is case-insensitive; each expression can only contain one language. lang:typescript type
sym: Regex match symbol definitions, as determined by universal ctags at index time, if it was present during indexing sym:\bmain\b
case: Unlike most other expressions, does not do anything on its own, but rather modifies other expressions in the query. case:yes makes other expressions case-sensitive; case:no makes them case-insensitive, and case:auto (the default behavior) makes them case-sensitive if they have any uppercase characters and case-insensitive otherwise case:no TEST
archived: archived:no excludes archived repositories while archived:yes excludes non-archived repositories. The default is to exclude neither. archived:no readme
fork: fork:no excludes repositories that are forks of another while fork:yes excludes repositories that are not forks of another. The default is to exclude neither. fork:no readme
public: public:no excludes public repositories while public:yes excludes private repositories. The default is to exclude neither. public:no readme