IndexSearch Abyss116
winget install --id=Abyss116.IndexSearch -e Persistent-index rg-like search for large source trees.
winget install --id=Abyss116.IndexSearch -e Persistent-index rg-like search for large source trees.
IndexSearch is a fast indexed search tool for very large source trees. It is
designed to feel close to rg, but repeated searches use a persistent project
index and a per-project daemon instead of walking the filesystem every time.
Use the short command:
is -n "SomeSymbol" .
is -i -w -g "*.cpp" "render pass" .
is --files .
isgrep -n "A\\|B" file.txt
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/Abyss116/IndexSearch/main/install.sh | sh
Windows PowerShell:
irm https://raw.githubusercontent.com/Abyss116/IndexSearch/main/install.ps1 | iex
Homebrew:
brew tap Abyss116/indexsearch
brew install indexsearch
WinGet, after package-manager moderation has accepted the manifest:
winget install --id Abyss116.IndexSearch -e
Direct downloads:
After extracting a direct-download archive, run:
./istool install
The installer places istool, indexsearch, is, isgrep, and is-daemon in a
user-writable bin directory. On Windows, is is a native is.exe, not an
is.cmd wrapper.
cd /path/to/large/repo
istool index .
is -n "SomeSymbol" .
The first is PATTERN inside a project automatically starts a per-project
daemon. That daemon keeps the index mmaped, watches filesystem changes, serves
future searches, and can compact deltas while idle.
If no IndexSearch project exists above the current directory, interactive is
asks whether to create one in the current directory. Choosing n runs the
current search through the external compatible searcher instead. istool index .
always rebuilds the base index explicitly.
When is or isgrep is used non-interactively by coding agents outside an
IndexSearch project, it does not create project config. The one-off search is
routed internally through rg or grep so the command still returns results
without leaving .indexsearch/ behind.
Manage project services:
istool projects
istool log .
istool stop .
istool stop --all
stop --all stops registered project services and also makes a best-effort pass
over stale is-daemon / search-daemon processes left by older versions.
Shell completion scripts can be generated from istool:
istool completions powershell >> $PROFILE
istool completions bash > ~/.local/share/bash-completion/completions/istool
istool completions zsh > ~/.zfunc/_istool
istool completions fish > ~/.config/fish/completions/istool.fish
Project rules live in .indexsearch/is-project-config.txt.
[IndexSearch.paths.ignore]
.git/
out/
**/Intermediate/
[IndexSearch.paths.live]
run-logs/
shader-debug/
[IndexSearch.files.ignore]
*.png
*.pdb
[IndexSearch.files.include]
*
IndexSearch.paths.live is for high-churn or generated text directories that
should not be persisted into the project index. Explicit searches inside those
paths are routed internally through rg, for example is Error Saved/Logs,
while ordinary project searches stay fast and stable. The bundled Unreal Engine
template uses this for logs and shader debug output, while excluding Saved/
from persistent indexing.
Use **/Name/ for a directory name that should match at any depth, such as
**/DerivedDataCache/. Directory patterns with a trailing slash also cover the
directory's full subtree.
When a command names multiple explicit paths, IndexSearch splits the work: paths
covered by IndexSearch.paths.ignore, IndexSearch.paths.live, or file
include/exclude rules are routed internally through the external stream searcher,
while indexed paths continue through the daemon. is uses rg; isgrep
translates compatible grep syntax to rg as well, and invokes system grep
internally for grep-only features that cannot be translated safely.
For Unreal Engine source trees, copy the bundled template into the project
root's .indexsearch/ directory:
mkdir -p /path/to/UnrealEngine/.indexsearch
cp templates/unreal-engine/is-project-config.txt /path/to/UnrealEngine/.indexsearch/is-project-config.txt
cd /path/to/UnrealEngine
istool index .
When indexing a Git project, IndexSearch also adds an anchored local ignore to
.git/info/exclude, for example /.indexsearch/ at the repository root or
/nested/project/.indexsearch/ for a project rooted in a subdirectory.
If the first interactive search discovers an Unreal Engine root or a .uproject
root, the generated config uses the UE template automatically.
istool update .
istool update --git .
istool compact .
update refreshes an existing index. If the daemon is running, it first flushes
pending filesystem events, so normal edit-and-search workflows stay current
without a full tree scan.
By default, update reconciles against the filesystem for correctness across
Git and non-Git trees. update --git remains an explicit fast path after
git pull, checkout, or rebase. compact folds delta indexes back into the
base index.
Common flags:
is -F "literal" .
is -i "case insensitive" .
is -w Actor .
is -g "*.cpp" Nanite .
is -n -C 3 "SomeSymbol" .
is --json "SomeSymbol" .
is -v -F "exclude this line" .
is --files-without-match "TODO" .
is --count-matches -F "Tick" .
is -x -F "exact whole line" .
When stdout is a terminal, output is grouped by file like rg --heading. When
stdout is captured or piped, output uses flat path:line:match rows. Use
--heading, --no-heading, -n, and -N to override.
For a pattern that starts with punctuation or looks like an option, use --:
is -- "--help" .
Unsupported rg flags are logged in the project log and ignored when that is
safe, so agent and editor integrations can keep running. Use rg for PCRE-only
patterns, multiline matching, preprocessors, archive search, or other behavior
that must exactly match ripgrep.
Use isgrep when replacing an existing grep command or when you want grep
option spellings:
isgrep -n "IndexGraph\\|agent interface\\|context\\|files" MEMORY.md
isgrep -E -n "IndexGraph|agent interface|context|files" MEMORY.md
isgrep -r -n --include="*.rs" "SomeSymbol" .
isgrep defaults to grep Basic Regex syntax, so A\|B is translated to the
Rust regex alternation used by IndexSearch. For rg-style, RTK grep-style, or
extended-regex patterns with bare A|B alternation, keep or add -E; plain
isgrep "A|B" follows grep BRE semantics and searches for a literal |.
It also maps grep-specific flags whose meanings conflict with is, such as
grep -h and grep -L. For grep semantics that the indexed backend cannot
provide, such as PCRE mode, backreferences, or null-data mode, isgrep falls
back to the system grep when available.
For pipeline input, the persistent project index is not used. is forwards
rg-style stdin searches to rg; isgrep translates compatible grep-style
stdin searches to rg too, and uses system grep only for grep-only semantics:
git diff | is -n "SomeSymbol"
git diff | isgrep -n "SomeSymbol"
Claude Code installs get an additional guardrail: istool install-skills --target claude copies a PreToolUse hook that blocks bare Bash rg/ripgrep
and grep/egrep/fgrep commands. Retry ordinary local source searches with
is or isgrep; they route stdin, live/generated paths, ignored explicit
paths, and compatible translated grep syntax through the necessary external
search internally. Exit code 1 with no output means no matches, not a reason to
rerun the same local search with bare rg or grep.
istool index --profile .
istool update --profile .
is --profile -n -g "*.cpp" Nanite .
profile: lines are printed to stderr and are intended for sharing performance
reports from large repositories.
Local Unreal Engine benchmark on macOS, hot filesystem cache, stdout redirected
to /dev/null:
| Workload | is | qgrep | rg |
|---|---|---|---|
| Fresh index | 10.57s | about 21s | n/a |
| Compact | 2.31s | n/a | n/a |
Nanite | 7.61ms | 21.52ms | 3139.98ms |
SkeletalMeshComponent | 7.46ms | 19.53ms | 3216.95ms |
| missing literal | 2.63ms | 13.64ms | 3194.67ms |
| qualified-call regex | 85.05ms | 357.42ms | 3217.22ms |
To reproduce the search benchmark:
python3 scripts/benchmark-ue.py /path/to/UnrealEngine --prepare-qgrep \
--search-repeats 7 --rg-repeats 3
cargo build --release
cargo test --locked
./tests/smoke.sh
./target/release/istool --version
Local builds append build metadata to the displayed version, for example
0.4.8+build.1770000000.g8d2644d.dirty. The package/release version remains
plain SemVer for package managers.
Tagged pushes create GitHub Releases with Linux, macOS, and Windows archives.
Bundled instructions for Codex, Claude Code, OpenCode, and Cursor can be installed with:
istool install-skills
istool install-skills --target all --scope project --project /path/to/project --ue-template
Claude Code is the strictest target because it supports a PreToolUse hook for
Bash commands. Codex and OpenCode receive skill/AGENTS.md instructions, and
Cursor receives an always-on rule file; those surfaces guide the agent but do
not provide the same hard interception as Claude's hook.
IndexSearch is distributed under the terms of both the MIT license and the
Apache License 2.0. You may choose either license; see LICENSE-MIT and
LICENSE-APACHE.
The references to ripgrep and qgrep are compatibility and benchmark references only; their source code is not vendored into IndexSearch.