mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-13 01:08:41 -09:00
Implement help window
The rewrite is now on feature-parity with ncdu 1.x. What remains is bugfixing and polishing.
This commit is contained in:
parent
c8636b8982
commit
6f07a36923
2 changed files with 155 additions and 10 deletions
10
README.md
10
README.md
|
|
@ -29,16 +29,8 @@ This rewrite is a test-bed for various improvements to the design of ncdu that
|
||||||
would impact large parts of its codebase. The improvements may also be
|
would impact large parts of its codebase. The improvements may also be
|
||||||
backported to the C version, depending on how viable a proper Zig release is.
|
backported to the C version, depending on how viable a proper Zig release is.
|
||||||
|
|
||||||
### Implementation status
|
|
||||||
|
|
||||||
Missing features:
|
|
||||||
|
|
||||||
- Help window
|
|
||||||
|
|
||||||
### Improvements compared to the C version
|
### Improvements compared to the C version
|
||||||
|
|
||||||
Already implemented:
|
|
||||||
|
|
||||||
- Significantly reduced memory usage, achieved by:
|
- Significantly reduced memory usage, achieved by:
|
||||||
- Removing pointers between nodes that are not strictly necessary for basic
|
- Removing pointers between nodes that are not strictly necessary for basic
|
||||||
tree traversal (this impacts *all* code in the C version of ncdu).
|
tree traversal (this impacts *all* code in the C version of ncdu).
|
||||||
|
|
@ -88,7 +80,7 @@ separately:
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Latest Zig compiler
|
- Zig 8.0
|
||||||
- Some sort of POSIX-like OS
|
- Some sort of POSIX-like OS
|
||||||
- ncurses libraries and header files
|
- ncurses libraries and header files
|
||||||
|
|
||||||
|
|
|
||||||
155
src/browser.zig
155
src/browser.zig
|
|
@ -308,7 +308,7 @@ const Row = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var state: enum { main, quit, info } = .main;
|
var state: enum { main, quit, help, info } = .main;
|
||||||
var message: ?[:0]const u8 = null;
|
var message: ?[:0]const u8 = null;
|
||||||
|
|
||||||
const quit = struct {
|
const quit = struct {
|
||||||
|
|
@ -554,6 +554,156 @@ const info = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const help = struct {
|
||||||
|
// TODO: Document 'u' key... once I have something final for it.
|
||||||
|
const keys = [_][:0]const u8{
|
||||||
|
"up, k", "Move cursor up",
|
||||||
|
"down, j", "Move cursor down",
|
||||||
|
"right/enter", "Open selected directory",
|
||||||
|
"left, <, h", "Open parent directory",
|
||||||
|
"n", "Sort by name (ascending/descending)",
|
||||||
|
"s", "Sort by size (ascending/descending)",
|
||||||
|
"C", "Sort by items (ascending/descending)",
|
||||||
|
"M", "Sort by mtime (-e flag)",
|
||||||
|
"d", "Delete selected file or directory",
|
||||||
|
"t", "Toggle dirs before files when sorting",
|
||||||
|
"g", "Show percentage and/or graph",
|
||||||
|
"a", "Toggle between apparent size and disk usage",
|
||||||
|
"c", "Toggle display of child item counts",
|
||||||
|
"m", "Toggle display of latest mtime (-e flag)",
|
||||||
|
"e", "Show/hide hidden or excluded files",
|
||||||
|
"i", "Show information about selected item",
|
||||||
|
"r", "Recalculate the current directory",
|
||||||
|
"b", "Spawn shell in current directory",
|
||||||
|
"q", "Quit ncdu"
|
||||||
|
};
|
||||||
|
const keylines = 10;
|
||||||
|
|
||||||
|
const flags = [_][:0]const u8{
|
||||||
|
"!", "An error occurred while reading this directory",
|
||||||
|
".", "An error occurred while reading a subdirectory",
|
||||||
|
"<", "File or directory is excluded from the statistics",
|
||||||
|
"e", "Empty directory",
|
||||||
|
">", "Directory was on another filesystem",
|
||||||
|
"@", "This is not a file nor a dir (symlink, socket, ...)",
|
||||||
|
"^", "Excluded Linux pseudo-filesystem",
|
||||||
|
"H", "Same file was already counted (hard link)",
|
||||||
|
};
|
||||||
|
|
||||||
|
// It's kinda ugly, but for nostalgia's sake...
|
||||||
|
const logo = [_]u29{
|
||||||
|
0b11111100111110000001100110011,
|
||||||
|
0b11001100110000000001100110011,
|
||||||
|
0b11001100110000011111100110011,
|
||||||
|
0b11001100110000011001100110011,
|
||||||
|
0b11001100111110011111100111111,
|
||||||
|
};
|
||||||
|
|
||||||
|
var tab: enum { keys, flags, about } = .keys;
|
||||||
|
var offset: u32 = 0;
|
||||||
|
|
||||||
|
fn drawKeys(box: ui.Box) void {
|
||||||
|
var line: u32 = 1;
|
||||||
|
var i = offset*2;
|
||||||
|
while (i < (offset + keylines)*2) : (i += 2) {
|
||||||
|
line += 1;
|
||||||
|
box.move(line, 13 - @intCast(u32, keys[i].len));
|
||||||
|
ui.style(.key);
|
||||||
|
ui.addstr(keys[i]);
|
||||||
|
ui.style(.default);
|
||||||
|
ui.addch(' ');
|
||||||
|
ui.addstr(keys[i+1]);
|
||||||
|
}
|
||||||
|
if (offset < keys.len/2-keylines) {
|
||||||
|
box.move(12, 25);
|
||||||
|
ui.addstr("-- more --");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drawFlags(box: ui.Box) void {
|
||||||
|
box.move(2, 3);
|
||||||
|
ui.style(.bold);
|
||||||
|
ui.addstr("X [size] [graph] [file or directory]");
|
||||||
|
box.move(3, 4);
|
||||||
|
ui.style(.default);
|
||||||
|
ui.addstr("The X is only present in the following cases:");
|
||||||
|
var i: u32 = 0;
|
||||||
|
while (i < flags.len) : (i += 2) {
|
||||||
|
box.move(i/2+5, 4);
|
||||||
|
ui.style(.flag);
|
||||||
|
ui.addstr(flags[i]);
|
||||||
|
ui.style(.default);
|
||||||
|
ui.addch(' ');
|
||||||
|
ui.addstr(flags[i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drawAbout(box: ui.Box) void {
|
||||||
|
for (logo) |s, n| {
|
||||||
|
box.move(@intCast(u32, n)+3, 12);
|
||||||
|
var i: u5 = 28;
|
||||||
|
while (true) {
|
||||||
|
ui.style(if (s & (@as(u29,1)<<i) > 0) .sel else .default);
|
||||||
|
ui.addch(' ');
|
||||||
|
if (i == 0)
|
||||||
|
break;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.style(.default);
|
||||||
|
box.move(3, 43); ui.addstr("NCurses");
|
||||||
|
box.move(4, 43); ui.addstr("Disk");
|
||||||
|
box.move(5, 43); ui.addstr("Usage");
|
||||||
|
ui.style(.num);
|
||||||
|
box.move(7, 43); ui.addstr(main.program_version);
|
||||||
|
ui.style(.default);
|
||||||
|
box.move(9, 9); ui.addstr("Written by Yoran Heling <projects@yorhel.nl>");
|
||||||
|
box.move(10,16); ui.addstr("https://dev.yorhel.nl/ncdu");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw() void {
|
||||||
|
const box = ui.Box.create(15, 60, "ncdu help");
|
||||||
|
box.tab(30, tab == .keys, 1, "Keys");
|
||||||
|
box.tab(39, tab == .flags, 2, "Format");
|
||||||
|
box.tab(50, tab == .about, 3, "About");
|
||||||
|
|
||||||
|
box.move(13, 42);
|
||||||
|
ui.addstr("Press ");
|
||||||
|
ui.style(.key);
|
||||||
|
ui.addch('q');
|
||||||
|
ui.style(.default);
|
||||||
|
ui.addstr(" to close");
|
||||||
|
|
||||||
|
switch (tab) {
|
||||||
|
.keys => drawKeys(box),
|
||||||
|
.flags => drawFlags(box),
|
||||||
|
.about => drawAbout(box),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn keyInput(ch: i32) void {
|
||||||
|
const ctab = tab;
|
||||||
|
defer if (ctab != tab or state != .help) { offset = 0; };
|
||||||
|
switch (ch) {
|
||||||
|
'1' => tab = .keys,
|
||||||
|
'2' => tab = .flags,
|
||||||
|
'3' => tab = .about,
|
||||||
|
'h', ui.c.KEY_LEFT => tab = if (tab == .about) .flags else .keys,
|
||||||
|
'l', ui.c.KEY_RIGHT => tab = if (tab == .keys) .flags else .about,
|
||||||
|
'j', ' ', ui.c.KEY_DOWN, ui.c.KEY_NPAGE => {
|
||||||
|
const max = switch (tab) {
|
||||||
|
.keys => keys.len/2 - keylines,
|
||||||
|
else => @as(u32, 0),
|
||||||
|
};
|
||||||
|
if (offset < max)
|
||||||
|
offset += 1;
|
||||||
|
},
|
||||||
|
'k', ui.c.KEY_UP, ui.c.KEY_PPAGE => { if (offset > 0) offset -= 1; },
|
||||||
|
else => state = .main,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn draw() void {
|
pub fn draw() void {
|
||||||
ui.style(.hd);
|
ui.style(.hd);
|
||||||
ui.move(0,0);
|
ui.move(0,0);
|
||||||
|
|
@ -620,6 +770,7 @@ pub fn draw() void {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.main => {},
|
.main => {},
|
||||||
.quit => quit.draw(),
|
.quit => quit.draw(),
|
||||||
|
.help => help.draw(),
|
||||||
.info => info.draw(),
|
.info => info.draw(),
|
||||||
}
|
}
|
||||||
if (message) |m| {
|
if (message) |m| {
|
||||||
|
|
@ -668,11 +819,13 @@ pub fn keyInput(ch: i32) void {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.main => {}, // fallthrough
|
.main => {}, // fallthrough
|
||||||
.quit => return quit.keyInput(ch),
|
.quit => return quit.keyInput(ch),
|
||||||
|
.help => return help.keyInput(ch),
|
||||||
.info => if (info.keyInput(ch)) return,
|
.info => if (info.keyInput(ch)) return,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
'q' => if (main.config.confirm_quit) { state = .quit; } else ui.quit(),
|
'q' => if (main.config.confirm_quit) { state = .quit; } else ui.quit(),
|
||||||
|
'?' => state = .help,
|
||||||
'i' => if (dir_items.items.len > 0) info.set(dir_items.items[cursor_idx], .info),
|
'i' => if (dir_items.items.len > 0) info.set(dir_items.items[cursor_idx], .info),
|
||||||
'r' => {
|
'r' => {
|
||||||
if (main.config.imported)
|
if (main.config.imported)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue