Add CLI options for individual -r features and to counter previous options

The --enable-* options also work for imported files, this fixes #120.

Most other options are not super useful on its own, but these will be
useful when there's a config file.
This commit is contained in:
Yorhel 2021-10-05 16:24:52 +02:00
parent bfead635e4
commit b3c6f0f48a
3 changed files with 90 additions and 62 deletions

100
ncdu.pod
View file

@ -57,12 +57,12 @@ directory with many files. 10.000 files will get you an export in the order of
gzip. This scales linearly, so be prepared to handle a few tens of megabytes
when dealing with millions of files.
=item -e
=item -e, --extended, --no-extended
Enable extended information mode. This will, in addition to the usual file
information, also read the ownership, permissions and last modification time
for each file. This will result in higher memory usage (by roughly ~30%) and in
a larger output file when exporting.
Enable/disable extended information mode. This will, in addition to the usual
file information, also read the ownership, permissions and last modification
time for each file. This will result in higher memory usage (by roughly ~30%)
and in a larger output file when exporting.
When using the file export/import function, this flag will need to be added
both when exporting (to make sure the information is added to the export), and
@ -102,40 +102,48 @@ Provide a full-screen ncurses interface while scanning a directory or importing
a file. This is the only interface that provides feedback on any non-fatal
errors while scanning.
=item -q
=item -q, --slow-ui-updates, --fast-ui-updates
Quiet mode. While scanning or importing the directory, ncdu will update the
screen 10 times a second by default, this will be decreased to once every 2
seconds in quiet mode. Use this feature to save bandwidth over remote
connections. This option has no effect when C<-0> is used.
Change the UI update interval while scanning or importing. Ncdu will update the
screen 10 times a second by default (C<--fast-ui-updates>), this can be
decreased to once every 2 seconds with C<-q> or C<--slow-ui-updates>. This
feature can be used to save bandwidth over remote connections. This option has
no effect when C<-0> is used.
=item --enable-shell, --disable-shell
Enable or disable shell spawning from the browser. This feature is enabled by
default when scanning a live directory and disabled when importing from file.
=item --enable-delete, --disable-delete
Enable or disable the built-in file deletion feature. This feature is enabled
by default when scanning a live directory and disabled when importing from
file. Explicitly disabling the deletion feature can work as a safeguard to
prevent accidental data loss.
=item --enable-refresh, --disable-refresh
Enable or disable directory refreshing from the browser. This feature is
enabled by default when scanning a live directory and disabled when importing
from file.
=item -r
Read-only mode. This will disable the built-in file deletion feature. This
option has no effect when C<-o> is used, because there will not be a browser
interface in that case. It has no effect when C<-f> is used, either, because
the deletion feature is disabled in that case anyway.
Read-only mode. When given once, this is an alias for C<--disable-delete>, when
given twice it will also add C<--disable-shell>, thus ensuring that there is no
way to modify the file system from within ncdu.
WARNING: This option will only prevent deletion through the file browser. It is
still possible to spawn a shell from ncdu and delete or modify files from
there. To disable that feature as well, pass the C<-r> option twice (see
C<-rr>).
=item -rr
In addition to C<-r>, this will also disable the shell spawning feature of the
file browser.
=item --si
=item --si, --no-si
List sizes using base 10 prefixes, that is, powers of 1000 (KB, MB, etc), as
defined in the International System of Units (SI), instead of the usual base 2
prefixes, that is, powers of 1024 (KiB, MiB, etc).
=item --confirm-quit
=item --confirm-quit, --no-confirm-quit
Requires a confirmation before quitting ncdu. Very helpful when you
accidentally press 'q' during or after a very long scan.
Require a confirmation before quitting ncdu. Very helpful when you accidentally
press 'q' during or after a very long scan.
=item --color I<SCHEME>
@ -155,11 +163,16 @@ directory information from a file.
=over
=item -x
=item -x, --one-file-system
Do not cross filesystem boundaries, i.e. only count files and directories on
the same filesystem as the directory being scanned.
=item --cross-file-system
Do cross filesystem boundaries. This is the default, but can be specified to
overrule a previously given C<-x>.
=item --exclude I<PATTERN>
Exclude files that match I<PATTERN>. The files will still be displayed by
@ -171,27 +184,24 @@ can be added multiple times to add more patterns.
Exclude files that match any pattern in I<FILE>. Patterns should be separated
by a newline.
=item --exclude-caches
=item --include-caches, --exclude-caches
Exclude directories containing CACHEDIR.TAG. The directories will still be
displayed, but not their content, and they are not counted towards the disk
usage statistics.
See http://www.brynosaurus.com/cachedir/
Include (default) or exclude directories containing CACHEDIR.TAG. The
directories will still be displayed, but their contents will not be scanned or
counted towards the disk usage statistics.
L<http://www.brynosaurus.com/cachedir/>
=item -L, --follow-symlinks
=item -L, --follow-symlinks, --no-follow-symlinks
Follow symlinks and count the size of the file they point to. As of ncdu 1.14,
this option will not follow symlinks to directories and will count each
symlinked file as a unique file (i.e. unlike how hard links are handled). This
is subject to change in later versions.
Follow (or not) symlinks and count the size of the file they point to. As of
ncdu 1.14, this option will not follow symlinks to directories and will count
each symlinked file as a unique file (i.e. unlike how hard links are handled).
This is subject to change in later versions.
=item --exclude-firmlinks
=item --include-kernfs, --exclude-kernfs
(MacOS only) Exclude firmlinks.
=item --exclude-kernfs
(Linux only) Exclude Linux pseudo filesystems, e.g. /proc (procfs), /sys (sysfs).
(Linux only) Include (default) or exclude Linux pseudo filesystems, e.g. /proc
(procfs), /sys (sysfs).
The complete list of currently known pseudo filesystems is: binfmt, bpf, cgroup,
cgroup2, debug, devpts, proc, pstore, security, selinux, sys, trace.

View file

@ -729,7 +729,7 @@ pub fn draw() void {
if (main.config.imported) {
ui.move(0, saturateSub(ui.cols, 10));
ui.addstr("[imported]");
} else if (main.config.read_only) {
} else if (!main.config.can_delete) {
ui.move(0, saturateSub(ui.cols, 10));
ui.addstr("[readonly]");
}
@ -840,27 +840,23 @@ pub fn keyInput(ch: i32) void {
'?' => state = .help,
'i' => if (dir_items.items.len > 0) info.set(dir_items.items[cursor_idx], .info),
'r' => {
if (main.config.imported)
message = "Directory imported from file, refreshing is disabled."
if (!main.config.can_refresh)
message = "Directory refresh feature disabled."
else {
main.state = .refresh;
scan.setupRefresh(dir_parent);
}
},
'b' => {
if (main.config.imported)
message = "Shell feature not available for imported directories."
else if (!main.config.can_shell)
message = "Shell feature disabled in read-only mode."
if (!main.config.can_shell)
message = "Shell feature disabled."
else
main.state = .shell;
},
'd' => {
if (dir_items.items.len == 0) {
} else if (main.config.imported)
message = "Deletion feature not available for imported directories."
else if (main.config.read_only)
message = "Deletion feature disabled in read-only mode."
} else if (!main.config.can_delete)
message = "Deletion feature disabled."
else if (dir_items.items[cursor_idx]) |e| {
main.state = .delete;
const next =

View file

@ -65,9 +65,10 @@ pub const config = struct {
pub var sort_order: SortOrder = .desc;
pub var sort_dirsfirst: bool = false;
pub var read_only: bool = false;
pub var imported: bool = false;
pub var can_delete: bool = true;
pub var can_shell: bool = true;
pub var can_refresh: bool = true;
pub var confirm_quit: bool = false;
pub var confirm_delete: bool = true;
pub var ignore_delete_errors: bool = false;
@ -266,6 +267,9 @@ pub fn main() void {
var import_file: ?[:0]const u8 = null;
var export_file: ?[:0]const u8 = null;
var has_scan_ui = false;
var has_can_delete = false;
var has_can_shell = false;
var has_can_refresh = false;
_ = args.next(); // program name
while (args.next()) |opt| {
if (!opt.opt) {
@ -276,11 +280,20 @@ pub fn main() void {
}
if (opt.is("-h") or opt.is("-?") or opt.is("--help")) help()
else if(opt.is("-v") or opt.is("-V") or opt.is("--version")) version()
else if(opt.is("-q")) config.update_delay = 2*std.time.ns_per_s
else if(opt.is("-x")) config.same_fs = true
else if(opt.is("-e")) config.extended = true
else if(opt.is("-r") and config.read_only) config.can_shell = false
else if(opt.is("-r")) config.read_only = true
else if(opt.is("-q") or opt.is("--slow-ui-updates")) config.update_delay = 2*std.time.ns_per_s
else if(opt.is("--fast-ui-updates")) config.update_delay = 100*std.time.ns_per_ms
else if(opt.is("-x") or opt.is("--one-file-system")) config.same_fs = true
else if(opt.is("--cross-file-system")) config.same_fs = false
else if(opt.is("-e") or opt.is("--extended")) config.extended = true
else if(opt.is("--no-extended")) config.extended = false
else if(opt.is("-r") and !config.can_delete) config.can_shell = false
else if(opt.is("-r")) config.can_delete = false
else if(opt.is("--enable-shell")) { has_can_shell = true; config.can_shell = true; }
else if(opt.is("--disable-shell")) { has_can_shell = true; config.can_shell = false; }
else if(opt.is("--enable-delete")) { has_can_delete = true; config.can_delete = true; }
else if(opt.is("--disable-delete")) { has_can_delete = true; config.can_delete = false; }
else if(opt.is("--enable-refresh")) { has_can_refresh = true; config.can_refresh = true; }
else if(opt.is("--disable-refresh")) { has_can_refresh = true; config.can_refresh = false; }
else if(opt.is("-0")) { has_scan_ui = true; config.scan_ui = .none; }
else if(opt.is("-1")) { has_scan_ui = true; config.scan_ui = .line; }
else if(opt.is("-2")) { has_scan_ui = true; config.scan_ui = .full; }
@ -289,14 +302,19 @@ pub fn main() void {
else if(opt.is("-f") and import_file != null) ui.die("The -f flag can only be given once.\n", .{})
else if(opt.is("-f")) import_file = args.arg()
else if(opt.is("--si")) config.si = true
else if(opt.is("--no-si")) config.si = false
else if(opt.is("-L") or opt.is("--follow-symlinks")) config.follow_symlinks = true
else if(opt.is("--no-follow-symlinks")) config.follow_symlinks = false
else if(opt.is("--exclude")) config.exclude_patterns.append(args.arg()) catch unreachable
else if(opt.is("-X") or opt.is("--exclude-from")) {
const arg = args.arg();
readExcludeFile(arg) catch |e| ui.die("Error reading excludes from {s}: {s}.\n", .{ arg, ui.errorString(e) });
} else if(opt.is("--exclude-caches")) config.exclude_caches = true
else if(opt.is("--include-caches")) config.exclude_caches = false
else if(opt.is("--exclude-kernfs")) config.exclude_kernfs = true
else if(opt.is("--include-kernfs")) config.exclude_kernfs = false
else if(opt.is("--confirm-quit")) config.confirm_quit = true
else if(opt.is("--no-confirm-quit")) config.confirm_quit = false
else if(opt.is("--color")) {
const val = args.arg();
if (std.mem.eql(u8, val, "off")) config.ui_color = .off
@ -337,6 +355,10 @@ pub fn main() void {
catch |e| ui.die("Error opening directory: {s}.\n", .{ui.errorString(e)});
if (out_file != null) return;
if (config.imported and !has_can_shell) config.can_shell = false;
if (config.imported and !has_can_delete) config.can_delete = false;
if (config.imported and !has_can_refresh) config.can_refresh = false;
config.scan_ui = .full; // in case we're refreshing from the UI, always in full mode.
ui.init();
state = .browse;