summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Wilson <alex.david.wilson@gmail.com>2019-01-20 13:03:38 -0700
committerYorhel <git@yorhel.nl>2019-01-21 07:33:24 +0100
commit60fdac0680750e660d2af0b06dde02d5da0ca57c (patch)
treeee52d30c59bc69d119447b4214a98b320cdd452c
parent2501fb1ad574dda6d2f38c34b71033189a97340e (diff)
add a max modified time, or mtime, view and sorting
This adds an 'm' command to show the latest modified time of all files in a directory. The 'M' command allows for ascending and descending mtime sorting. These are only enabled with the -e flag and overload the dir_ext mtime field.
-rw-r--r--doc/ncdu.pod12
-rw-r--r--src/browser.c41
-rw-r--r--src/dir_mem.c9
-rw-r--r--src/dirlist.c11
-rw-r--r--src/dirlist.h1
-rw-r--r--src/help.c4
-rw-r--r--src/util.c14
-rw-r--r--src/util.h2
8 files changed, 84 insertions, 10 deletions
diff --git a/doc/ncdu.pod b/doc/ncdu.pod
index 2946c3d..99a7577 100644
--- a/doc/ncdu.pod
+++ b/doc/ncdu.pod
@@ -67,6 +67,9 @@ when importing (to read this extra information in memory). This flag has no
effect when importing a file that has been exported without the extended
information.
+This enables viewing and sorting by the latest child mtime, or modified time,
+using 'm' and 'M', respectively.
+
=back
=head2 Interface options
@@ -208,6 +211,11 @@ Order by number of items (press again for descending order)
Toggle between showing disk usage and showing apparent size.
+=item M
+
+Order by latest child mtime, or modified time. (press again for descending order)
+Requires the -e flag.
+
=item d
Delete the selected file or directory. An error message will be shown when the
@@ -228,6 +236,10 @@ the current directory.
Toggle display of child item counts.
+=item m
+
+Toggle display of latest child mtime, or modified time. Requies the -e flag.
+
=item e
Show/hide 'hidden' or 'excluded' files and directories. Please note that even
diff --git a/src/browser.c b/src/browser.c
index 97132ba..7cd0ac5 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -31,7 +31,7 @@
#include <time.h>
-static int graph = 1, show_as = 0, info_show = 0, info_page = 0, info_start = 0, show_items = 0;
+static int graph = 1, show_as = 0, info_show = 0, info_page = 0, info_start = 0, show_items = 0, show_mtime = 0;
static char *message = NULL;
@@ -196,6 +196,30 @@ static void browse_draw_items(struct dir *n, int *x) {
}
+static void browse_draw_mtime(struct dir *n, int *x) {
+ enum ui_coltype c = n->flags & FF_BSEL ? UIC_SEL : UIC_DEFAULT;
+ char mbuf[26];
+ struct dir_ext *e;
+ time_t t;
+
+ if (n->flags & FF_EXT) {
+ e = dir_ext_ptr(n);
+ } else if (!strcmp(n->name, "..") && (n->parent->flags & FF_EXT)) {
+ e = dir_ext_ptr(n->parent);
+ } else {
+ snprintf(mbuf, sizeof(mbuf), "no mtime");
+ goto no_mtime;
+ }
+ t = (time_t)e->mtime;
+
+ strftime(mbuf, sizeof(mbuf), "%Y-%m-%d %H:%M:%S %z", localtime(&t));
+ uic_set(c == UIC_SEL ? UIC_NUM_SEL : UIC_NUM);
+no_mtime:
+ printw("%26s", mbuf);
+ *x += 27;
+}
+
+
static void browse_draw_item(struct dir *n, int row) {
int x = 0;
@@ -218,6 +242,11 @@ static void browse_draw_item(struct dir *n, int row) {
browse_draw_items(n, &x);
move(row, x);
+ if (extended_info && show_mtime) {
+ browse_draw_mtime(n, &x);
+ move(row, x);
+ }
+
if(n->flags & FF_DIR)
c = c == UIC_SEL ? UIC_DIR_SEL : UIC_DIR;
addchc(c, n->flags & FF_DIR ? '/' : ' ');
@@ -409,6 +438,12 @@ int browse_key(int ch) {
dirlist_set_sort(DL_COL_ITEMS, dirlist_sort_col == DL_COL_ITEMS ? !dirlist_sort_desc : 1, DL_NOCHANGE);
info_show = 0;
break;
+ case 'M':
+ if (extended_info) {
+ dirlist_set_sort(DL_COL_MTIME, dirlist_sort_col == DL_COL_MTIME ? !dirlist_sort_desc : 1, DL_NOCHANGE);
+ info_show = 0;
+ }
+ break;
case 'e':
dirlist_set_hidden(!dirlist_hidden);
info_show = 0;
@@ -474,6 +509,10 @@ int browse_key(int ch) {
case 'c':
show_items = !show_items;
break;
+ case 'm':
+ if (extended_info)
+ show_mtime = !show_mtime;
+ break;
case 'i':
info_show = !info_show;
break;
diff --git a/src/dir_mem.c b/src/dir_mem.c
index 5007980..dc15586 100644
--- a/src/dir_mem.c
+++ b/src/dir_mem.c
@@ -144,10 +144,13 @@ static int item(struct dir *dir, const char *name, struct dir_ext *ext) {
* possible hard link, because hlnk_check() will take care of it in that
* case. */
if(item->flags & FF_HLNKC) {
- addparentstats(item->parent, 0, 0, 1);
+ addparentstats(item->parent, 0, 0, 0, 1);
hlink_check(item);
- } else
- addparentstats(item->parent, item->size, item->asize, 1);
+ } else if(item->flags & FF_EXT) {
+ addparentstats(item->parent, item->size, item->asize, dir_ext_ptr(item)->mtime, 1);
+ } else {
+ addparentstats(item->parent, item->size, item->asize, 0, 1);
+ }
/* propagate ERR and SERR back up to the root */
if(item->flags & FF_SERR || item->flags & FF_ERR)
diff --git a/src/dirlist.c b/src/dirlist.c
index da51a98..63a4cac 100644
--- a/src/dirlist.c
+++ b/src/dirlist.c
@@ -50,6 +50,14 @@ static struct dir *parent_alloc, *head, *head_real, *selected, *top = NULL;
))
+static inline int cmp_mtime(struct dir *x, struct dir*y) {
+ int64_t x_mtime = 0, y_mtime = 0;
+ if (x->flags & FF_EXT)
+ x_mtime = dir_ext_ptr(x)->mtime;
+ if (y->flags & FF_EXT)
+ y_mtime = dir_ext_ptr(y)->mtime;
+ return (x_mtime > y_mtime ? 1 : (x_mtime == y_mtime ? 0 : -1));
+}
static int dirlist_cmp(struct dir *x, struct dir *y) {
int r;
@@ -80,7 +88,8 @@ static int dirlist_cmp(struct dir *x, struct dir *y) {
r = dirlist_sort_col == DL_COL_NAME ? CMP_NAME :
dirlist_sort_col == DL_COL_SIZE ? CMP_SIZE :
dirlist_sort_col == DL_COL_ASIZE ? CMP_ASIZE :
- CMP_ITEMS;
+ dirlist_sort_col == DL_COL_ITEMS ? CMP_ITEMS :
+ cmp_mtime(x, y);
/* try 2 */
if(!r)
r = dirlist_sort_col == DL_COL_SIZE ? CMP_ASIZE : CMP_SIZE;
diff --git a/src/dirlist.h b/src/dirlist.h
index 6e19e4f..5437e4b 100644
--- a/src/dirlist.h
+++ b/src/dirlist.h
@@ -37,6 +37,7 @@
#define DL_COL_SIZE 1
#define DL_COL_ASIZE 2
#define DL_COL_ITEMS 3
+#define DL_COL_MTIME 4
void dirlist_open(struct dir *);
diff --git a/src/help.c b/src/help.c
index 1c46b0f..caba9b3 100644
--- a/src/help.c
+++ b/src/help.c
@@ -32,7 +32,7 @@
int page, start;
-#define KEYS 17
+#define KEYS 19
char *keys[KEYS*2] = {
/*|----key----| |----------------description----------------|*/
"up, k", "Move cursor up",
@@ -42,11 +42,13 @@ char *keys[KEYS*2] = {
"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",
diff --git a/src/util.c b/src/util.c
index 5f3dbd3..45660bf 100644
--- a/src/util.c
+++ b/src/util.c
@@ -344,8 +344,11 @@ void freedir(struct dir *dr) {
freedir_hlnk(dr);
/* update sizes of parent directories if this isn't a hard link.
- * If this is a hard link, freedir_hlnk() would have done so already */
- addparentstats(dr->parent, dr->flags & FF_HLNKC ? 0 : -dr->size, dr->flags & FF_HLNKC ? 0 : -dr->asize, -(dr->items+1));
+ * If this is a hard link, freedir_hlnk() would have done so already
+ *
+ * mtime is 0 here because recalculating the maximum at every parent
+ * dir is expensive, but might be good feature to add later if desired */
+ addparentstats(dr->parent, dr->flags & FF_HLNKC ? 0 : -dr->size, dr->flags & FF_HLNKC ? 0 : -dr->asize, 0, -(dr->items+1));
free(dr);
}
@@ -397,11 +400,16 @@ struct dir *getroot(struct dir *d) {
}
-void addparentstats(struct dir *d, int64_t size, int64_t asize, int items) {
+void addparentstats(struct dir *d, int64_t size, int64_t asize, uint64_t mtime, int items) {
+ struct dir_ext *e;
while(d) {
d->size = adds64(d->size, size);
d->asize = adds64(d->asize, asize);
d->items += items;
+ if (d->flags & FF_EXT) {
+ e = dir_ext_ptr(d);
+ e->mtime = (e->mtime > mtime) ? e->mtime : mtime;
+ }
d = d->parent;
}
}
diff --git a/src/util.h b/src/util.h
index 0af8e77..a1b9781 100644
--- a/src/util.h
+++ b/src/util.h
@@ -163,7 +163,7 @@ struct dir *getroot(struct dir *);
: (a)+(b) < 0 ? 0 : (a)+(b))
/* Adds a value to the size, asize and items fields of *d and its parents */
-void addparentstats(struct dir *, int64_t, int64_t, int);
+void addparentstats(struct dir *, int64_t, int64_t, uint64_t, int);
/* A simple stack implemented in macros */