Metadata-Version: 2.5
Name: jupyterlab-r-folding
Version: 0.1.0
Summary: R code folding for JupyterLab 4.6 notebook cells and editors
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: jupyterlab<5,>=4.6.4
Description-Content-Type: text/markdown

# JupyterLab R Folding

为 JupyterLab **4.6.4** 的 R Notebook 代码单元和 `.R` 编辑器添加代码折叠。
基于 CodeMirror 6 `foldService` 和 JupyterLab 公共编辑器扩展注册接口。
插件是预编译前端扩展，与 IRkernel、Ark、xeus-r 无关，无需向 R 安装包。

## 安装

在**启动 JupyterLab 的 Python 环境**中执行，不能只安装到 R 内核环境：

```bash
python -m pip install ./jupyterlab_r_folding-0.1.0-py3-none-any.whl
python -m jupyterlab.labextensions list
```

如果你的启动环境为 `/root/miniforge3/envs/jpl`：

```bash
/root/miniforge3/envs/jpl/bin/python -m pip install ./jupyterlab_r_folding-0.1.0-py3-none-any.whl
/root/miniforge3/envs/jpl/bin/python -m jupyterlab.labextensions list
```

安装 wheel 不需要 Node.js、不需要 `jupyter lab build`，也不依赖扩展管理器的 PyPI 搜索。
重启 JupyterLab 服务，浏览器按 Ctrl+F5 刷新。

## 开启 Notebook 折叠栏

进入 Settings → Settings Editor → Notebook，开启 Code Folding；如果图形设置没有该项，
切换 JSON 设置编辑器，在 Notebook 的用户设置中合并以下字段：

```json
{
  "codeCellConfig": {
    "codeFolding": true,
    "lineNumbers": true
  }
}
```

保留你的其他 Notebook 设置。折叠栏沿用 JupyterLab 原生实现，插件不会重复添加折叠栏。
如果只需要 `.R` 编辑器，Text Editor 的用户设置为：

```json
{
  "editorConfig": {
    "codeFolding": true,
    "lineNumbers": true
  }
}
```

点击代码行左侧的折叠标记收起，再次点击展开。快捷键在编辑模式中使用：

| 操作 | Windows / Linux | macOS |
| --- | --- | --- |
| 折叠当前行代码块 | Ctrl+Alt+F | Ctrl+Option+F |
| 展开当前行代码块 | Ctrl+Alt+U | Ctrl+Option+U |
| 折叠当前单元全部代码块 | Ctrl+Alt+[ | Ctrl+Option+[ |
| 展开当前单元全部代码块 | Ctrl+Alt+] | Ctrl+Option+] |

JupyterLab 的 Ctrl+Shift+[ / ] 用于切换标签页，因此插件使用上述独立快捷键。
这些快捷键作用于当前编辑器（Notebook 中为当前单元）。
不会删除代码，也不会影响执行结果。折叠状态只在当前编辑器生命周期内保留；
刷新页面或重新打开文件后不保证保留。

## 支持的范围

- 跨行 `{ ... }`：函数、`if/else`、`for/while/repeat`、匿名函数。
- 跨行 `( ... )`：模型、`list()`、`data.frame()`、`lapply()` 等多行参数。
- 跨行 `[ ... ]` 和 `[[ ... ]]`：多行索引。
- 显式 `# region 标题` / `# endregion`，允许嵌套，要求标记独占一行。
- 顶层 RStudio 分节 `# 标题 ----`、`# 标题 ==== `、`# 标题 ####`，以及
  `#==================== 参数 ====================`。
  从标题行折叠到下一个标题前，最后一个标题折叠到当前单元末尾。
- 字符串、反引号名称、原始字符串、注释和 `%...%` 运算符中的括号不会误配对。

例子（也见 `examples/R-folding-demo.ipynb`）：

```r
#==================== 参数 ====================
ref <- "Po"
test <- "ne"

#==================== 拟合模型 ====================
fit_one <- function(d) {
  fit <- glmmTMB::glmmTMB(
    crop_volume ~ type_label + Group + (1 | hive_number),
    family = Gamma(link = "log"),
    data = d
  )
  summary(fit)
}

# region 结果整理
results <- list(
  reference = ref,
  comparison = test
)
# endregion
```

R 不按缩进定义语法块，因此没有大括号的任意缩进代码、无括号的管道链不会自动折叠。
这类代码可用 `# region` 标记。折叠范围不会跨 Notebook 单元。
算法是线性词法扫描，不是完整的 R 语法解析器；未配对的括号和未结束的 region 不提供折叠。
R 单元依照编辑器 MIME `text/x-rsrc` 识别。Python Notebook 中的 `%%R` 嵌入单元未单独支持。
不支持 JupyterLab 3 / CodeMirror 5。依赖约束允许 JupyterLab 4.6.4 到 4.x，
验证目标为 4.6.4；未来 4.x 或 4.7 预发布版需重新验证。

## 排查

1. `python -m jupyterlab --version` 应为 4.6.4 或满足依赖的后续 4.x。
2. `python -m jupyterlab.labextensions list` 应包含 `jupyterlab-r-folding`，显示 enabled、OK。
3. 确认是 R Notebook，代码语法着色正常，并打开 `codeFolding`。
4. 用 `f <- function(x) {`、下一行 `x + 1`、下一行 `}` 三行代码验证。
5. 若只修改配置，重新打开 Notebook；新安装插件需重启服务并强制刷新。
6. 使用折叠快捷键时先按 Enter 进入单元编辑模式。

禁用与卸载：

```bash
python -m jupyterlab.labextensions disable jupyterlab-r-folding
python -m pip uninstall jupyterlab-r-folding
```

## 修改源码 / 重建

源码压缩包包含 `package-lock.json`、TypeScript 源码、测试及预编译文件。
安装 Node.js 22+ 与 Python 3.10+，在解压后的项目目录运行：

```bash
python -m pip install "jupyterlab==4.6.4" build hatchling
npm ci
npm run typecheck
npm test
npm run build
python -m build --no-isolation
python -m pip install --force-reinstall --no-deps ./dist/jupyterlab_r_folding-0.1.0-py3-none-any.whl
```

`src/folding.ts`：独立 R 词法扫描器；`src/extension.ts`：缓存、foldService、快捷键；
`src/index.ts`：JupyterLab 插件入口。CodeMirror 依赖设为共享 singleton，避免重复状态类型。

## 验证结果

在 JupyterLab 4.6.4 中完成 TypeScript 类型检查、25 项自动测试和 wheel 安装检查（enabled / OK）。
浏览器验证通过：插件自动激活、原生折叠栏、鼠标收起/展开、四个快捷键、R 与纯文本 MIME 切换。
验证折叠前后单元源代码完全一致。大型单元测试覆盖 10,000 个函数、30,000 行代码。
浏览器测试使用无内核 R Notebook，证明折叠不依赖 R 进程；未逐一安装不同 R 内核验证。

## 官方依据（核实日期：2026-10-10）

- https://github.com/jupyterlab/jupyterlab/releases （最新稳定版 v4.6.4，4.7.0a2 为预发布）
- https://github.com/jupyterlab/jupyterlab/blob/v4.6.4/packages/codemirror/src/language.ts （R 使用 legacy-modes，MIME text/x-rsrc）
- https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html
- https://jupyterlab.readthedocs.io/en/stable/api/interfaces/codemirror.IEditorExtensionRegistry.html
- https://codemirror.net/docs/ref/#language.foldService
- https://discuss.codemirror.net/t/enable-foldgutter-for-legacy-mode-languages/5017

MIT License.
