crep is a command-line tool designed for searching code using
Tree-sitter queries. Unlike
traditional grep, which operates on text lines, crep understands the
structure of your code, allowing for more precise semantic searching.
[!IMPORTANT]
crepwas built for fun and is not intended for real use. I made it to learn Tree-sitter and how searching over files works.
Features
- Semantic Search: Uses Tree-sitter to parse code into Concrete Syntax Trees (CSTs) and execute queries against them.
- Broad Language Support: Supports a wide range of languages including C, C++, Rust, Python, Go, and others (see full list below).
- Multi-threaded: Utilizes a custom thread pool for efficient scanning of large codebases.
- Structural Matching: Reports file path, line number, return type, function name, and parameters for each match.
- Debug Mode: Supports detailed logging via the
DEBUGenvironment variable. - Fuzzy Matching: Supports configurable Levenshtein distance for fuzzy search.
Prerequisites
To build crep, you need:
- A C compiler (GCC or Clang)
makexxd(used for embedding Tree-sitter queries)pthreadlibrary
Installation
git clone https://github.com/mitjafelicijan/crep.git
cd crep
make all
Usage
./crep [-c|--case-sensitive] [-l|--levenshtein <dist>] [-d|--depth <level>] <search_term> [path]
-c, --case-sensitive: Enable case-sensitive matching (default is case-insensitive).-l, --levenshtein <dist>: Enable fuzzy matching with a maximum Levenshtein distance of<dist>.-d, --depth <level>: Set the maximum recursion depth for directory traversal.<search_term>: The string to search for within function/method names.[path]: Optional. The directory or file to search (defaults to current directory).
Environment Variables
DEBUG=1orDEBUG=true: Enable verbose debug logging.
Examples
Search for all functions containing "init" in the current directory:
./crep init .
Search for functions containing "parse" in a specific file:
./crep parse main.c
Run with debug logging enabled:
DEBUG=1 ./crep init .
Search for "main" allowing for 2 typos (e.g. "mian"):
./crep -l 2 "mian" main.c
How It Works
crep works by:
- Identifying supported files based on extension.
- Parsing the files using language-specific Tree-sitter grammars.
- Executing a structural query to find function/method definitions, including return types and parameters.
- Matching the identifier against the provided search term.
- Displaying the results with added semantic context.
Supported Languages
| Language | Extensions |
|---|---|
| C | .c, .h |
| C++ | .cpp, .hpp |
| CUDA | .cu, .cuh |
| GLSL | .glsl |
| Go | .go |
| JavaScript | .js |
| Kotlin | .kt |
| Lua | .lua |
| Odin | .odin |
| PHP | .php |
| Python | .py |
| Rust | .rs |
| Tcl | .tcl |
| Zig | .zig |
Running Tests
To run the test suite:
make tests
Additional resources
- https://en.wikipedia.org/wiki/Ctags
- https://www.emacswiki.org/emacs/TagsFile
- https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm
- https://en.wikipedia.org/wiki/Levenshtein_distance
- https://github.com/tree-sitter/tree-sitter
- https://tree-sitter.github.io/tree-sitter/playground
- https://dreampuf.github.io/GraphvizOnline/
- https://github.com/tree-sitter-grammars
