1`crep` is a command-line tool designed for searching code using
2[Tree-sitter](https://tree-sitter.github.io/tree-sitter/) queries. Unlike
3traditional `grep`, which operates on text lines, `crep` understands the
4structure of your code, allowing for more precise semantic searching.
5
6> [!IMPORTANT]
7> `crep` was built for fun and is not intended for real use. I made it to learn
8> Tree-sitter and how searching over files works.
9
10## Features
11
12- **Semantic Search**: Uses Tree-sitter to parse code into Concrete Syntax Trees
13 (CSTs) and execute queries against them.
14- **Broad Language Support**: Supports a wide range of languages including C, C++,
15 Rust, Python, Go, and others (see full list below).
16- **Multi-threaded**: Utilizes a custom thread pool for efficient scanning of
17 large codebases.
18- **Structural Matching**: Reports file path, line number, return type, function
19 name, and parameters for each match.
20- **Debug Mode**: Supports detailed logging via the `DEBUG` environment
21 variable.
22- **Fuzzy Matching**: Supports configurable Levenshtein distance for fuzzy search.
23
24## Prerequisites
25
26To build `crep`, you need:
27- A C compiler (GCC or Clang)
28- `make`
29- `xxd` (used for embedding Tree-sitter queries)
30- `pthread` library
31
32## Installation
33
34```bash
35git clone https://github.com/mitjafelicijan/crep.git
36cd crep
37make all
38```
39
40## Usage
41
42```bash
43./crep [-c|--case-sensitive] [-l|--levenshtein <dist>] [-d|--depth <level>] <search_term> [path]
44```
45
46- `-c, --case-sensitive`: Enable case-sensitive matching (default is case-insensitive).
47- `-l, --levenshtein <dist>`: Enable fuzzy matching with a maximum Levenshtein distance of `<dist>`.
48- `-d, --depth <level>`: Set the maximum recursion depth for directory traversal.
49- `<search_term>`: The string to search for within function/method names.
50- `[path]`: Optional. The directory or file to search (defaults to current directory).
51
52### Environment Variables
53
54- `DEBUG=1` or `DEBUG=true`: Enable verbose debug logging.
55
56### Examples
57
58Search for all functions containing "init" in the current directory:
59
60```bash
61./crep init .
62```
63
64Search for functions containing "parse" in a specific file:
65```bash
66./crep parse main.c
67```
68
69Run with debug logging enabled:
70```bash
71DEBUG=1 ./crep init .
72```
73
74Search for "main" allowing for 2 typos (e.g. "mian"):
75
76```bash
77./crep -l 2 "mian" main.c
78```
79
80## How It Works
81
82`crep` works by:
83
841. Identifying supported files based on extension.
852. Parsing the files using language-specific Tree-sitter grammars.
863. Executing a structural query to find function/method definitions, including
87 return types and parameters.
884. Matching the identifier against the provided search term.
895. Displaying the results with added semantic context.
90
91## Supported Languages
92
93| Language | Extensions |
94| ---------- | -------------- |
95| C | `.c`, `.h` |
96| C++ | `.cpp`, `.hpp` |
97| CUDA | `.cu`, `.cuh` |
98| GLSL | `.glsl` |
99| Go | `.go` |
100| JavaScript | `.js` |
101| Kotlin | `.kt` |
102| Lua | `.lua` |
103| Odin | `.odin` |
104| PHP | `.php` |
105| Python | `.py` |
106| Rust | `.rs` |
107| Tcl | `.tcl` |
108| Zig | `.zig` |
109
110## Running Tests
111
112To run the test suite:
113
114```bash
115make tests
116```
117
118## Additional resources
119
120- https://en.wikipedia.org/wiki/Ctags
121- https://www.emacswiki.org/emacs/TagsFile
122- https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm
123- https://en.wikipedia.org/wiki/Levenshtein_distance
124- https://github.com/tree-sitter/tree-sitter
125- https://tree-sitter.github.io/tree-sitter/playground
126- https://dreampuf.github.io/GraphvizOnline/
127- https://github.com/tree-sitter-grammars