ESC
开源 2 分钟阅读

disktree:为 Omarchy 打造的磁盘空间可视化清理工具,Rust + GPUI 构建

开源工具 disktree 发布,专为 Omarchy 桌面环境打造磁盘空间可视化分析。它基于 Rust 和 GPUI 构建,以 treemap 嵌套图展示各目录的实际磁盘占用,按数据类型着色,可标记缓存等可回收空间并安全删除,内置防止误删系统目录的多重保护规则。项目采用 MIT 协议,可通过预编译包或源码构建安装。

来源:GitHub

disktree

disktree:以 treemap 展示的主目录,按数据类型着色,可回收空间以斜线阴影标出,侧边面板显示选中项、发现和剩余空间

找出占用磁盘的东西,标记该删的内容并删除——整个过程始终显示卷的剩余空间。

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/、Makefiledesktop entry、图标和安装

界面遵循 GPUI Kit 设计指南: 每个尺寸都在同一套 rem 标度上,因此界面缩放能保持比例, primary 色保留给 Enter 执行的操作,而整个应用唯一会问的问题, 就是那个无法撤回的问题。

许可证

MIT