disktree

找出占用磁盘的东西,标记该删的内容并删除——整个过程始终显示卷的剩余空间。
disktree 是为 Omarchy 打造的一款 treemap(矩形树图)工具。它默认扫描你的主目录,将每个目录绘制成按实际磁盘占用大小排列的嵌套马赛克图,让你可以用键盘或鼠标在其中穿行。你可以随意标记;在你查看列表并确认之前不会发生任何操作,而永久删除路径总是会先询问。
它基于 GPUI 并通过 gpui-omarchy 构建,因此会遵循你的 Omarchy 主题,表现得像桌面的其他部分一样。
安装
从最新发布版下载
disktree-*-x86_64-linux.tar.gz,解压后在目录内运行 ./install.sh(或者直接把
disktree 复制到你的 PATH 中)。或者自行构建:
git clone https://github.com/tobi/disktree
cd disktree
make install
make install 会构建一个 release 二进制文件,并将三样东西放到 ~/.local 下(无需
root 权限):
~/.local/bin/disktree- 一个 desktop entry,让 disktree 出现在启动器以及文件管理器对目录的打开方式中(它只添加一个处理程序,永远不会成为默认)
- 一个图标
sudo make install PREFIX=/usr/local 安装到系统范围;make uninstall 会精确移除已安装的内容。
你需要 Rust 1.97 或更新版本,以及一个 Wayland 或 X11 会话,且 GPU(Vulkan)能被 GPUI 驱动。
使用
disktree # 扫描主目录
disktree --disk # 它所在的整个磁盘
disktree ~/src # 或任意目录
disktree --help # 选项:表观大小、跟随链接、跳过隐藏文件……
界面布局
- 顶部: 从
/开始的路径轨迹,然后是当前测量内容——大小、文件数或 时间、隐藏文件、表观大小,以及绘制的深度。在树中,面包屑可以跳转到该处, 其 ▾ 会列出同级目录,按占用从大到小排列并显示份额和大小,便于横向跳转(方向键和 Enter 也可以)。在扫描根之上,面包屑颜色更暗,点击它可以将扫描范围扩展到该处(见下文)。 - 其下: 扫描总计、输入过滤条件时的过滤器,以及图例。
- 马赛克: 颜色表示数据的类型——代码、agent 临时文件、工具链、同步文件、git、 媒体、文档、缓存——以统一的柔和色调显示,层级越深越亮。对角线阴影表示可以收回的空间 (缓存、同步历史、包存储、构建产物),与颜色无关。顶层目录带有一条颜色条和名称带; 更深层的打开目录则有一条细标签行。在时间模式下,颜色改为表示最后写入时间, 从本周到更早。
- 面板: 选中项(大小以大字显示、占扫描总量的份额、文件数、最后写入时间, 对于代码 checkout 还显示 git 的状态——更改、stash、未推送的提交); 值得关注,即最可能可以删除的大项;已标记的内容;以及磁盘信息, 当前剩余空间和标记后可释放的空间,还有进入审查界面的入口。拖动其左边缘可调整大小; 双击边缘可重置。
有一种颜色是专门保留的:琥珀色用于标记选中项、主操作以及可以收回的内容。
这些类型来自目录名称和一些特征形状(裸 git 仓库、Cargo.toml 旁边的
target)。有些名称是特定于某台机器的;参见
crates/disktree-core/src/classify.rs。
标记
Space、X、Enter 和方向键作用于鼠标悬停的磁贴(如果最后移动的是鼠标), 或者在你使用方向键或 Tab 后作用于键盘选中项。
被标记的磁贴会呈现危险色,其内部的所有内容也是如此:删除一个目录会连带其全部内容。 标记一个目录会吸收其中已有的任何标记,而已标记目录内的东西不能单独被标记或保留; 其面板会提供取消标记该目录的选项。标记是可逆的——再按一次即可—— 且节省的空间永远不会被重复计算。
缩放与深入
滚动可朝指针方向放大。滚轮会持续放大,直到指针下的目录填满视图,再滚一格则进入其中——
一个连贯的动作,目录的内容逐渐展开到位。反向滚动可以退出。Enter 可以在任意深度进入选中的目录,Backspace 或 Escape 向上一级。+ 和 -
只缩放而不进入;0 重置视图。
删除
c(或审查……)会打开所有已标记内容的列表。你可以在那里取消标记任何内容,
然后选择:
- 移到回收站——当回收站可用时这是默认选项(优先 trash-cli 的
trash-put,其次gio trash,最后是内置的 XDG 回收站)。在清空回收站之前都可恢复, 因此会直接提交。 - 永久删除——
rm -rf语义。它总是先询问,在对话框中说明将删除什么、 将回收多少空间。
完成后,disktree 会重新扫描,使屏幕上的数字与磁盘一致,并显示实际获得的可用空间。
按键
| 按键 | 功能 |
|---|---|
space / x | 标记或取消标记你指向的磁贴 |
ctrl-点击 | 在不移动选中项的情况下标记 |
enter | 打开该目录,任意深度 |
⌫ / esc | 向上一个目录 |
← ↑ ↓ → | 在同一层级的磁贴间移动 |
tab | 跳到下一个更大的同级目录 |
| 滚动 | 朝目录缩放,随后进入其中 |
shift-滚动 | 平移放大的视图 |
[ ] | 一次绘制更少或更多层级 |
- = 0 | 放大、缩小、重置视图 |
ctrl = ctrl - ctrl 0 | 界面缩放 |
/ | 按名称过滤:只有匹配项保留颜色;enter 只显示匹配项,esc 清除 |
c | 审查已标记列表 |
t | 按大小或文件数排序 |
d | 磁盘占用或表观大小 |
i | 包含或跳过隐藏条目 |
r | 重新扫描 |
g | 扫描整个磁盘 |
p | 显示或隐藏选中项信息行 |
? | 所有按键 |
q | 退出 |
在审查界面:m 移到回收站,p 永久删除,! 全部取消标记,enter
提交,esc 返回。
它测量什么
- 默认测量磁盘占用:
st_blocks × 512,即du报告的数字, 也是删除文件后实际回收的空间。表观大小(ls -l显示的)只需一个开关即可切换。 - 硬链接只计算一次。 同一 inode 的两个名称只算一个文件。
- 包含隐藏条目,因为
~/.cache往往是主目录中最大的东西。不跟随符号链接。
扫描遵循 dust 的方法:每个根一个 rayon scope,每个目录一个完成计数器,确保在最后一个子目录完成之前不会构建该目录, 以及一次自底向上的遍历来聚合大小并去除重复硬链接。
整个磁盘
在路径轨迹中点击 /(或扫描根之上的任何目录),按 g,运行
disktree --disk,或使用启动器中的扫描整个磁盘操作。g 和 --disk
扫描你的主目录所在的磁盘——在 Omarchy 上就是 /。
扩展扫描是经过记忆化的:已测量的树会被交给更大范围的遍历并在到达处复用,
因此从 ~ 到 / 只需读取 ~ 之外的内容(在这台机器上只需几秒,
而不是完整重扫)。当前视图会一直留在屏幕上,直到更大的树完成,
随后打开时你原来所在的目录会保持选中。往回走只是普通导航。
扫描只停留在一个卷上,而卷指的是挂载源,不是设备号:btrfs
会给每个子卷分配自己的 st_dev,因此 /home、/var/log 和
/var/cache/pacman/pkg 会被包含,而 /proc、/sys、/run、tmpfs、
/boot、其他磁盘、网络共享和自动挂载点会被排除(通过路径判断,
因此不会为了测量而挂载一个自动挂载的 NAS)。快照子卷也被排除:
它们的文件与活动文件共享数据块,统计它们会重复计算磁盘。-X
则会进入一切。
没有 root 权限时,某些系统目录无法读取;它们会在顶栏中被计为不可读, 而不是凭猜测。
它拒绝做的事
删除规则位于 crates/disktree-core/src/removal.rs,每条规则都有测试:
- 只有扫描根之下的路径才能被删除;
- 文件系统根、扫描根和你的主目录一律拒绝;
- 挂载点一律拒绝,因为删除它会波及另一个文件系统;
- 系统目录树(
/usr、/etc、/boot、/var/lib、/nix/store等)一律拒绝, 即使权限允许:它们由软件包管理,pacman、paccache 或journalctl --vacuum才是正确的工具; - 符号链接只做 unlink,绝不跟随;
- 任何东西都不经过 shell 传递——一个名为
-rf的文件只是一个普通文件。
在 Hyprland 上
Hyprland 会平铺新窗口,因此 disktree 会被塞进任意一个磁贴中。 它是为宽敞的窗口设计的;将其浮动,或给它一条规则:
windowrule = float, class:^(disktree)$
windowrule = size 1400 900, class:^(disktree)$
开发
make run # release 构建,扫描 $HOME
make lint # rustfmt --check,然后 clippy 将所有警告视为错误
make test # 扫描器、布局和删除测试,加上窗口测试框架测试
make ci # 先 lint,再 test
lint 关卡是刻意严格的:clippy::all 和 clippy::pedantic 都视为错误,
每个例外都在 Cargo.toml 中写明了理由。窗口测试框架会绘制真实帧、
按下真实按键——其中一个测试会标记一个目录、确认删除,然后检查目标文件已消失
而其相邻文件不受影响。
| 路径 | 内容 |
|---|---|
crates/disktree-core | 扫描、树结构、squarified 布局、剩余空间和删除——不含 UI |
crates/disktree-app/src/state.rs | 界面可执行的每个操作,以及键位映射 |
crates/disktree-app/src/views.rs | 各个界面 |
crates/disktree-app/src/treemap_view.rs | 马赛克绘制及其标签 |
crates/disktree-app/src/ui.rs | 间距、字体和尺寸标度,以 rem 为单位 |
crates/disktree-app/src/tests.rs | 通过真实窗口进行的端到端测试 |
packaging/、assets/、Makefile | desktop entry、图标和安装 |
界面遵循
GPUI Kit 设计指南:
每个尺寸都在同一套 rem 标度上,因此界面缩放能保持比例,
primary 色保留给 Enter 执行的操作,而整个应用唯一会问的问题,
就是那个无法撤回的问题。
许可证
MIT