diff --git a/docs/docs/features/search/syntax-reference.mdx b/docs/docs/features/search/syntax-reference.mdx
index cde52d0e..f5760002 100644
--- a/docs/docs/features/search/syntax-reference.mdx
+++ b/docs/docs/features/search/syntax-reference.mdx
@@ -4,32 +4,51 @@ title: Writing search queries
Sourcebot uses a powerful regex-based query language that enabled precise code search within large codebases.
-
## Syntax reference guide
-Queries consist of space-separated regular expressions. Wrapping expressions in `""` combines them. By default, a file must have at least one match for each expression to be included.
+Queries consist of space-separated search patterns that are matched against file contents. A file must have at least one match for each expression to be included. Queries can optionally contain search filters to further refine the search results.
+
+## Keyword search (default)
+
+Keyword search matches search patterns exactly in file contents. Wrapping search patterns in `""` combines them as a single expression.
+
+| Example | Explanation |
+| :--- | :--- |
+| `foo` | Match files containing the keyword `foo` |
+| `foo bar` | Match files containing both `foo` **and** `bar` |
+| `"foo bar"` | Match files containing the phrase `foo bar` |
+| `"foo \"bar\""` | Match files containing `foo "bar"` exactly (escaped quotes) |
+
+## Regex search
+
+Toggle the regex button (`.*`) in the search bar to interpret search patterns as regular expressions.
| Example | Explanation |
| :--- | :--- |
| `foo` | Match files with regex `/foo/` |
-| `foo bar` | Match files with regex `/foo/` **and** `/bar/` |
-| `"foo bar"` | Match files with regex `/foo bar/` |
+| `foo.*bar` | Match files with regex `/foo.*bar/` (foo followed by any characters, then bar) |
+| `^function\s+\w+` | Match files with regex `/^function\s+\w+/` (function at start of line, followed by whitespace and word characters) |
+| `"foo bar"` | Match files with regex `/foo bar/`. Quotes are not matched. |
-Multiple expressions can be or'd together with `or`, negated with `-`, or grouped with `()`.
+## Search filters
-| Example | Explanation |
-| :--- | :--- |
-| `foo or bar` | Match files with regex `/foo/` **or** `/bar/` |
-| `foo -bar` | Match files with regex `/foo/` but **not** `/bar/` |
-| `foo (bar or baz)` | Match files with regex `/foo/` **and** either `/bar/` **or** `/baz/` |
-
-Expressions can be prefixed with certain keywords to modify search behavior. Some keywords can be negated using the `-` prefix.
+Search queries (keyword or regex) can include multiple search filters to further refine the search results. Some filters can be negated using the `-` prefix.
| Prefix | Description | Example |
| :--- | :--- | :--- |
| `file:` | Filter results from filepaths that match the regex. By default all files are searched. | `file:README` - Filter results to filepaths that match regex `/README/` `file:"my file"` - Filter results to filepaths that match regex `/my file/` `-file:test\.ts$` - Ignore results from filepaths match regex `/test\.ts$/` |
-| `repo:` | Filter results from repos that match the regex. By default all repos are searched. | `repo:linux` - Filter results to repos that match regex `/linux/` `-repo:^web/.*` - Ignore results from repos that match regex `/^web\/.*` |
+| `repo:` | Filter results from repos that match the regex. By default all repos are searched. | `repo:linux` - Filter results to repos that match regex `/linux/` `-repo:^web/.*` - Ignore results from repos that match regex `/^web\/.*/` |
| `rev:` | Filter results from a specific branch or tag. By default **only** the default branch is searched. | `rev:beta` - Filter results to branches that match regex `/beta/` |
| `lang:` | Filter results by language (as defined by [linguist](https://github.com/github-linguist/linguist/blob/main/lib/linguist/languages.yml)). By default all languages are searched. | `lang:TypeScript` - Filter results to TypeScript files `-lang:YAML` - Ignore results from YAML files |
| `sym:` | Match symbol definitions created by [universal ctags](https://ctags.io/) at index time. | `sym:\bmain\b` - Filter results to symbols that match regex `/\bmain\b/` |
-| `context:` | Filter results to a predefined [search context](/docs/features/search/search-contexts). | `context:web` - Filter results to the web context `-context:pipelines` - Ignore results from the pipelines context |
\ No newline at end of file
+| `context:` | Filter results to a predefined [search context](/docs/features/search/search-contexts). | `context:web` - Filter results to the web context `-context:pipelines` - Ignore results from the pipelines context |
+
+## Boolean operators & grouping
+
+By default, space-separated expressions are and'd together. Using the `or` keyword as well as parentheses `()` can be used to create more complex boolean logic. Parentheses can be negated using the `-` prefix.
+
+| Example | Explanation |
+| :--- | :--- |
+| `foo or bar` | Match files containing `foo` **or** `bar` |
+| `foo (bar or baz)` | Match files containing `foo` **and** either `bar` **or** `baz`. |
+| `-(foo) bar` | Match files containing `bar` **and not** `foo`. |
diff --git a/packages/queryLanguage/test.ts b/packages/queryLanguage/test.ts
deleted file mode 100644
index e7a6e378..00000000
--- a/packages/queryLanguage/test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { parser } from "./src/parser";
-
-const input = "hello case:yes";
-const tree = parser.parse(input);
-
-const prettyPrint = (tree: ReturnType, input: string) => {
- let result = "";
- let lastPos = 0;
-
- tree.iterate({
- enter: (node) => {
- // If this is a leaf node (terminal), collect its text
- if (node.from >= node.to) {
- // Empty node, skip
- return;
- }
-
- // Check if this node has any children by checking the tree structure
- const nodeTree = node.node;
- const isLeaf = !nodeTree.firstChild;
-
- if (isLeaf) {
- // Add any whitespace between the last position and this node
- if (node.from > lastPos) {
- result += input.slice(lastPos, node.from);
- }
-
- // Add the node's text
- result += input.slice(node.from, node.to);
- lastPos = node.to;
- }
- }
- });
-
- // Add any trailing content
- if (lastPos < input.length) {
- result += input.slice(lastPos, input.length);
- }
-
- return result;
-}
-
-const reconstructed = prettyPrint(tree, input);
-console.log("Original:", input);
-console.log("Reconstructed:", reconstructed);
-console.log("Match:", input === reconstructed);
\ No newline at end of file
diff --git a/packages/web/src/app/[domain]/components/syntaxReferenceGuide.tsx b/packages/web/src/app/[domain]/components/syntaxReferenceGuide.tsx
index 52ec7aea..39f84ae2 100644
--- a/packages/web/src/app/[domain]/components/syntaxReferenceGuide.tsx
+++ b/packages/web/src/app/[domain]/components/syntaxReferenceGuide.tsx
@@ -15,6 +15,7 @@ import { useCallback, useRef } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useSyntaxGuide } from "./syntaxGuideProvider";
import { CodeSnippet } from "@/app/components/codeSnippet";
+import { ExternalLinkIcon, RegexIcon } from "lucide-react";
const LINGUIST_LINK = "https://github.com/github-linguist/linguist/blob/main/lib/linguist/languages.yml";
const CTAGS_LINK = "https://ctags.io/";
@@ -61,70 +62,92 @@ export const SyntaxReferenceGuide = () => {
onOpenChange={handleOpenChange}
>
- Syntax Reference Guide
+ Syntax Reference Guide
- Queries consist of space-seperated regular expressions. Wrapping expressions in {`""`} combines them. By default, a file must have at least one match for each expression to be included.
+ Queries consist of space-separated search patterns that are matched against file contents. A file must have at least one match for each expression to be included. Queries can optionally contain search filters to further refine the search results.
-
-
-
- Example
- Explanation
-
-
-
-
- foo
- Match files with regex /foo/
-
-
- foo bar
- Match files with regex /foo/and/bar/
-
-
- {`"foo bar"`}
- Match files with regex /foo bar/
-
-
-
-
-
- {`Multiple expressions can be or'd together with `}or, negated with -, or grouped with ().
-
-
-
-
- Example
- Explanation
-
-
-
-
- foo or bar
- Match files with regex /foo/or/bar/
-
-
- foo -bar
- Match files with regex /foo/ but not/bar/
-
-
- foo (bar or baz)
- Match files with regex /foo/and either /bar/or/baz/
-
-
-
+
+
Keyword search (default)
+
+ Keyword search matches search patterns exactly in file contents. Wrapping search patterns in {`""`} combines them as a single expression.
+
+
+
+
+ Example
+ Explanation
+
+
+
+
+ foo
+ Match files containing the keyword foo
+
+
+ foo bar
+ Match files containing both fooandbar
+
+
+ {`"foo bar"`}
+ Match files containing the phrase foo bar
+
+
+ {'"foo \\"bar\\""'}
+ Match files containing foo "bar" exactly (escaped quotes)
+
+
+
+
-
-
- Expressions can be prefixed with certain keywords to modify search behavior. Some keywords can be negated using the - prefix.
-
+
-
+
+
Regex search
+
+ Toggle the button to interpret search patterns as regular expressions.
+
+
+
+
+ Example
+ Explanation
+
+
+
+
+ foo
+ Match files with regex /foo/
+
+
+ foo.*bar
+ Match files with regex /foo.*bar/ (foo followed by any characters, then bar)
+
+
+ {`^function\\s+\\w+`}
+ Match files with regex /^function\s+\w+/ (function at start of line, followed by whitespace and word characters)
+
+
+ {`"foo bar"`}
+ Match files with regex /foo bar/. Quotes are not matched.
+
+
+
+
+
+
+
+
+
Search filters
+
+ Search queries (keyword or regex) can include multiple search filters to further refine the search results. Some filters can be negated using the - prefix.
+
+ By default, space-seperated expressions are and'd together. Using the or keyword as well as parantheses () can be used to create more complex boolean logic. Parantheses can be negated using the - prefix.
+
+
+
+
+ Example
+ Explanation
+
+
+
+
+ foo or bar
+ Match files containing fooorbar
+
+
+ foo (bar or baz)
+ Match files containing fooand either barorbaz.
+
+
+ -(foo) bar
+ Match files containing barand notfoo.
+
+
+