searchast

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 2, 2026 License: MIT Imports: 9 Imported by: 0

README

Go Grep AST

Go Version License

A Go tool that combines grep functionality with Abstract Syntax Tree (AST) analysis for powerful code search and pattern matching. This tool is heavily inspired by Aider-AI/grep-ast and provides similar functionality with Go performance and tree-sitter integration.

Installation

Install as CLI Tool
Using Go Install
go install github.com/andersonjoseph/searchast/cmd/searchast@latest
Install as Go Package
go get github.com/andersonjoseph/searchast

Usage

CLI Usage

The project provides two main CLI tools:

Basic usage:

searchast -filename <file> -pattern <regex>

Examples:

Example 1: Find all function definitions
searchast -filename main.go -pattern "func.*\\("

Output:

  ⋮
 3 │ import (
 4 │ 	"fmt"
 5 │ 	"log"
 6 │ 	"os"
 7 │ )
 8 │ 
 9 █ func main() {
10 │ 	fmt.Println("Starting application...")
11 │ 	
12 │ 	if err := run(); err != nil {
13 │ 		log.Fatalf("Application failed: %v", err)
14 │ 	}
15 │ 	
16 │ 	fmt.Println("Application finished")
17 │ }
  ⋮
Example 2: Find error handling patterns
searchast -filename main.go -pattern "err.*nil"

Output:

  ⋮
 9 │ func main() {
10 │ 	fmt.Println("Starting application...")
11 │ 	
12 █ 	if err := run(); err != nil {
13 │ 		log.Fatalf("Application failed: %v", err)
14 │ 	}
15 │ 	
16 │ 	fmt.Println("Application finished")
17 │ }
18 │ 
19 │ func run() error {
20 │ 	// Process some data
21 │ 	data := []string{"item1", "item2", "item3"}
22 │ 	
23 │ 	for i, item := range data {
24 █ 		if err := processItem(i, item); err != nil {
25 │ 			return fmt.Errorf("failed to process item %d: %w", i, err)
26 │ 		}
27 │ 	}
28 │ 	
29 │ 	return saveResults("output.txt")
30 │ }
  ⋮
Example 3: Custom formatting
searchast -filename main.go -pattern "func.*\\(" -highlight-symbol ">>>" -context-symbol " | "

Output:

  ⋮
 3  |  import (
 4  | 	"fmt"
 5  | 	"log"
 6  | 	"os"
 7  |  )
 8  | 
 9 >>> func main() {
10  | 	fmt.Println("Starting application...")
11  |  	
12  | 	if err := run(); err != nil {
13  | 		log.Fatalf("Application failed: %v", err)
14  | 	}
15  |  	
16  | 	fmt.Println("Application finished")
17  |  }
  ⋮
Example 4: Find specific function calls
searchast -filename main.go -pattern "fmt\\.Print"

Output:

  ⋮
 3 │ import (
 4 │ 	"fmt"
 5 │ 	"log"
 6 │ 	"os"
 7 │ )
 8 │ 
 9 │ func main() {
10 █ 	fmt.Println("Starting application...")
11 │ 	
12 │ 	if err := run(); err != nil {
13 │ 		log.Fatalf("Application failed: %v", err)
14 │ 	}
15 │ 	
16 █ 	fmt.Println("Application finished")
17 │ }
18 │ 
19 │ func run() error {
20 │ 	// Process some data
21 │ 	data := []string{"item1", "item2", "item3"}
22 │ 	
23 │ 	for i, item := range data {
24 │ 		if err := processItem(i, item); err != nil {
25 │ 			return fmt.Errorf("failed to process item %d: %w", i, err)
26 │ 		}
27 │ 	}
28 │ 	
29 │ 	return saveResults("output.txt")
30 │ }
31 │ 
32 │ func processItem(index int, item string) error {
33 █ 	fmt.Printf("Processing item %d: %s\n", index, item)
34 │ 	
35 │ 	if item == "" {
36 │ 		return fmt.Errorf("empty item at index %d", index)
37 │ 	}
38 │ 	
39 │ 	return nil
40 │ }
  ⋮
Package Usage
package main

import (
    "context"
    "fmt"
    "os"
    "regexp"
    
    "github.com/andersonjoseph/searchast"
)

func main() {
    // Open a file
    file, err := os.Open("example.go")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // Create a source tree
    sourceTree, err := searchast.NewSourceTree(context.Background(), file, "example.go")
    if err != nil {
        panic(err)
    }

    // Search for a pattern
    linesOfInterest, err := sourceTree.Search("func.*main")
    if err != nil {
        panic(err)
    }

    // Add context
    linesToShow := searchast.NewContextBuilder().AddContext(sourceTree, linesOfInterest)

    // Format output
    formatter := searchast.NewTextFormatter()
    output := formatter.Format(sourceTree.Lines(), linesToShow, linesOfInterest)
    fmt.Print(output)
}
Advanced Usage
Custom Context Builder
// Create a context builder with custom options
contextBuilder := searchast.NewContextBuilder(
    searchast.WithSurroundingLines(5),      // Show 5 lines before/after matches
    searchast.WithParentContext(false),    // Don't include parent context
    searchast.WithCloseScopeGaps(true),    // Close gaps within scopes
    searchast.WithChildLines(2),           // Show 2 lines of child context
)

linesToShow := contextBuilder.AddContext(sourceTree, linesOfInterest)
Custom Formatter
// Create a formatter with custom symbols
formatter := searchast.NewTextFormatter(
    searchast.WithHighlightSymbol(">>>"),
    searchast.WithContextSymbol(" | "),
    searchast.WithGapSymbol("..."),
    searchast.WithLineNumbers(true),
    searchast.WithSpacer("  "),
)

output := formatter.Format(sourceTree.Lines(), linesToShow, linesOfInterest)

Inspiration

This project is heavily inspired by Aider-AI/grep-ast, which provides similar functionality for Python. This Go implementation aims to provide:

  • Better performance through Go's concurrency
  • Easy integration with Go toolchains
  • Cross-platform deployment
  • Type-safe API for Go developers

Documentation

Overview

Package searchast parses a source code file to build a tree structure representing code scopes. It allows for searching specific patterns and understanding their context within the code's hierarchy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewContextBuilder

func NewContextBuilder(opts ...Option) *contextBuilder

func NewSourceTree

func NewSourceTree(ctx context.Context, r io.Reader, filename string) (*sourceTree, error)

NewSourceTree constructs a new sourceTree from a reader and filename. the filename is used to determine the programming language.

Types

type Formatter

type Formatter interface {
	Format(lines []line, linesToShow Set[lineNumber], linesToHighlight Set[lineNumber]) string
}

type Option

type Option func(*contextBuilder)

func WithChildLines

func WithChildLines(lines lineNumber) Option

WithChildLines enables or disables the inclusion of child context.

func WithCloseScopeGaps

func WithCloseScopeGaps(enabled bool) Option

WithCloseScopeGaps enables or disables the inclusion of lines between the start and end of a scope.

func WithExpandChildScopes

func WithExpandChildScopes(enabled bool) Option

WithExpandChildScopes enables or disables the inclusion of all lines within child scopes of matched lines.

func WithGapToClose

func WithGapToClose(gap lineNumber) Option

WithGapToClose sets the maximum gap between lines that should be filled in.

func WithParentContext

func WithParentContext(enabled bool) Option

WithParentContext enables or disables the inclusion of parent context.

func WithSurroundingLines

func WithSurroundingLines(lines lineNumber) Option

WithSurroundingLines enables or disables the inclusion of surrounding lines.

type Set

type Set[T comparable] map[T]struct{}

func NewSet

func NewSet[T comparable]() Set[T]

func NewSetFromSlice

func NewSetFromSlice[T comparable](s []T) Set[T]

func (Set[T]) Add

func (s Set[T]) Add(v T)

func (*Set[T]) Clear

func (s *Set[T]) Clear()

func (Set[T]) Has

func (s Set[T]) Has(v T) bool

func (Set[T]) Remove

func (s Set[T]) Remove(v T)

func (Set[T]) ToSlice

func (s Set[T]) ToSlice() []T

type TextFormatter

type TextFormatter struct {
	// contains filtered or unexported fields
}

func NewTextFormatter

func NewTextFormatter(opts ...TextFormatterOption) *TextFormatter

func (*TextFormatter) Format

func (tf *TextFormatter) Format(lines []line, linesToShow Set[lineNumber], linesToHighlight Set[lineNumber]) string

type TextFormatterOption

type TextFormatterOption func(*TextFormatter)

func WithColors

func WithColors(enabled bool) TextFormatterOption

func WithContextSymbol

func WithContextSymbol(symbol string) TextFormatterOption

func WithGapSymbol

func WithGapSymbol(symbol string) TextFormatterOption

func WithHighlightSymbol

func WithHighlightSymbol(symbol string) TextFormatterOption

func WithLineNumbers

func WithLineNumbers(lineNumbers bool) TextFormatterOption

func WithSpacer

func WithSpacer(spacer string) TextFormatterOption

Directories

Path Synopsis
cmd
overview command
searchast command
Package language provides a convenient interface for retrieving the corresponding tree-sitter language object for a given file extension.
Package language provides a convenient interface for retrieving the corresponding tree-sitter language object for a given file extension.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL