jbearak/raven
GitHub: jbearak/raven
Raven 是一款 R 语言静态分析器和 LSP 语言服务器,无需运行代码即可提供跨文件的作用域感知代码智能、错误诊断和 CI 自动化检查。
Stars: 2 | Forks: 0
# Raven
Raven 是一款针对 R 语言的静态分析器,它能够解析每一行代码所处的作用域——从而捕获未定义和未定义前即使用的变量(即便是在单个脚本中,也能通过追踪 `source()` 链跨文件实现)——这一切都无需运行你的代码。同样的作用域模型驱动了它其余的代码智能功能——自动补全、转到定义、查找引用、悬停提示——因此每个功能反映的都是光标处实际可访问的内容,而不仅仅是项目中某处存在的内容。它还能诊断语法错误,并可选地检查代码风格和格式。
Raven 速度极快,能够在你的编辑器中实时执行所有这些操作,诊断信息会在你输入时瞬间更新。它还填补了工作流另一端的空白:Pull Request 中的自动化检查——运行 `raven check` 可以在代码合并前标记出未定义变量和其他错误,这种自动化审查在其他语言中早已是基本要求,但在 R 语言中却长期缺失。
在 R 语言中做好这项工作非常困难——这也是为什么该语言几乎没有静态工具的部分原因。R 极度依赖[非标准求值](docs/non-standard-evaluation.md)(NSE):函数可以将参数作为未求值的代码接收,并在运行时决定这些符号的含义,因此 `dplyr::filter(df, col > 0)` 中的 `col` 是一个数据框列,而不是未定义的变量。一个不考虑这一点的检查器会将地道的 R 代码标记为错误;Raven 能够识别这些 NSE 上下文并对其不予标记——尽管那些在运行时将名称引入作用域的代码(例如 `attach()`)仍可能引发误报,你可以通过使用[指令](docs/directives.md)声明这些符号来解决。同样的分析不仅是防御性的:只要能在静态下确定对象的结构,Raven 就会自动补全其字段——开始输入 `fruit$a`,它就能在你打开文件的那一刻建议补全 `apple`,完全不需要 R 会话。
除了代码智能之外,Raven 的 VS Code 扩展还能将 R 工作流的其余部分整合进编辑器——带有[绘图](docs/plot-viewer.md)和[数据](docs/data-viewer.md)查看器的 [R 控制台](docs/r-console.md)——但它的设计初衷是增强而非改变你的现有配置:那些基于 R 会话的功能默认会交由 REditorSupport 或 Positron 处理,并且语言服务器可以与 [r-language-server](https://github.com/REditorSupport/languageserver) 并行运行或取而代之([详见下文](#how-raven-differs))。
Raven 是完全开源的([GPL-3.0](LICENSE))且不依赖于特定编辑器:它使用 Language Server Protocol,因此可以在 VS Code、Neovim、Zed 或任何 LSP 客户端中运行——包括通过 VS Code Remote-SSH 运行,这样你就可以在计算能力远超笔记本电脑的远程服务器上进行开发。
Raven 的兄弟项目 [Sight](https://github.com/jbearak/sight) 实现了用于 Stata 的语言服务器。它们共同为社会科学研究中广泛使用的两种语言带来了跨文件导航、错误检测和代码智能功能。
## 功能
### 代码智能
- **[自动补全](docs/completion.md)** — 跨文件的符号、包和函数参数
- **[转到定义](docs/go-to-definition.md)** — 跨越文件边界跳转到定义
- **[查找引用](docs/find-references.md)** — 定位项目中某个符号的所有用法
- **[悬停提示](docs/hover.md)** — 包含源文件和包来源的符号信息
- **[诊断](docs/diagnostics.md)** — 能够理解引用文件和已加载包的未定义变量检测
- **[非标准求值](docs/non-standard-evaluation.md)** — 针对数据屏蔽、tidyselect、ggplot 映射、Shiny、foreach 和自定义辅助工具的 NSE 感知诊断
- **[代码检查](docs/linting.md)** — 可选的风格/检查规则(行长、尾随空格、尾随空行、制表符、赋值运算符、对象名称、中缀空格、被注释的代码、缩进)
- **[文档大纲](docs/document-outline.md)** — 包含节、类和嵌套函数的分层视图
- **工作区符号** — 全项目符号搜索 (Cmd/Ctrl+T)
- **文件路径智能提示** — 在 `source()` 路径内提供自动补全和 cmd+click 功能
- **[智能缩进](docs/indentation.md)** — 具备上下文感知能力的自动缩进,采用 RStudio 风格的对齐方式
- **[跨文件感知](docs/cross-file.md)** — 跟踪 `source()` 链以解析跨文件的作用域
- **[指令](docs/directives.md)** — 声明分析器无法推断的关系和符号
- **[语法高亮](docs/syntax-highlighting.md)** — 通过 LSP 语义 token 实现的 R 函数名称高亮,以及 JAGS 和 Stan 的语法高亮
Raven 还为 **JAGS** (`.jags`, `.bugs`) 和 **Stan** (`.stan`) 文件提供了轻量级支持:[语法高亮](docs/syntax-highlighting.md#jags-and-stan)、[自动补全](docs/completion.md#jags-and-stan)(关键字、分布、文件局部符号)、[转到定义](docs/go-to-definition.md#jags-and-stan)、[查找引用](docs/find-references.md#jags-and-stan)以及[带有模型结构导航的文档大纲](docs/document-outline.md#jags-and-stan-model-structure)。
### R 会话集成
- **[R 控制台](docs/r-console.md)** — 交互式 R 控制台,具备语句检测和针对大型代码块的临时文件回退机制;支持 R、arf 和 radian
- **[代码块](docs/chunks.md)** — R Markdown / Quarto 代码块检测,附带 Run Chunk / Run Above / Run All 命令、CodeLens 按钮、导航和背景高亮;代码块主体内具备完整的 R 语言智能(诊断、补全、悬停、导航);支持 `.R` 文件中的 `# %%` 单元格
- **[Knit 预览 + 导出](docs/knit.md)** — `Raven: Knit Preview` 无需 Pandoc 即可将 R Markdown 渲染为 HTML 预览;配套的 `Export to HTML / PDF / Word` 命令可通过 Pandoc 将结果保存到 `.Rmd` 旁边
- **[绘图查看器](docs/plot-viewer.md)** — 通过 [httpgd](https://nx10.dev/httpgd/) 在 VS Code 面板中渲染图表,支持历史导航、保存 (PNG/SVG/PDF) 以及随主题自适应的背景
- **[数据查看器](docs/data-viewer.md)** — `View(df)` 可打开由 Apache Arrow 支持的虚拟化网格;基于视口的渲染使得在数百万行的数据框上滚动依然保持流畅
- **[帮助查看器](docs/help-viewer.md)** — 具备作用域感知的 R 帮助:悬停时会显示光标处作用域内的函数,而不是在无法推断作用域时直接跳转到一个包含多包的列表
## Raven 的不同之处
Raven 采用静态分析方法,而不是附加到活动的 R 会话上,因此它可以在打开文件的那一刻就开始回答问题,而无需运行用户代码。这带来了四个实际影响:
- **即时可用,甚至适用于你尚未运行的代码** — 打开文件时即可获得答案,包括运行到一半报错的代码、缺少依赖项的代码,或者你仅仅是在阅读的代码(上手新代码库、审查 Pull Request)。基于会话的工具在代码完全跑通之前几乎无法提供帮助。
- **反映你的代码所写的内容,而不是你的会话所记住的内容** — 绑定到实时会话的工具只能看到当前 `globalenv()` 中的内容,这可能是过时的。在你的会话中仍然附加着 `library(dplyr)` 时注释掉它,基于会话的工具会继续补全 `dplyr` 函数;而 Raven 读取文件并知道它在那里并没有被加载。
- **只读且无副作用** — 计算作用域永远不会运行你的代码,因此它所做的任何事情(写文件、访问数据库、长时间运行的任务)都不会被触发。这也正是让 Raven 能够安全地在智能体/AI 工具后台运行的原因。
- **可在 CI 和其他无头环境中运行** — 作用域解析不需要活动的 R 会话,因此 Raven 的诊断和检查可以在 CI pipeline 或任何无头环境中运行。使用 [`raven check`](docs/cli.md#raven-check) 获取完整的诊断集(跨文件、未定义变量、包),使用 [`raven lint`](docs/cli.md#raven-lint) 进行仅针对风格的门控检查。
有关起源和初衷,请参阅[为什么创建 Raven](docs/comparison.md#why-raven-exists)。
**为共存而生,而非取代。** Raven 以两种不同的方式叠加到你现有的 R 配置上,且任何一种方式都不会接管一切。
*语言服务器是附加性的。* 它存在的理由是进行静态、跨文件的分析,并且它能与 [r-language-server](https://github.com/REditorSupport/languageserver) 并驾齐驱:安装 Raven,你就能在你已经运行的任何工具之上获得它的诊断、补全和导航功能。如果你不想让两个提供商同时提供补全,可以将 `r.lsp.enabled` 设置为 `false` 以关闭 REditorSupport 的语言服务器,让 Raven 独自处理代码智能。如果你想保留 REditorSupport 的语言服务器但不要它的 [`lintr`](https://lintr.r-lib.org/) 风格诊断,可以将 `r.lsp.diagnostics` 设置为 `false` —— 你将保留 Raven 的语法和作用域诊断,但没有风格检查。如果你想要找回一部分风格检查,Raven 内置了自选启用的检查器(`raven.linting.enabled`),可以通过 `.lintr` 文件(为了向后兼容)、`raven.toml` 或 VS Code 的设置 UI 进行配置——这提供了一种无需手写 `.lintr` 语法的点击式替代方案。Raven 还在你输入时融入了 [RStudio 风格的自动缩进](docs/indentation.md);它从不重新格式化整个文件,因此不会与像 [Air](https://github.com/posit-dev/air) (Posit) 这样专门的格式化工具发生冲突。社区已经有专门用于这些工作的工具了——Air 用于格式化,[lintr](https://lintr.r-lib.org/) 或 [Jarl](https://github.com/etiennebacher/jarl) 用于代码检查——而 Raven 的设计初衷就是与它们并肩运行。
*R 控制台和各类查看器会顺从你已经在使用的任何工具。* Raven 的 [R 控制台](docs/r-console.md)、它的[绘图](docs/plot-viewer.md)和[数据](docs/data-viewer.md)查看器,以及它的 [KnitPreview](docs/knit.md) 与 REditorSupport、RStudio 和 Positron 已经提供的功能有所重叠——如果你喜欢他们那种基于实时会话、监视工作区的工作方式,Raven 并不打算取代它。默认情况下,这些功能会主动让位:在 `raven.rConsole.activation` 的 `auto` 设置下,只要启用了 REditorSupport 或者你正在 Positron 中运行,它们就会退居幕后,因此安装 Raven 永远不会取代你现有的 R 集成。它们的存在有两个原因。首先,既然构建了一个刻意不需要实时 R 会话的语言服务器,我不希望随后又被强迫去搭配一个会将自身注入到会话中的工具——所以 Raven 提供了一个你*可以*独立运行的完整 R 工作流。其次,我有一些特定的偏好,这些查看器正是围绕这些偏好构建的:一个在数百万行数据下依然保持流畅、可以在 VS Code 重启后重新打开、在多次 `View()` 调用之间记住排序和过滤、并显示从 Stata / SPSS 导入数据的值标签的数据查看器,所有这些都无需等待活动的 R 会话(数据框会以 Arrow 格式流式传输到磁盘上);帮助功能只列出当前作用域内实际存在的函数(悬停在 `print()` 上你会看到 `base::print`,而不是一个列出了碰巧定义了 `print` 的所有包的列表);以及一个快速的 `.Rmd` 预览,它的正文字体、语法高亮和图表主题都能与你的编辑器相匹配。使用 `raven.rConsole.activation: "enabled"` 可在所有地方开启它们。(Raven 具备作用域感知的[帮助查看器](docs/help-viewer.md)无论如何都保持可用——它只在你点击 Raven 某个悬停提示中的链接时才会打开,所以它不会妨碍其他任何功能。)
有关与 RStudio、Positron (Ark) 和 REditorSupport 的详细对比——涵盖语言智能和 R 会话集成——请参阅 [docs/comparison.md](docs/comparison.md)。
## 安装
**VS Code:** 从 [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=jbearak.raven-r) 安装
**Cursor、Positron 及其他基于 VS Code 的编辑器:** 从 [OpenVSX](https://open-vsx.org/extension/jbearak/raven-r) 安装,或从发布页面](https://github.com/jbearak/raven/releases)下载 .vsix 文件并手动安装。
**其他编辑器:** 从[发布页面](https://github.com/jbearak/raven/releases)下载预构建的二进制文件,然后运行 `raven --stdio` 并通过你的编辑器的 LSP 客户端进行连接。有关 Zed、Neovim 和 AI 智能体的配置,请参阅[编辑器集成](docs/editor-integrations.md)。
**GitHub Actions:** 使用 `jbearak/setup-raven@v1` 安装预构建的 CLI,然后使用你想要的标志运行 `raven check`。请参阅 [CLI](docs/cli.md#github-actions-example)。
**从源码构建:** 使用 `cargo install --git https://github.com/jbearak/raven raven` 安装,或从本地检出代码进行构建。请参阅[开发说明](docs/development.md)。
## 文档
上方的每个功能都链接到了其专属页面。除此之外:
- [编辑器集成](docs/editor-integrations.md) — VS Code、Zed、Neovim、AI 智能体
- [配置](docs/configuration.md) — 所有设置和选项([字母顺序参考](docs/settings-reference.md))
- [CLI](docs/cli.md) — 用于 CI 和命令行用法的 `raven check`(完整诊断)和 `raven lint`(风格检查)
- [R 包开发](docs/r-package-dev.md) — 包模式、可见性规则和构建命令
- [`.Rprofile` 启动前奏](docs/rprofile.md) — Raven 如何为脚本作用域建模项目启动文件
- [非标准求值](docs/non-standard-evaluation.md) — Raven 如何处理 NSE,何时添加 `# raven: nse`,以及何时使用其他逃生舱
- [加速跨文件分析](docs/cross-file-analysis-performance.md) — 何时使用 `# raven: self-contained` 来改善对高扇出 source 图的分析
- [共存](docs/coexistence.md) — 与 REditorSupport (vscode-R) 和 Positron 并行运行
- [对比](docs/comparison.md) — Raven 与其他 R 工具的对比
- [代码块快捷键对比](docs/keybinding-comparison.md) — Raven、Quarto、RStudio 和 REditorSupport 之间的代码块快捷方式
- [限制](docs/limitations.md) — 尚未实现的功能
## 开发
有关构建/测试、性能分析和内部架构,请参阅[开发说明](docs/development.md)。
## 出处
Raven 包含了源自 [Ark](https://github.com/posit-dev/ark)(MIT License,Posit Software, PBC)的代码——最初的 LSP 接线和 tree-sitter 脚手架——以及源自 Raven 的姐妹项目 [Sight](https://github.com/jbearak/sight)(同为 GPL-3.0)的代码——跨文件感知系统(指令 + 具备位置感知的作用域模型)。内置的 R 和 R Markdown TextMate 语法来自 [vscode-R-syntax](https://github.com/REditorSupport/vscode-R-syntax) (MIT)。
Raven 可下载的包符号数据库是根据由 [rOpenSci](https://ropensci.org/r-universe/) 维护的 [r-universe](https://r-universe.dev) 发布的 CRAN/Bioconductor 元数据构建的。请参阅[包数据库](docs/package-database.md#data-source-and-acknowledgement)。
## 许可证
[GPL-3.0](LICENSE)。有关第三方署名,请参阅 [NOTICE](NOTICE)。
标签:IDE插件, LSP, R语言, SOC Prime, Subfinder, 代码质量检查, 开发工具, 通知系统, 错误基检测, 静态代码分析