<pre style='margin:0'>
Vadym-Valdis Yudaiev (judaew) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/08862ef23c2f5a8e2a397e176346312413f0a2fc">https://github.com/macports/macports-ports/commit/08862ef23c2f5a8e2a397e176346312413f0a2fc</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 08862ef23c2f5a8e2a397e176346312413f0a2fc
</span>Author: Vadym-Valdis Yudaiev <judaew@macports.org>
AuthorDate: Fri Jan 20 13:24:05 2023 +0200

<span style='display:block; white-space:pre;color:#404040;'>    ncdu: update to 2.2.2
</span>---
 sysutils/ncdu/Portfile                   |  11 +-
 sysutils/ncdu/files/patch-zig-0.10.patch | 857 -------------------------------
 2 files changed, 4 insertions(+), 864 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/sysutils/ncdu/Portfile b/sysutils/ncdu/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 3328c1570b2..b8541515875 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/sysutils/ncdu/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/sysutils/ncdu/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -32,21 +32,18 @@ subport ncdu1 {
</span> }
 
 if {${subport} eq ${name}} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    version             2.2.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version             2.2.2
</span>     revision            0
     conflicts           ncdu1
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    checksums           rmd160  8d0ef44ce63f732e453136740a968124df49d494 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        sha256  5e4af8f6bcd8cf7ad8fd3d7900dab1320745a0453101e9e374f9a77f72aed141 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        size    55972
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    checksums           rmd160  d537972c6a31f73ca58d8345b5d7d8c86a4eef0a \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        sha256  90d920024e752318b469776ce57e03b3c702d49329ad9825aeeab36c3babf993 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        size    56096
</span> 
     depends_build       port:zig
 
     use_configure       no
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    patch.args          -p1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    patchfiles-append   patch-zig-0.10.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     # Build manually using `zig cc`. The standard build with the patch that adds
     # the --search-prefix option doesn't work. See:
     # https://trac.macports.org/ticket/66044
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/sysutils/ncdu/files/patch-zig-0.10.patch b/sysutils/ncdu/files/patch-zig-0.10.patch
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 52a3cee4a74..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/sysutils/ncdu/files/patch-zig-0.10.patch
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,857 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/browser.zig b/src/browser.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 13e09eb..8ec4765 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/browser.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/browser.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -83,22 +83,22 @@ fn sortLt(_: void, ap: ?*model.Entry, bp: ?*model.Entry) bool {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     switch (main.config.sort_col) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         .name => {}, // name sorting is the fallback
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         .blocks => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (sortIntLt(a.size, b.size)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         .size => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (sortIntLt(a.size, b.size)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         .items => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             const ai = if (a.dir()) |d| d.items else 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             const bi = if (b.dir()) |d| d.items else 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (sortIntLt(ai, bi)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (sortIntLt(a.blocks, b.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (sortIntLt(a.pack.blocks, b.pack.blocks)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (sortIntLt(a.size, b.size)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         .mtime => {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (!a.isext or !b.isext) return a.isext;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (!a.pack.isext or !b.pack.isext) return a.pack.isext;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (sortIntLt(a.ext().?.mtime, b.ext().?.mtime)) |r| return r;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -135,10 +135,10 @@ pub fn loadDir(next_sel: ?*const model.Entry) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         dir_items.append(null) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var it = dir_parent.sub;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     while (it) |e| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (e.blocks > dir_max_blocks) dir_max_blocks = e.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (e.pack.blocks > dir_max_blocks) dir_max_blocks = e.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (e.size > dir_max_size) dir_max_size = e.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         const shown = main.config.show_hidden or blk: {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            const excl = if (e.file()) |f| f.excluded else false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            const excl = if (e.file()) |f| f.pack.excluded else false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             const name = e.name();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             break :blk !excl and name[0] != '.' and name[name.len-1] != '~';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -164,14 +164,14 @@ const Row = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         const item = self.item orelse return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         const ch: u7 = ch: {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (item.file()) |f| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (f.err) break :ch '!';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (f.excluded) break :ch '<';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (f.other_fs) break :ch '>';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (f.kernfs) break :ch '^';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (f.notreg) break :ch '@';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (f.pack.err) break :ch '!';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (f.pack.excluded) break :ch '<';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (f.pack.other_fs) break :ch '>';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (f.pack.kernfs) break :ch '^';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (f.pack.notreg) break :ch '@';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else if (item.dir()) |d| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (d.err) break :ch '!';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (d.suberr) break :ch '.';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (d.pack.err) break :ch '!';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (d.pack.suberr) break :ch '.';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (d.sub == null) break :ch 'e';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else if (item.link()) |_| break :ch 'H';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -187,7 +187,7 @@ const Row = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             width += 2 + width;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         defer self.col += width;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         const item = self.item orelse return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        const siz = if (main.config.show_blocks) util.blocksToSize(item.blocks) else item.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        const siz = if (main.config.show_blocks) util.blocksToSize(item.pack.blocks) else item.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var shr = if (item.dir()) |d| (if (main.config.show_blocks) util.blocksToSize(d.shared_blocks) else d.shared_size) else 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.show_shared == .unique) shr = siz -| shr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -216,8 +216,8 @@ const Row = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.show_percent) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             self.bg.fg(.num);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.addprint("{d:>5.1}", .{ 100 *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (main.config.show_blocks) @intToFloat(f32, item.blocks) / @intToFloat(f32, std.math.max(1, dir_parent.entry.blocks))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                else                         @intToFloat(f32, item.size)   / @intToFloat(f32, std.math.max(1, dir_parent.entry.size))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (main.config.show_blocks) @intToFloat(f32, item.pack.blocks) / @intToFloat(f32, std.math.max(1, dir_parent.entry.pack.blocks))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                else                         @intToFloat(f32, item.size)        / @intToFloat(f32, std.math.max(1, dir_parent.entry.size))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             self.bg.fg(.default);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.addch('%');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -225,7 +225,7 @@ const Row = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.show_graph and main.config.show_percent) ui.addch(' ');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.show_graph) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             var max = if (main.config.show_blocks) dir_max_blocks else dir_max_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            var num = if (main.config.show_blocks) item.blocks else item.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            var num = if (main.config.show_blocks) item.pack.blocks else item.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (max < bar_size) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 max *= bar_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 num *= bar_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -290,7 +290,7 @@ const Row = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     fn name(self: *Self) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         ui.move(self.row, self.col);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (self.item) |i| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            self.bg.fg(if (i.etype == .dir) .dir else .default);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            self.bg.fg(if (i.pack.etype == .dir) .dir else .default);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.addch(if (i.isDirectory()) '/' else ' ');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.addstr(ui.shorten(ui.toUtf8(i.name()), ui.cols -| self.col -| 1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -460,7 +460,7 @@ const info = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.addstr("Type: ");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ui.style(.default);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            ui.addstr(if (e.isDirectory()) "Directory" else if (if (e.file()) |f| f.notreg else false) "Other" else "File");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            ui.addstr(if (e.isDirectory()) "Directory" else if (if (e.file()) |f| f.pack.notreg else false) "Other" else "File");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         row.* += 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -474,7 +474,7 @@ const info = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // Disk usage & Apparent size
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        drawSize(box, row, "   Disk usage: ", util.blocksToSize(e.blocks), if (e.dir()) |d| util.blocksToSize(d.shared_blocks) else 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        drawSize(box, row, "   Disk usage: ", util.blocksToSize(e.pack.blocks), if (e.dir()) |d| util.blocksToSize(d.shared_blocks) else 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         drawSize(box, row, "Apparent size: ", e.size, if (e.dir()) |d| d.shared_size else 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // Number of items
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -522,7 +522,7 @@ const info = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var row: u32 = 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // Tabs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (e.etype == .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (e.pack.etype == .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             box.tab(cols-19, tab == .info, 1, "Info");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             box.tab(cols-10, tab == .links, 2, "Links");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -543,7 +543,7 @@ const info = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     fn keyInput(ch: i32) bool {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (entry.?.etype == .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (entry.?.pack.etype == .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             switch (ch) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 '1', 'h', ui.c.KEY_LEFT => { set(entry, .info); return true; },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 '2', 'l', ui.c.KEY_RIGHT => { set(entry, .links); return true; },
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -778,7 +778,7 @@ pub fn draw() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.move(ui.rows-1, 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.style(if (main.config.show_blocks) .bold_hd else .hd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addstr("Total disk usage: ");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    ui.addsize(.hd, util.blocksToSize(dir_parent.entry.blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ui.addsize(.hd, util.blocksToSize(dir_parent.entry.pack.blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.style(if (main.config.show_blocks) .hd else .bold_hd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addstr("  Apparent size: ");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addsize(.hd, dir_parent.entry.size);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/delete.zig b/src/delete.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 22c2706..d98a2bd 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/delete.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/delete.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -45,8 +45,7 @@ fn deleteItem(dir: std.fs.Dir, path: [:0]const u8, ptr: *align(1) ?*model.Entry)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if (entry.dir()) |d| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        var fd = dir.openDirZ(path, .{ .access_sub_paths = true, .iterate = false })
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            catch |e| return err(e);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        var fd = dir.openDirZ(path, .{.no_follow = true}, false) catch |e| return err(e);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var it = &d.sub;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         parent = d;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         defer parent = parent.parent.?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -101,7 +100,7 @@ fn drawConfirm() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addstr("Are you sure you want to delete \"");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addstr(ui.shorten(ui.toUtf8(entry.name()), 21));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ui.addch('"');
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    if (entry.etype != .dir)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (entry.pack.etype != .dir)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         ui.addch('?')
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         box.move(2, 18);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/exclude.zig b/src/exclude.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 8e2b793..0528f30 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/exclude.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/exclude.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -120,7 +120,7 @@ test "parse" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // the match result is only used to construct the PatternList of the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // subdirectory) and patterns without a sub-pointer (where the match result
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // determines whether the file/dir at this level should be included or not).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--fn PatternList(withsub: bool) type {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+fn PatternList(comptime withsub: bool) type {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     return struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         literals: std.HashMapUnmanaged(*const Pattern, Val, Ctx, 80) = .{},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         wild: std.ArrayListUnmanaged(*const Pattern) = .{},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -150,7 +150,7 @@ fn PatternList(withsub: bool) type {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var e = self.literals.getOrPut(main.allocator, pat) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (!e.found_existing) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     e.key_ptr.* = pat;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    e.value_ptr.* = .{};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    e.value_ptr.* = if (withsub) .{} else {};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (!withsub and !pat.isdir and e.key_ptr.*.isdir) e.key_ptr.* = pat;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (withsub) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -165,14 +165,14 @@ fn PatternList(withsub: bool) type {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (self.literals.getKey(&.{ .pattern = name })) |p| ret = p.isdir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             for (self.wild.items) |p| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (ret == false) return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (c.fnmatch(p.pattern, name, 0) == 0) ret = p.isdir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (c.fnmatch(p.pattern.ptr, name.ptr, 0) == 0) ret = p.isdir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             return ret;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         fn enter(self: *const Self, out: *Patterns, name: [:0]const u8) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (self.literals.get(&.{ .pattern = name })) |lst| for (lst.items) |sub| out.append(sub);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            for (self.wild.items) |p| if (c.fnmatch(p.pattern, name, 0) == 0) out.append(p.sub.?);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            for (self.wild.items) |p| if (c.fnmatch(p.pattern.ptr, name.ptr, 0) == 0) out.append(p.sub.?);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         fn deinit(self: *Self) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/main.zig b/src/main.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a04d96f..c2dd268 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/main.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/main.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -261,7 +261,8 @@ fn tryReadArgsFile(path: [:0]const u8) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer f.close();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var arglist = std.ArrayList([:0]const u8).init(allocator);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var rd = std.io.bufferedReader(f.reader()).reader();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var rd_ = std.io.bufferedReader(f.reader());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var rd = rd_.reader();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var linebuf: [4096]u8 = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     while (
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -343,8 +344,7 @@ fn spawnShell() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         env.put("NCDU_LEVEL", "1") catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const shell = std.os.getenvZ("NCDU_SHELL") orelse std.os.getenvZ("SHELL") orelse "/bin/sh";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var child = std.ChildProcess.init(&.{shell}, allocator) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    defer child.deinit();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var child = std.ChildProcess.init(&.{shell}, allocator);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     child.cwd = path.items;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     child.env_map = &env;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -380,7 +380,8 @@ fn spawnShell() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fn readExcludeFile(path: [:0]const u8) !void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const f = try std.fs.cwd().openFileZ(path, .{});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer f.close();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var rd = std.io.bufferedReader(f.reader()).reader();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var rd_ = std.io.bufferedReader(f.reader());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var rd = rd_.reader();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var buf = std.ArrayList(u8).init(allocator);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer buf.deinit();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     while (true) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/model.zig b/src/model.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 75cfe3d..d93d5b7 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/model.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/model.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -17,7 +17,7 @@ const allocator = allocator_state.allocator();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pub const EType = enum(u2) { dir, link, file };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--// Type for the Entry.blocks field. Smaller than a u64 to make room for flags.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+// Type for the Entry.Packed.blocks field. Smaller than a u64 to make room for flags.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pub const Blocks = u60;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Memory layout:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -31,93 +31,98 @@ pub const Blocks = u60;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // These are all packed structs and hence do not have any alignment, which is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // great for saving memory but perhaps not very great for code size or
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // performance.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--// (TODO: What are the aliassing rules for Zig? There is a 'noalias' keyword,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--// but does that mean all unmarked pointers are allowed to alias?)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    etype: EType,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    isext: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    // Whether or not this entry's size has been counted in its parents.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    // Counting of Link entries is deferred until the scan/delete operation has
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    // completed, so for those entries this flag indicates an intention to be
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    // counted.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    counted: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    blocks: Blocks, // 512-byte blocks
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    size: u64,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    next: ?*Entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pub const Entry = extern struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pack: Packed align(1),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    size: u64 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    next: ?*Entry align(1) = null,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pub const Packed = packed struct(u64) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        etype: EType,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        isext: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        // Whether or not this entry's size has been counted in its parents.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        // Counting of Link entries is deferred until the scan/delete operation has
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        // completed, so for those entries this flag indicates an intention to be
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        // counted.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        counted: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        blocks: Blocks = 0, // 512-byte blocks
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const Self = @This();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn dir(self: *Self) ?*Dir {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return if (self.etype == .dir) @ptrCast(*Dir, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return if (self.pack.etype == .dir) @ptrCast(*Dir, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn link(self: *Self) ?*Link {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return if (self.etype == .link) @ptrCast(*Link, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return if (self.pack.etype == .link) @ptrCast(*Link, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn file(self: *Self) ?*File {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return if (self.etype == .file) @ptrCast(*File, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return if (self.pack.etype == .file) @ptrCast(*File, self) else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // Whether this entry should be displayed as a "directory".
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // Some dirs are actually represented in this data model as a File for efficiency.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn isDirectory(self: *Self) bool {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return if (self.file()) |f| f.other_fs or f.kernfs else self.etype == .dir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    fn nameOffset(etype: EType) usize {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return switch (etype) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .dir => @offsetOf(Dir, "name"),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .link => @offsetOf(Link, "name"),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .file => @offsetOf(File, "name"),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return if (self.file()) |f| f.pack.other_fs or f.pack.kernfs else self.pack.etype == .dir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn name(self: *const Self) [:0]const u8 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        const ptr = @ptrCast([*:0]const u8, self) + nameOffset(self.etype);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return std.mem.sliceTo(ptr, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        const ptr = switch (self.pack.etype) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .dir => &@ptrCast(*const Dir, self).name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .link => &@ptrCast(*const Link, self).name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .file => &@ptrCast(*const File, self).name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return std.mem.sliceTo(@ptrCast([*:0]const u8, ptr), 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn ext(self: *Self) ?*Ext {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (!self.isext) return null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (!self.pack.isext) return null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return @ptrCast(*Ext, @ptrCast([*]Ext, self) - 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    fn alloc(comptime T: type, etype: EType, isext: bool, ename: []const u8) *Entry {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        const size = (if (isext) @as(usize, @sizeOf(Ext)) else 0) + @sizeOf(T) + ename.len + 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        var ptr = blk: while (true) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (allocator.allocWithOptions(u8, size, 1, null)) |p| break :blk p
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            else |_| {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            ui.oom();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (isext) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            @ptrCast(*Ext, ptr).* = .{};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            ptr = ptr[@sizeOf(Ext)..];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        const e = @ptrCast(*T, ptr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        e.* = .{ .entry = .{ .pack = .{ .etype = etype, .isext = isext } } };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        const n = @ptrCast([*]u8, &e.name)[0..ename.len+1];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        std.mem.copy(u8, n, ename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        n[ename.len] = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return &e.entry;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn create(etype: EType, isext: bool, ename: []const u8) *Entry {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        const extsize = if (isext) @as(usize, @sizeOf(Ext)) else 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        const size = nameOffset(etype) + ename.len + 1 + extsize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        var ptr = blk: {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            while (true) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (allocator.allocWithOptions(u8, size, std.math.max(@alignOf(Ext), @alignOf(Entry)), null)) |p|
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    break :blk p
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                else |_| {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                ui.oom();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return switch (etype) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .dir  => alloc(Dir, etype, isext, ename),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .file => alloc(File, etype, isext, ename),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .link => alloc(Link, etype, isext, ename),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        std.mem.set(u8, ptr, 0); // kind of ugly, but does the trick
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        var e = @ptrCast(*Entry, ptr.ptr + extsize);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        e.etype = etype;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        e.isext = isext;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        var name_ptr = @ptrCast([*]u8, e) + nameOffset(etype);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        std.mem.copy(u8, name_ptr[0..ename.len], ename);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        return e;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // Set the 'err' flag on Dirs and Files, propagating 'suberr' to parents.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn setErr(self: *Self, parent: *Dir) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (self.dir()) |d| d.err = true
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        else if (self.file()) |f| f.err = true
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (self.dir()) |d| d.pack.err = true
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        else if (self.file()) |f| f.pack.err = true
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         else unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var it: ?*Dir = if (&parent.entry == self) parent.parent else parent;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         while (it) |p| : (it = p.parent) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (p.suberr) break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            p.suberr = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (p.pack.suberr) break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            p.pack.suberr = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn addStats(self: *Entry, parent: *Dir, nlink: u31) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (self.counted) return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        self.counted = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (self.pack.counted) return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        self.pack.counted = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // Add link to the inode map, but don't count its size (yet).
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (self.link()) |l| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -125,7 +130,7 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             var d = inodes.map.getOrPut(l) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (!d.found_existing) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 d.value_ptr.* = .{ .counted = false, .nlink = nlink };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                inodes.total_blocks +|= self.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                inodes.total_blocks +|= self.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 l.next = l;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 inodes.setStats(.{ .key_ptr = d.key_ptr, .value_ptr = d.value_ptr }, false);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -144,9 +149,9 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (p.entry.ext()) |pe|
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     if (e.mtime > pe.mtime) { pe.mtime = e.mtime; };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             p.items +|= 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (self.etype != .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (self.pack.etype != .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 p.entry.size +|= self.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                p.entry.blocks +|= self.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                p.entry.pack.blocks +|= self.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -165,8 +170,8 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // anymore, meaning that delStats() followed by addStats() with the same
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // data may cause information to be lost.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn delStats(self: *Entry, parent: *Dir) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (!self.counted) return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        defer self.counted = false; // defer, to make sure inodes.setStats() still sees it as counted.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (!self.pack.counted) return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        defer self.pack.counted = false; // defer, to make sure inodes.setStats() still sees it as counted.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (self.link()) |l| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             var d = inodes.map.getEntry(l).?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -175,7 +180,7 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (l.next == l) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 _ = inodes.map.remove(l);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 _ = inodes.uncounted.remove(l);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                inodes.total_blocks -|= self.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                inodes.total_blocks -|= self.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (d.key_ptr.* == l)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     d.key_ptr.* = l.next;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -195,9 +200,9 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var it: ?*Dir = parent;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         while(it) |p| : (it = p.parent) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             p.items -|= 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (self.etype != .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (self.pack.etype != .link) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 p.entry.size -|= self.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                p.entry.blocks -|= self.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                p.entry.pack.blocks -|= self.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -212,32 +217,35 @@ pub const Entry = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--const DevId = u30; // Can be reduced to make room for more flags in Dir.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+const DevId = u30; // Can be reduced to make room for more flags in Dir.Packed.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--pub const Dir = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pub const Dir = extern struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     entry: Entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    sub: ?*Entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    parent: ?*Dir,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    sub: ?*Entry align(1) = null,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parent: ?*Dir align(1) = null,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // entry.{blocks,size}: Total size of all unique files + dirs. Non-shared hardlinks are counted only once.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     //   (i.e. the space you'll need if you created a filesystem with only this dir)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // shared_*: Unique hardlinks that still have references outside of this directory.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     //   (i.e. the space you won't reclaim by deleting this dir)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // (space reclaimed by deleting a dir =~ entry. - shared_)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    shared_blocks: u64,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    shared_size: u64,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    items: u32,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    // Indexes into the global 'devices.list' array
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    dev: DevId,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    shared_blocks: u64 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    shared_size: u64 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    items: u32 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    err: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    suberr: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pack: Packed align(1) = .{},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // Only used to find the @offsetOff, the name is written at this point as a 0-terminated string.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // (Old C habits die hard)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    name: u8,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    name: [0]u8 = undefined,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pub const Packed = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        // Indexes into the global 'devices.list' array
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        dev: DevId = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        err: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        suberr: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     pub fn fmtPath(self: *const @This(), withRoot: bool, out: *std.ArrayList(u8)) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (!withRoot and self.parent == null) return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -259,16 +267,16 @@ pub const Dir = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // File that's been hardlinked (i.e. nlink > 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--pub const Link = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pub const Link = extern struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     entry: Entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    parent: *Dir,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    next: *Link, // Singly circular linked list of all *Link nodes with the same dev,ino.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parent: *Dir align(1) = undefined,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    next: *Link align(1) = undefined, // Singly circular linked list of all *Link nodes with the same dev,ino.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // dev is inherited from the parent Dir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    ino: u64,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    name: u8,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ino: u64 align(1) = undefined,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    name: [0]u8 = undefined,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     // Return value should be freed with main.allocator.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    pub fn path(self: @This(), withRoot: bool) [:0]const u8 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pub fn path(self: *const @This(), withRoot: bool) [:0]const u8 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var out = std.ArrayList(u8).init(main.allocator);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         self.parent.fmtPath(withRoot, &out);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         out.append('/') catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -278,40 +286,28 @@ pub const Link = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Anything that's not an (indexed) directory or hardlink. Excluded directories are also "Files".
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--pub const File = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pub const File = extern struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     entry: Entry,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    err: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    excluded: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    other_fs: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    kernfs: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    notreg: bool,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    _pad: u3,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    name: u8,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    pub fn resetFlags(f: *@This()) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        f.err = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        f.excluded = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        f.other_fs = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        f.kernfs = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        f.notreg = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pack: Packed = .{},
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    name: [0]u8 = undefined,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    pub const Packed = packed struct(u8) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        err: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        excluded: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        other_fs: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        kernfs: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        notreg: bool = false,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        _pad: u3 = 0, // Make this struct "ABI sized" to allow inclusion in an extern struct
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--pub const Ext = packed struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    mtime: u64 = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    uid: u32 = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    gid: u32 = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    mode: u16 = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+pub const Ext = extern struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    mtime: u64 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    uid: u32 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    gid: u32 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    mode: u16 align(1) = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--comptime {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    std.debug.assert(@bitOffsetOf(Dir, "name") % 8 == 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    std.debug.assert(@bitOffsetOf(Link, "name") % 8 == 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    std.debug.assert(@bitOffsetOf(File, "name") % 8 == 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // List of st_dev entries. Those are typically 64bits, but that's quite a waste
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // of space when a typical scan won't cover many unique devices.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -367,13 +363,13 @@ pub const inodes = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     const HashContext = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         pub fn hash(_: @This(), l: *Link) u64 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             var h = std.hash.Wyhash.init(0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            h.update(std.mem.asBytes(&@as(u32, l.parent.dev)));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            h.update(std.mem.asBytes(&@as(u32, l.parent.pack.dev)));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             h.update(std.mem.asBytes(&l.ino));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             return h.final();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         pub fn eql(_: @This(), a: *Link, b: *Link) bool {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            return a.ino == b.ino and a.parent.dev == b.parent.dev;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            return a.ino == b.ino and a.parent.pack.dev == b.parent.pack.dev;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -399,7 +395,7 @@ pub const inodes = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         defer dirs.deinit();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var it = entry.key_ptr.*;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         while (true) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (it.entry.counted) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (it.entry.pack.counted) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 nlink += 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var parent: ?*Dir = it.parent;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 while (parent) |p| : (parent = p.parent) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -419,19 +415,19 @@ pub const inodes = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var dir_iter = dirs.iterator();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (add) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             while (dir_iter.next()) |de| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                de.key_ptr.*.entry.blocks +|= entry.key_ptr.*.entry.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                de.key_ptr.*.entry.size   +|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                de.key_ptr.*.entry.pack.blocks +|= entry.key_ptr.*.entry.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                de.key_ptr.*.entry.size        +|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (de.value_ptr.* < nlink) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    de.key_ptr.*.shared_blocks +|= entry.key_ptr.*.entry.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    de.key_ptr.*.shared_blocks +|= entry.key_ptr.*.entry.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     de.key_ptr.*.shared_size   +|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             while (dir_iter.next()) |de| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                de.key_ptr.*.entry.blocks -|= entry.key_ptr.*.entry.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                de.key_ptr.*.entry.size   -|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                de.key_ptr.*.entry.pack.blocks -|= entry.key_ptr.*.entry.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                de.key_ptr.*.entry.size        -|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (de.value_ptr.* < nlink) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    de.key_ptr.*.shared_blocks -|= entry.key_ptr.*.entry.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    de.key_ptr.*.shared_blocks -|= entry.key_ptr.*.entry.pack.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     de.key_ptr.*.shared_size   -|= entry.key_ptr.*.entry.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -458,7 +454,7 @@ pub var root: *Dir = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- test "entry" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var e = Entry.create(.file, false, "hello");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    try std.testing.expectEqual(e.etype, .file);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    try std.testing.expect(!e.isext);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    try std.testing.expectEqual(e.pack.etype, .file);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    try std.testing.expect(!e.pack.isext);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     try std.testing.expectEqualStrings(e.name(), "hello");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/scan.zig b/src/scan.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b6a411b..5da6a6e 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/scan.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/scan.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -156,14 +156,14 @@ const ScanDir = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 // in-place conversion to a File entry. That's more efficient,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 // but also more code. I don't expect this to happen often.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var e = entry.key_ptr.*.?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (e.etype == .file) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    if (e.size > 0 or e.blocks > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (e.pack.etype == .file) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    if (e.size > 0 or e.pack.blocks > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                         e.delStats(self.dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                         e.size = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                        e.blocks = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                        e.pack.blocks = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                         e.addStats(self.dir, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                    e.file().?.resetFlags();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    e.file().?.pack = .{};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     _ = self.entries.removeAdapted(@as(?*model.Entry,null), HashContext{ .cmp = name });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     break :blk e;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 } else e.delStatsRec(self.dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -177,9 +177,9 @@ const ScanDir = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var f = e.file().?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         switch (t) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             .err => e.setErr(self.dir),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .other_fs => f.other_fs = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .kernfs => f.kernfs = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            .excluded => f.excluded = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .other_fs => f.pack.other_fs = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .kernfs => f.pack.kernfs = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            .excluded => f.pack.excluded = true,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -192,9 +192,9 @@ const ScanDir = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 // XXX: In-place conversion may also be possible here.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var e = entry.key_ptr.*.?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 // changes of dev/ino affect hard link counting in a way we can't simply merge.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                const samedev = if (e.dir()) |d| d.dev == model.devices.getId(stat.dev) else true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                const samedev = if (e.dir()) |d| d.pack.dev == model.devices.getId(stat.dev) else true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 const sameino = if (e.link()) |l| l.ino == stat.ino else true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                if (e.etype == etype and samedev and sameino) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                if (e.pack.etype == etype and samedev and sameino) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     _ = self.entries.removeAdapted(@as(?*model.Entry,null), HashContext{ .cmp = name });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     break :blk e;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 } else e.delStatsRec(self.dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -209,19 +209,16 @@ const ScanDir = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // entire subtree, which, in turn, would break all shared hardlink
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // sizes. The current approach may result in incorrect sizes after
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // refresh, but I expect the difference to be fairly minor.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (!(e.etype == .dir and e.counted) and (e.blocks != stat.blocks or e.size != stat.size)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (!(e.pack.etype == .dir and e.pack.counted) and (e.pack.blocks != stat.blocks or e.size != stat.size)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             e.delStats(self.dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            e.blocks = stat.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            e.pack.blocks = stat.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             e.size = stat.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (e.dir()) |d| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             d.parent = self.dir;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            d.dev = model.devices.getId(stat.dev);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (e.file()) |f| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            f.resetFlags();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            f.notreg = !stat.dir and !stat.reg;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            d.pack.dev = model.devices.getId(stat.dev);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (e.file()) |f| f.pack = .{ .notreg = !stat.dir and !stat.reg };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (e.link()) |l| l.ino = stat.ino;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (e.ext()) |ext| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             if (ext.mtime > stat.ext.mtime)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -415,11 +412,11 @@ const Context = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             var e = if (p.items.len == 0) blk: {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 // Root entry
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var e = model.Entry.create(.dir, main.config.extended, self.name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                e.blocks = self.stat.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                e.pack.blocks = self.stat.blocks;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 e.size = self.stat.size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (e.ext()) |ext| ext.* = self.stat.ext;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 model.root = e.dir().?;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                model.root.dev = model.devices.getId(self.stat.dev);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                model.root.pack.dev = model.devices.getId(self.stat.dev);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 break :blk e;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 p.items[p.items.len-1].addStat(self.name, &self.stat);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -450,8 +447,8 @@ const Context = struct {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- var active_context: *Context = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Read and index entries of the given dir.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--fn scanDir(ctx: *Context, pat: *const exclude.Patterns, dir: std.fs.Dir, dir_dev: u64) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var it = main.allocator.create(std.fs.Dir.Iterator) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+fn scanDir(ctx: *Context, pat: *const exclude.Patterns, dir: std.fs.IterableDir, dir_dev: u64) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var it = main.allocator.create(std.fs.IterableDir.Iterator) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer main.allocator.destroy(it);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     it.* = dir.iterate();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     while(true) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -471,7 +468,7 @@ fn scanDir(ctx: *Context, pat: *const exclude.Patterns, dir: std.fs.Dir, dir_dev
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        ctx.stat = Stat.read(dir, ctx.name, false) catch {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ctx.stat = Stat.read(dir.dir, ctx.name, false) catch {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ctx.addSpecial(.err);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -481,7 +478,7 @@ fn scanDir(ctx: *Context, pat: *const exclude.Patterns, dir: std.fs.Dir, dir_dev
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.follow_symlinks and ctx.stat.symlink) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (Stat.read(dir, ctx.name, true)) |nstat| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (Stat.read(dir.dir, ctx.name, true)) |nstat| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (!nstat.dir) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     ctx.stat = nstat;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     // Symlink targets may reside on different filesystems,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -497,19 +494,21 @@ fn scanDir(ctx: *Context, pat: *const exclude.Patterns, dir: std.fs.Dir, dir_dev
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         var edir =
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (ctx.stat.dir) dir.openDirZ(ctx.name, .{ .access_sub_paths = true, .iterate = true, .no_follow = true }) catch {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (!ctx.stat.dir) null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            else if (dir.dir.openDirZ(ctx.name, .{ .no_follow = true }, true)) |d| std.fs.IterableDir{.dir = d}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            else |_| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 ctx.addSpecial(.err);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            } else null;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         defer if (edir != null) edir.?.close();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        if (@import("builtin").os.tag == .linux and main.config.exclude_kernfs and ctx.stat.dir and isKernfs(edir.?, ctx.stat.dev)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (@import("builtin").os.tag == .linux and main.config.exclude_kernfs and ctx.stat.dir and isKernfs(edir.?.dir, ctx.stat.dev)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ctx.addSpecial(.kernfs);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             continue;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         if (main.config.exclude_caches and ctx.stat.dir) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--            if (edir.?.openFileZ("CACHEDIR.TAG", .{})) |f| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (edir.?.dir.openFileZ("CACHEDIR.TAG", .{})) |f| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 const sig = "Signature: 8a477f597d28d172789f06886806bc55";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 var buf: [sig.len]u8 = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 if (f.reader().readAll(&buf)) |len| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -550,19 +549,20 @@ pub fn setupRefresh(parent: *model.Dir) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     parent.fmtPath(true, &full_path);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     active_context.pushPath(full_path.items);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     active_context.stat.dir = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    active_context.stat.dev = model.devices.list.items[parent.dev];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    active_context.stat.dev = model.devices.list.items[parent.pack.dev];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // To be called after setupRefresh() (or from scanRoot())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pub fn scan() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer active_context.deinit();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var dir = std.fs.cwd().openDirZ(active_context.pathZ(), .{ .access_sub_paths = true, .iterate = true }) catch |e| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var dir_ = std.fs.cwd().openDirZ(active_context.pathZ(), .{}, true) catch |e| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         active_context.last_error = main.allocator.dupeZ(u8, active_context.path.items) catch unreachable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         active_context.fatal_error = e;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         while (main.state == .refresh or main.state == .scan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             main.handleEvent(true, true);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var dir = std.fs.IterableDir{.dir = dir_};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer dir.close();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     var pat = exclude.getPatterns(active_context.pathZ());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     defer pat.deinit();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1018,7 +1018,7 @@ fn drawBox() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         box.move(2, 30);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         ui.addstr("size: ");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         // TODO: Should display the size of the dir-to-be-refreshed on refreshing, not the root.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--        ui.addsize(.default, util.blocksToSize(model.root.entry.blocks +| model.inodes.total_blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ui.addsize(.default, util.blocksToSize(model.root.entry.pack.blocks +| model.inodes.total_blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     box.move(3, 2);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -1085,7 +1085,7 @@ pub fn draw() void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     .{ ui.shorten(active_context.pathZ(), 63), active_context.items_seen }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 ) catch return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--                const r = ui.FmtSize.fmt(util.blocksToSize(model.root.entry.blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                const r = ui.FmtSize.fmt(util.blocksToSize(model.root.entry.pack.blocks));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 line = std.fmt.bufPrint(&buf, "\x1b7\x1b[J{s: <51} {d:>9} files / {s}{s}\x1b8",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                     .{ ui.shorten(active_context.pathZ(), 51), active_context.items_seen, r.num(), r.unit }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 ) catch return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/src/ui.zig b/src/ui.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e0f66c8..161546d 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/src/ui.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/src/ui.zig
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -286,8 +286,8 @@ const styles = [_]StyleDef{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pub const Style = lbl: {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var fields: [styles.len]std.builtin.TypeInfo.EnumField = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    var decls = [_]std.builtin.TypeInfo.Declaration{};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var fields: [styles.len]std.builtin.Type.EnumField = undefined;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    var decls = [_]std.builtin.Type.Declaration{};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     inline for (styles) |s, i| {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-         fields[i] = .{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             .name = s.name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -395,7 +395,7 @@ pub fn move(y: u32, x: u32) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // (Well, addchstr() does that, but not entirely sure I want to go that way.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Does that even work with UTF-8? Or do I really need to go wchar madness?)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- pub fn addstr(s: [:0]const u8) void {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    _ = c.addstr(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _ = c.addstr(s.ptr);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- // Not to be used for strings that may end up >256 bytes.
</span></pre><pre style='margin:0'>

</pre>