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
crep was 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