Skip to content

Instantly share code, notes, and snippets.

@hyf0
Created November 12, 2025 06:12
Show Gist options
  • Select an option

  • Save hyf0/08add23ba35d983e9dc706f33b2bb71d to your computer and use it in GitHub Desktop.

Select an option

Save hyf0/08add23ba35d983e9dc706f33b2bb71d to your computer and use it in GitHub Desktop.
ast-grep-search
name description allowed-tools
ast-grep-search
Syntax-aware code searching that understands code structure rather than just text patterns. Always prefer ast-grep than grep for code searches.
Read, Grep, Bash(ast-grep:*), Bash(sg:*)

ast-grep: Structural Code Search

ast-grep allows searching code based on its Abstract Syntax Tree (AST), enabling syntax-aware pattern matching. It is ideal for finding function calls, method invocations, variable declarations, and other code structures while respecting language syntax.

Use ast-grep when:

  • Searching for function/method calls with varying arguments
  • Finding code patterns that respect language syntax
  • Matching code structure regardless of formatting/whitespace
  • Locating specific AST nodes (imports, exports, classes, function definitions)
  • Need to understand semantic code structure
  • Searching requires syntax awareness

Use grep/ripgrep when:

  • Simple string or regex searches
  • Searching in comments, strings, or documentation
  • Looking for identifiers or variable names
  • Quick text-based searches where syntax doesn't matter

ast-grep cannot:

  • Perform type-aware searches (doesn't understand type inference)
  • Search across files for relationships (e.g., "find all callers")
  • Handle ambiguous partial syntax
  • Search inside macro expansions (searches source only)
  • Understand semantic equivalence (different code, same meaning)

Instructions

Basic Command Syntax

ast-grep --lang <language> -p '<pattern>' [paths...]

Pattern Syntax

Meta-Variables

ast-grep uses meta-variables prefixed with $ to create structural patterns:

  • $IDENTIFIER - Matches a single AST node (expression, identifier, statement, type)

    • Examples: $VAR, $EXPR, $ARG, $METHOD, $TYPE
  • $$$MULTI - Matches zero or more consecutive nodes (ellipsis pattern)

    • Examples: $$$ARGS, $$$BODY, $$$FIELDS, $$$PARAMS

Pattern Construction Rules

  1. Use concrete syntax for known parts (keywords, operators, punctuation)
  2. Use meta-variables only where variation is expected
  3. Preserve language syntax (brackets, semicolons, commas)
  4. Start specific then generalize if too few results
  5. Respect AST boundaries - patterns must be valid AST nodes

Basic Pattern Examples

Find any function call:

ast-grep -l rust -p 'function_name($$$ARGS)'

Find method calls on any object:

ast-grep -l typescript -p '$OBJ.method_name($$$ARGS)'

Find variable declarations:

ast-grep -l rust -p 'let $VAR = $EXPR'

Find struct instantiation with any fields:

ast-grep -l rust -p '$TYPE { $$$FIELDS }'

Context Lines

Show surrounding code:

# 3 lines after matches
ast-grep -l rust -p '$PATTERN' -A 3

# 3 lines before matches
ast-grep -l rust -p '$PATTERN' -B 3

# 3 lines before and after
ast-grep -l rust -p '$PATTERN' -C 3

Advanced Features

JSON Output for Processing

Three JSON output formats available:

# Pretty-printed JSON
ast-grep -l rust -p '$PATTERN' --json=pretty

# Streaming JSON (one object per line)
ast-grep -l rust -p '$PATTERN' --json=stream

# Compact JSON (single line)
ast-grep -l rust -p '$PATTERN' --json=compact

Workflow

Step 1: Understand the Search Request

Parse the user's description: $ARGUMENTS

Determine:

  1. What pattern? - What code structure are we searching for?
  2. Which language? - Rust (crates/) or TypeScript (packages/)?
  3. Which scope? - Specific directory, whole crates/, or whole packages/?
  4. What context needed? - Should we show surrounding code?

Step 2: Construct the Pattern

Build a pattern following these principles:

  1. Identify concrete parts - Function names, keywords, operators
  2. Identify variable parts - Use $VAR for single nodes
  3. Identify sequences - Use $$$VARS for argument lists, statement blocks
  4. Preserve syntax - Keep brackets, braces, semicolons exact
  5. Test mentally - Would this pattern match the target code?

Pattern development tips:

  • Start with actual code example, then generalize
  • Use --debug-query=pattern to see how ast-grep parses it
  • Test on known examples first
  • Add more concrete syntax if results too broad
  • Generalize if results too narrow

Step 3: Execute the Search

Choose appropriate command:

# Basic search
!`ast-grep --lang <language> -p '<pattern>' <path>`

# With context lines
!`ast-grep --lang <language> -p '<pattern>' -C 2 <path>`

# JSON output for processing
!`ast-grep --lang <language> -p '<pattern>' --json=stream <path>`

Step 4: Analyze and Present Results

  1. Count matches - How many files and total matches?
  2. Show representative examples - Don't overwhelm with all results
  3. Identify patterns - Common themes in matches?
  4. Suggest next steps - Refine search, explore specific files, or related searches

Step 5: Refine if Needed

If results are:

  • Too broad - Add more concrete syntax, narrow the scope
  • Too narrow - Use more meta-variables, broaden the pattern
  • Wrong matches - Check pattern syntax, use --debug-query
  • No matches - Verify language, check pattern validity, test simpler pattern

Common Use Cases

Use Case 1: Find Error Conversions

Query: "Find all places where errors are converted using .context()"

!`ast-grep -l rust -p '$EXPR.context($MSG)' crates/`

Use Case 2: Find Plugin Hook Implementations

Query: "Show implementations of the transform hook in plugins"

!`ast-grep -l rust -p 'fn transform(&self, $$$PARAMS) -> $RET { $$$BODY }' crates/rolldown_plugin*/`

Use Case 3: Find All Type Assertions

Query: "Find TypeScript type assertions"

!`ast-grep -l typescript -p '$EXPR as $TYPE' packages/`

Use Case 4: Find NAPI Bindings

Query: "Find all #[napi] annotated functions"

!`ast-grep -l rust -p '#[napi] fn $NAME($$$PARAMS) $$$REST' crates/rolldown_binding/`

Use Case 5: Find Specific Import Usage

Query: "Find all files importing from rolldown core"

!`ast-grep -l typescript -p 'import { $$$IMPORTS } from "rolldown"' packages/`

Use Case 6: Find Promise Patterns

Query: "Find unhandled promises (await without try-catch)"

!`ast-grep -l typescript -p 'await $EXPR' packages/ -A 0 -B 5`

Then manually inspect for missing error handling.

Use Case 7: Find Clone Calls

Query: "Find all .clone() calls that might be expensive"

!`ast-grep -l rust -p '$EXPR.clone()' crates/rolldown/src/`

Use Case 8: Find Mutable References

Query: "Find all functions taking mutable self"

!`ast-grep -l rust -p 'fn $NAME(&mut self, $$$PARAMS) $$$REST' crates/`

Multi-Language Support

ast-grep supports 40+ languages:

Compiled languages: C, C++, C#, Go, Java, Kotlin, Rust, Swift, Dart Scripting languages: Python, Ruby, PHP, Lua, Elixir Web languages: JavaScript, TypeScript, HTML, CSS Other: Bash, YAML, JSON, Thrift, Protobuf, and more

Best Practices

  1. Start simple - Begin with basic patterns, add complexity as needed
  2. Test iteratively - Run on small scope first, expand when confident
  3. Use concrete syntax - More concrete = more precise results
  4. Leverage ellipsis - $$$ARGS is powerful for variable-length sequences
  5. Read the AST - Use --debug-query to understand structure
  6. Combine with grep - Use grep for preliminary filtering, ast-grep for precision
  7. Save useful patterns - Document patterns that work well for reuse
  8. Use configuration - For repeated searches, create sgconfig.yml rules

Output Format

After executing searches, provide:

  1. Summary - "Found X matches in Y files"
  2. Sample Results - Show relevant file paths and code snippets
  3. Analysis - Identify patterns, commonalities, or insights
  4. Recommendations - Suggest next steps, refinements, or related searches

Reference Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment