mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-12 17:08:39 -09:00
Only keep total_items + Zig test update + pointless churn
This commit is contained in:
parent
7b3ebf9241
commit
9474aa4329
4 changed files with 84 additions and 80 deletions
|
|
@ -85,8 +85,8 @@ fn sortLt(_: void, ap: ?*model.Entry, bp: ?*model.Entry) bool {
|
|||
if (sortIntLt(a.blocks, b.blocks)) |r| return r;
|
||||
},
|
||||
.items => {
|
||||
const ai = if (a.dir()) |d| d.total_items else 0;
|
||||
const bi = if (b.dir()) |d| d.total_items else 0;
|
||||
const ai = if (a.dir()) |d| d.items else 0;
|
||||
const bi = if (b.dir()) |d| d.items else 0;
|
||||
if (sortIntLt(ai, bi)) |r| return r;
|
||||
if (sortIntLt(a.blocks, b.blocks)) |r| return r;
|
||||
if (sortIntLt(a.size, b.size)) |r| return r;
|
||||
|
|
@ -208,11 +208,15 @@ const Row = struct {
|
|||
}
|
||||
if (main.config.show_graph == .both) ui.addch(' ');
|
||||
if (main.config.show_graph == .both or main.config.show_graph == .graph) {
|
||||
const perblock = std.math.divCeil(u64, if (main.config.show_blocks) dir_max_blocks else dir_max_size, bar_size) catch unreachable;
|
||||
const perblock = std.math.divFloor(u64, if (main.config.show_blocks) dir_max_blocks else dir_max_size, bar_size) catch unreachable;
|
||||
const num = if (main.config.show_blocks) item.blocks else item.size;
|
||||
var i: u32 = 0;
|
||||
var siz: u64 = 0;
|
||||
self.bg.fg(.graph);
|
||||
while (i < bar_size) : (i += 1) ui.addch(if (i*perblock <= num) '#' else ' ');
|
||||
while (i < bar_size) : (i += 1) {
|
||||
siz = saturateAdd(siz, perblock);
|
||||
ui.addch(if (siz <= num) '#' else ' ');
|
||||
}
|
||||
}
|
||||
self.bg.fg(.default);
|
||||
ui.addch(']');
|
||||
|
|
@ -221,14 +225,16 @@ const Row = struct {
|
|||
fn items(self: *Self) void {
|
||||
if (!main.config.show_items) return;
|
||||
defer self.col += 7;
|
||||
const d = if (self.item) |d| d.dir() orelse return else return;
|
||||
const n = d.total_items;
|
||||
const n = (if (self.item) |d| d.dir() orelse return else return).items;
|
||||
ui.move(self.row, self.col);
|
||||
self.bg.fg(.num);
|
||||
if (n < 1000)
|
||||
ui.addprint(" {d:>4}", .{n})
|
||||
else if (n < 100_000)
|
||||
ui.addprint("{d:>6.3}", .{ @intToFloat(f32, n) / 1000 })
|
||||
else if (n < 10_000) {
|
||||
ui.addch(' ');
|
||||
ui.addnum(self.bg, n);
|
||||
} else if (n < 100_000)
|
||||
ui.addnum(self.bg, n)
|
||||
else if (n < 1000_000) {
|
||||
ui.addprint("{d:>5.1}", .{ @intToFloat(f32, n) / 1000 });
|
||||
self.bg.fg(.default);
|
||||
|
|
@ -360,18 +366,20 @@ pub fn draw() !void {
|
|||
ui.move(ui.rows-1, 0);
|
||||
ui.hline(' ', ui.cols);
|
||||
ui.move(ui.rows-1, 1);
|
||||
ui.style(if (main.config.show_blocks) .bold_hd else .hd);
|
||||
ui.addstr("Total disk usage: ");
|
||||
ui.addsize(.hd, blocksToSize(dir_parents.top().entry.blocks));
|
||||
ui.style(if (main.config.show_blocks) .hd else .bold_hd);
|
||||
ui.addstr(" Apparent size: ");
|
||||
ui.addsize(.hd, dir_parents.top().entry.size);
|
||||
ui.addstr(" Items: ");
|
||||
ui.addnum(.hd, dir_parents.top().total_items);
|
||||
ui.addnum(.hd, dir_parents.top().items);
|
||||
|
||||
if (need_confirm_quit) drawQuit();
|
||||
if (sel_row > 0) ui.move(sel_row, 0);
|
||||
}
|
||||
|
||||
fn sortToggle(col: main.SortCol, default_order: main.SortOrder) void {
|
||||
fn sortToggle(col: main.config.SortCol, default_order: main.config.SortOrder) void {
|
||||
if (main.config.sort_col != col) main.config.sort_order = default_order
|
||||
else if (main.config.sort_order == .asc) main.config.sort_order = .desc
|
||||
else main.config.sort_order = .asc;
|
||||
|
|
|
|||
92
src/main.zig
92
src/main.zig
|
|
@ -9,40 +9,38 @@ const c = @cImport(@cInclude("locale.h"));
|
|||
|
||||
pub const allocator = std.heap.c_allocator;
|
||||
|
||||
pub const config = struct {
|
||||
pub const SortCol = enum { name, blocks, size, items, mtime };
|
||||
pub const SortOrder = enum { asc, desc };
|
||||
|
||||
pub const Config = struct {
|
||||
same_fs: bool = true,
|
||||
extended: bool = false,
|
||||
follow_symlinks: bool = false,
|
||||
exclude_caches: bool = false,
|
||||
exclude_kernfs: bool = false,
|
||||
exclude_patterns: std.ArrayList([:0]const u8) = std.ArrayList([:0]const u8).init(allocator),
|
||||
pub var same_fs: bool = true;
|
||||
pub var extended: bool = false;
|
||||
pub var follow_symlinks: bool = false;
|
||||
pub var exclude_caches: bool = false;
|
||||
pub var exclude_kernfs: bool = false;
|
||||
pub var exclude_patterns: std.ArrayList([:0]const u8) = std.ArrayList([:0]const u8).init(allocator);
|
||||
|
||||
update_delay: u64 = 100*std.time.ns_per_ms,
|
||||
scan_ui: enum { none, line, full } = .full,
|
||||
si: bool = false,
|
||||
nc_tty: bool = false,
|
||||
ui_color: enum { off, dark } = .off,
|
||||
thousands_sep: []const u8 = ".",
|
||||
pub var update_delay: u64 = 100*std.time.ns_per_ms;
|
||||
pub var scan_ui: enum { none, line, full } = .full;
|
||||
pub var si: bool = false;
|
||||
pub var nc_tty: bool = false;
|
||||
pub var ui_color: enum { off, dark } = .off;
|
||||
pub var thousands_sep: []const u8 = ",";
|
||||
|
||||
show_hidden: bool = true,
|
||||
show_blocks: bool = true,
|
||||
show_items: bool = false,
|
||||
show_mtime: bool = false,
|
||||
show_graph: enum { off, graph, percent, both } = .graph,
|
||||
sort_col: SortCol = .blocks,
|
||||
sort_order: SortOrder = .desc,
|
||||
sort_dirsfirst: bool = false,
|
||||
pub var show_hidden: bool = true;
|
||||
pub var show_blocks: bool = true;
|
||||
pub var show_items: bool = false;
|
||||
pub var show_mtime: bool = false;
|
||||
pub var show_graph: enum { off, graph, percent, both } = .graph;
|
||||
pub var sort_col: SortCol = .blocks;
|
||||
pub var sort_order: SortOrder = .desc;
|
||||
pub var sort_dirsfirst: bool = false;
|
||||
|
||||
read_only: bool = false,
|
||||
can_shell: bool = true,
|
||||
confirm_quit: bool = false,
|
||||
pub var read_only: bool = false;
|
||||
pub var can_shell: bool = true;
|
||||
pub var confirm_quit: bool = false;
|
||||
};
|
||||
|
||||
pub var config = Config{};
|
||||
|
||||
pub var state: enum { scan, browse } = .browse;
|
||||
|
||||
// Simple generic argument parser, supports getopt_long() style arguments.
|
||||
|
|
@ -298,30 +296,30 @@ test "argument parser" {
|
|||
const l = L{ .lst = &lst };
|
||||
const T = struct {
|
||||
a: Args(L),
|
||||
fn opt(self: *@This(), isopt: bool, val: []const u8) void {
|
||||
fn opt(self: *@This(), isopt: bool, val: []const u8) !void {
|
||||
const o = self.a.next().?;
|
||||
std.testing.expectEqual(isopt, o.opt);
|
||||
std.testing.expectEqualStrings(val, o.val);
|
||||
std.testing.expectEqual(o.is(val), isopt);
|
||||
try std.testing.expectEqual(isopt, o.opt);
|
||||
try std.testing.expectEqualStrings(val, o.val);
|
||||
try std.testing.expectEqual(o.is(val), isopt);
|
||||
}
|
||||
fn arg(self: *@This(), val: []const u8) void {
|
||||
std.testing.expectEqualStrings(val, self.a.arg());
|
||||
fn arg(self: *@This(), val: []const u8) !void {
|
||||
try std.testing.expectEqualStrings(val, self.a.arg());
|
||||
}
|
||||
};
|
||||
var t = T{ .a = Args(L).init(l) };
|
||||
t.opt(false, "a");
|
||||
t.opt(true, "-a");
|
||||
t.opt(true, "-b");
|
||||
t.arg("cd=e");
|
||||
t.opt(true, "--opt1");
|
||||
t.arg("arg1");
|
||||
t.opt(true, "--opt2");
|
||||
t.arg("arg2");
|
||||
t.opt(true, "-x");
|
||||
t.arg("foo");
|
||||
t.opt(false, "");
|
||||
t.opt(false, "--arg");
|
||||
t.opt(false, "");
|
||||
t.opt(false, "-");
|
||||
std.testing.expectEqual(t.a.next(), null);
|
||||
try t.opt(false, "a");
|
||||
try t.opt(true, "-a");
|
||||
try t.opt(true, "-b");
|
||||
try t.arg("cd=e");
|
||||
try t.opt(true, "--opt1");
|
||||
try t.arg("arg1");
|
||||
try t.opt(true, "--opt2");
|
||||
try t.arg("arg2");
|
||||
try t.opt(true, "-x");
|
||||
try t.arg("foo");
|
||||
try t.opt(false, "");
|
||||
try t.opt(false, "--arg");
|
||||
try t.opt(false, "");
|
||||
try t.opt(false, "-");
|
||||
try std.testing.expectEqual(t.a.next(), null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ pub const Entry = packed struct {
|
|||
if (self.ext()) |e|
|
||||
if (p.entry.ext()) |pe|
|
||||
if (e.mtime > pe.mtime) { pe.mtime = e.mtime; };
|
||||
p.items = saturateAdd(p.items, 1);
|
||||
|
||||
// Hardlink in a subdirectory with a different device, only count it the first time.
|
||||
if (self.link() != null and dev != p.dev) {
|
||||
|
|
@ -128,12 +129,10 @@ pub const Entry = packed struct {
|
|||
add_total = true;
|
||||
p.shared_size = saturateAdd(p.shared_size, self.size);
|
||||
p.shared_blocks = saturateAdd(p.shared_blocks, self.blocks);
|
||||
p.shared_items = saturateAdd(p.shared_items, 1);
|
||||
// Encountered this file in this dir the same number of times as its link count, meaning it's not shared with other dirs.
|
||||
} else if(d.entry.key.num_files == l.nlink) {
|
||||
p.shared_size = saturateSub(p.shared_size, self.size);
|
||||
p.shared_blocks = saturateSub(p.shared_blocks, self.blocks);
|
||||
p.shared_items = saturateSub(p.shared_items, 1);
|
||||
}
|
||||
} else {
|
||||
add_total = true;
|
||||
|
|
@ -141,7 +140,6 @@ pub const Entry = packed struct {
|
|||
if(add_total) {
|
||||
p.entry.size = saturateAdd(p.entry.size, self.size);
|
||||
p.entry.blocks = saturateAdd(p.entry.blocks, self.blocks);
|
||||
p.total_items = saturateAdd(p.total_items, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -161,10 +159,7 @@ pub const Dir = packed struct {
|
|||
// (space reclaimed by deleting a dir =~ entry. - shared_)
|
||||
shared_blocks: u64,
|
||||
shared_size: u64,
|
||||
shared_items: u32,
|
||||
total_items: u32,
|
||||
// TODO: ncdu1 only keeps track of a total item count including duplicate hardlinks.
|
||||
// That number seems useful, too. Include it somehow?
|
||||
items: u32,
|
||||
|
||||
// Indexes into the global 'devices' array
|
||||
dev: DevId,
|
||||
|
|
|
|||
31
src/ui.zig
31
src/ui.zig
|
|
@ -118,25 +118,25 @@ pub fn shorten(in: [:0]const u8, max_width: u32) ![:0] const u8 {
|
|||
return try arrayListBufZ(&shorten_buf);
|
||||
}
|
||||
|
||||
fn shortenTest(in: [:0]const u8, max_width: u32, out: [:0]const u8) void {
|
||||
std.testing.expectEqualStrings(out, shorten(in, max_width) catch unreachable);
|
||||
fn shortenTest(in: [:0]const u8, max_width: u32, out: [:0]const u8) !void {
|
||||
try std.testing.expectEqualStrings(out, try shorten(in, max_width));
|
||||
}
|
||||
|
||||
test "shorten" {
|
||||
_ = c.setlocale(c.LC_ALL, ""); // libc wcwidth() may not recognize Unicode without this
|
||||
const t = shortenTest;
|
||||
t("abcde", 3, "...");
|
||||
t("abcde", 5, "abcde");
|
||||
t("abcde", 4, "...e");
|
||||
t("abcdefgh", 6, "a...gh");
|
||||
t("abcdefgh", 7, "ab...gh");
|
||||
t("ABCDEFGH", 16, "ABCDEFGH");
|
||||
t("ABCDEFGH", 7, "A...H");
|
||||
t("ABCDEFGH", 8, "A...H");
|
||||
t("ABCDEFGH", 9, "A...GH");
|
||||
t("AaBCDEFGH", 8, "A...H"); // could optimize this, but w/e
|
||||
t("ABCDEFGaH", 8, "A...aH");
|
||||
t("ABCDEFGH", 15, "ABC...FGH");
|
||||
try t("abcde", 3, "...");
|
||||
try t("abcde", 5, "abcde");
|
||||
try t("abcde", 4, "...e");
|
||||
try t("abcdefgh", 6, "a...gh");
|
||||
try t("abcdefgh", 7, "ab...gh");
|
||||
try t("ABCDEFGH", 16, "ABCDEFGH");
|
||||
try t("ABCDEFGH", 7, "A...H");
|
||||
try t("ABCDEFGH", 8, "A...H");
|
||||
try t("ABCDEFGH", 9, "A...GH");
|
||||
try t("AaBCDEFGH", 8, "A...H"); // could optimize this, but w/e
|
||||
try t("ABCDEFGaH", 8, "A...aH");
|
||||
try t("ABCDEFGH", 15, "ABC...FGH");
|
||||
}
|
||||
|
||||
// ncurses_refs.c
|
||||
|
|
@ -167,6 +167,9 @@ const styles = [_]StyleDef{
|
|||
.{ .name = "bold",
|
||||
.off = .{ .fg = -1, .bg = -1, .attr = c.A_BOLD },
|
||||
.dark = .{ .fg = -1, .bg = -1, .attr = c.A_BOLD } },
|
||||
.{ .name = "bold_hd",
|
||||
.off = .{ .fg = -1, .bg = -1, .attr = c.A_BOLD|c.A_REVERSE },
|
||||
.dark = .{ .fg = c.COLOR_BLACK, .bg = c.COLOR_CYAN, .attr = c.A_BOLD } },
|
||||
.{ .name = "box_title",
|
||||
.off = .{ .fg = -1, .bg = -1, .attr = c.A_BOLD },
|
||||
.dark = .{ .fg = c.COLOR_BLUE, .bg = -1, .attr = c.A_BOLD } },
|
||||
|
|
|
|||
Loading…
Reference in a new issue