ast-index 是一个用 Rust 编写的原生命令行代码搜索工具,面向多平台项目提供结构化代码搜索,底层使用 SQLite + FTS5 索引。
用途
ast-index 用于在代码库中快速查找类、符号、用法、实现、文件等。官方将其定位为代码搜索的首选工具,建议在 grep、ripgrep 或 Search 工具之前使用。据其说明,ast-index 比 grep 快 17-69 倍(1-10ms 对比 200ms-3s),并返回结构化、准确的结果。
支持的项目
工具通过标记文件(如 build.gradle.kts、Package.swift、Makefile.PL 等)自动检测项目类型,支持以下平台与语言:
- Android/Java:Kotlin、Java,模块系统为 Gradle(build.gradle.kts)、Maven(pom.xml)
- iOS:Swift、Objective-C,模块系统为 SPM(Package.swift)
- Web:TypeScript、JavaScript、React、Vue、Svelte,模块系统为 package.json
- Rust:Rust,模块系统为 Cargo.toml
- Ruby:Ruby、Rails、RSpec,模块系统为 Gemfile
- .NET:C#、ASP.NET、Unity,模块系统为 *.csproj
- Dart/Flutter:Dart,模块系统为 pubspec.yaml
- Scala:Scala,模块系统为 Bazel(WORKSPACE、BUILD)
- PHP:PHP,模块系统为 composer.json
- Perl:Perl,模块系统为 Makefile.PL、Build.PL
- Python:Python,无模块系统(*.py 文件)
- Go:Go,无模块系统(*.go 文件)
- Proto:Protocol Buffers(proto2/proto3),无模块系统(*.proto 文件)
- WSDL:WSDL、XSD,无模块系统(.wsdl、.xsd 文件)
- C/C++:C、C++(JNI、uservices),无模块系统(.cpp、.h、*.hpp 文件)
- Godot:GDScript,模块系统为 project.godot
- 混合项目:以上全部
Python、Go、Proto、WSDL 和 C++ 文件会与主项目类型一起被索引。压缩过的 JavaScript/CSS 不会被索引或搜索:命名为 .min. 或 -min. 的 .js/.mjs/.cjs/.css 文件,或前 64 KiB 为压缩器输出的文件会被跳过;设置 AST_INDEX_SKIP_MINIFIED=0 可关闭该过滤。
安装与初始化
安装 CLI:
brew tap defendend/ast-index brew install ast-index
在项目根目录初始化索引:
cd /path/to/project ast-index rebuild
索引存储在 ~/Library/Caches/ast-index/<project-hash>/index.db(macOS)或 ~/.cache/ast-index/<project-hash>/index.db(Linux)。rebuild 会构建全新索引并替换,命名子树和已收集的 Git 历史(hotspots --collect)会被保留。
主要能力
explore(一次性上下文)
对查询最相关的符号进行排序,展示最佳文件——包括类型或模块的大纲(含行范围,选中的定义以 → 标记)、函数的源码(从磁盘实时读取)、图邻居(调用者/子类)列表,并按路径约定定位测试,全部在一次调用中完成。语言无关且能识别第三方代码(node_modules 的 .d.ts 和跨栈匹配会被降权,但不会被删除)。
示例:
ast-index explore applicant merge MergeService ast-index explore "how does auth session work" ast-index explore PaymentService --rwr ast-index explore Repository --max-files 8 ast-index explore Session request --rwr --format json
默认(Stage A)按词法匹配 + 多词佐证排序。问题中的词也会被连读匹配(pdf to html service 可找到 PdfToHtmlService),并与文件路径匹配。--rwr(Stage B)在内存中构建调用/继承图,按个性化 PageRank 重新排序,在 "Graph neighbours" 部分展示调用者/子类。
search(通用搜索)
同时在文件、符号和模块中搜索。
ast-index search "Payment" ast-index search "Payment" --with-content ast-index search "ViewModel" ast-index search "Store" --fuzzy ast-index search "Handler" --module "core/" ast-index search "UserService" ast-index search "@RestController" ast-index search "@GetMapping"
符号按层级排列:精确名称,然后是最后一段 :: 或 . 段为查询的名称,再是部分匹配。每个层级内定义先于导入,项目代码先于 node_modules;部分匹配中测试符号排在最后。
search --rank <preset> 可按文件的 Git 历史和符号在依赖图中的位置重新排序 Files 和 Symbols 部分,并在每个结果旁附上说明。预设包括:proven(可复制的成熟示例)、hotspots(持续被修改和修复)、risky(危险:依赖多且历史不稳定)、central(其他部分依赖的核心,PageRank)。
其他核心命令
- file:按名称模式查找文件。如 ast-index file "Fragment.kt"
- symbol:按名称查找符号(类、接口、函数、属性)。支持 --with-content、--fuzzy、--in-file、--limit
- class:查找类、接口或协议定义
- usages:查找符号被使用的所有位置,对重构至关重要。索引符号约 8ms
- refs:显示符号的交叉引用:定义、导入和用法
- implementations:查找继承或实现给定类/接口/协议的所有类。参数是父类型
- hierarchy:显示完整的类层次树
- callers:查找调用某函数的行,按名称在查询时匹配
- call-tree:显示向上调用层次:调用所在的函数,然后是它的调用者
- graph:从索引构建的有向符号到符号图。支持 build、status、dependents、dependencies、impact、path、cycles、top、metrics 等子命令
使用方式与限制
官方给出的关键规则:始终优先使用 ast-index 进行代码搜索;如果 ast-index 找到了用法/实现,那就是完整答案,不要重复运行 grep;不要重新读取 --with-content 返回的内容。仅在以下情况使用 grep/Search:ast-index 返回空结果、搜索正则表达式(ast-index 使用字面匹配)、搜索代码中的字符串字面量、搜索注释内容。
usages 和 refs 会跳过字符串和注释中的名称。索引的用法包括首字母大写的名称和写作 name( 的调用,包含 snake_case 和 _private 名称;保留字(如 sizeof (x)、#if defined(X)、Go 的 func (r *T)、Python 的 None)不会被记录。
graph 的每条边都带有目标解析的置信级别:local(同文件)、scoped(显式命名空间、词法嵌套、常量接收者 Type.method 或继承/混入)、import(源文件导入目标的模块)、unique(该名称在语言中唯一定义)、ambiguous(多个候选,或对未知类型接收者的调用)。Fan-in、fan-out、dependents 和 PageRank 只统计已解析的边。
排名预设依赖数据:缺少数据时不会按零排名,预设不应用,结果保持普通顺序,输出会提示需要运行的命令。第三方代码(node_modules、.d.ts)从不参与评分,列在所有项目结果之后。
关于收费、价格、平台限制等更多信息,资料中暂未提供。