summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2014-01-22 13:30:51 +0100
committerYorhel <git@yorhel.nl>2014-01-22 13:30:51 +0100
commitfe932c7b2215d49945e8ac02590b5ac49a98ffbd (patch)
treebb94a6819406b4366ea9cf577a436fdc757613d4
parent3f29a46f3ab94090448f793a7d7c90c6743e84be (diff)
Add support for browsing empty directories
Turns out that being able to open an empty directory actually has its uses: - If you delete the last file in a directory, you now won't be directed to the parent directory anymore. This allows keeping 'd' pressed without worrying that you'll delete stuff outside of the current dir. (This is the primary motivation for doing this) - You can now scan and later refresh an empty directory, as suggested by #2 in http://dev.yorhel.nl/ncdu/bug/15
-rw-r--r--src/browser.c24
-rw-r--r--src/delete.c14
-rw-r--r--src/dir_import.c2
-rw-r--r--src/dir_mem.c2
-rw-r--r--src/dir_scan.c6
-rw-r--r--src/dirlist.c19
-rw-r--r--src/dirlist.h3
7 files changed, 36 insertions, 34 deletions
diff --git a/src/browser.c b/src/browser.c
index 1039834..f2fadda 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -187,9 +187,9 @@ void browse_draw() {
/* second line - the path */
mvhline(1, 0, '-', wincols);
- if(t) {
+ if(dirlist_par) {
mvaddch(1, 3, ' ');
- tmp = getpath(t->parent);
+ tmp = getpath(dirlist_par);
mvaddstr(1, 4, cropstr(tmp, wincols-8));
mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' ');
}
@@ -363,8 +363,8 @@ int browse_key(int ch) {
case 10:
case KEY_RIGHT:
case 'l':
- if(sel != NULL && sel->sub != NULL) {
- dirlist_open(sel->sub);
+ if(sel != NULL && sel->flags & FF_DIR) {
+ dirlist_open(sel == dirlist_parent ? dirlist_par->parent : sel);
dirlist_top(-3);
}
info_show = 0;
@@ -372,8 +372,8 @@ int browse_key(int ch) {
case KEY_LEFT:
case 'h':
case '<':
- if(sel != NULL && sel->parent->parent != NULL) {
- dirlist_open(sel->parent);
+ if(dirlist_par && dirlist_par->parent != NULL) {
+ dirlist_open(dirlist_par->parent);
dirlist_top(-3);
}
info_show = 0;
@@ -385,10 +385,10 @@ int browse_key(int ch) {
message = "Directory imported from file, won't refresh.";
break;
}
- if(sel != NULL) {
+ if(dirlist_par) {
dir_ui = 2;
- dir_mem_init(sel->parent);
- dir_scan_init(getpath(sel->parent));
+ dir_mem_init(dirlist_par);
+ dir_scan_init(getpath(dirlist_par));
}
info_show = 0;
break;
@@ -425,7 +425,7 @@ int browse_key(int ch) {
info_show = 0;
if((t = dirlist_get(1)) == sel)
if((t = dirlist_get(-1)) == sel || t == dirlist_parent)
- t = sel->parent;
+ t = NULL;
delete_init(sel, t);
break;
}
@@ -441,9 +441,9 @@ int browse_key(int ch) {
}
-void browse_init(struct dir *cur) {
+void browse_init(struct dir *par) {
pstate = ST_BROWSE;
message = NULL;
- dirlist_open(cur);
+ dirlist_open(par);
}
diff --git a/src/delete.c b/src/delete.c
index 015af78..9c358c1 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -209,11 +209,13 @@ delete_nxt:
void delete_process() {
+ struct dir *par;
+
/* confirm */
seloption = 1;
while(state == DS_CONFIRM && !noconfirm)
if(input_handle(0)) {
- browse_init(root);
+ browse_init(root->parent);
return;
}
@@ -229,13 +231,13 @@ void delete_process() {
/* delete */
seloption = 0;
state = DS_PROGRESS;
- if(delete_dir(root))
- browse_init(root);
- else {
+ par = root->parent;
+ delete_dir(root);
+ if(nextsel)
nextsel->flags |= FF_BSEL;
- browse_init(nextsel);
+ browse_init(par);
+ if(nextsel)
dirlist_top(-4);
- }
}
diff --git a/src/dir_import.c b/src/dir_import.c
index 40a3a53..03bcfbf 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -547,8 +547,6 @@ static int item(uint64_t dev) {
if(!isroot)
dir_curpath_leave();
- else /* The root item must not be empty. */
- E(ctx->items <= 1, "Empty directory");
return 0;
}
diff --git a/src/dir_mem.c b/src/dir_mem.c
index 888d698..73dd848 100644
--- a/src/dir_mem.c
+++ b/src/dir_mem.c
@@ -198,7 +198,7 @@ static int final(int fail) {
freedir(orig);
}
- browse_init(root->sub);
+ browse_init(root);
dirlist_top(-3);
return 0;
}
diff --git a/src/dir_scan.c b/src/dir_scan.c
index 2953421..e3d93e8 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -266,12 +266,6 @@ static int process() {
if(!dir_fatalerr && !(dir = dir_read(&fail)))
dir_seterr("Error reading directory: %s", strerror(errno));
- /* Special case: empty directory = error */
- if(!dir_fatalerr && !*dir) {
- dir_seterr("Directory empty");
- free(dir);
- }
-
if(!dir_fatalerr) {
curdev = (uint64_t)fs.st_dev;
d = dir_createstruct(dir_curpath);
diff --git a/src/dirlist.c b/src/dirlist.c
index a61b816..7b7fa9e 100644
--- a/src/dirlist.c
+++ b/src/dirlist.c
@@ -29,7 +29,8 @@
/* public variables */
-struct dir *dirlist_parent = NULL;
+struct dir *dirlist_parent = NULL,
+ *dirlist_par = NULL;
int64_t dirlist_maxs = 0,
dirlist_maxa = 0;
@@ -186,29 +187,33 @@ static void dirlist_fixup() {
void dirlist_open(struct dir *d) {
+ dirlist_par = d;
+
/* set the head of the list */
- head_real = head = d == NULL ? NULL : d->parent == NULL ? d->sub : d->parent->sub;
+ head_real = head = d == NULL ? NULL : d->sub;
/* reset internal status */
dirlist_maxs = dirlist_maxa = 0;
/* stop if this is not a directory list we can work with */
- if(head == NULL) {
+ if(d == NULL) {
dirlist_parent = NULL;
return;
}
/* sort the dir listing */
- head_real = head = dirlist_sort(head);
+ if(head)
+ head_real = head = dirlist_sort(head);
/* set the reference to the parent dir */
dirlist_parent_alloc.flags &= ~FF_BSEL;
- if(head->parent->parent) {
+ dirlist_parent_alloc.flags |= FF_DIR;
+ if(d->parent) {
dirlist_parent = &dirlist_parent_alloc;
strcpy(dirlist_parent->name, "..");
dirlist_parent->next = head;
- dirlist_parent->parent = head->parent;
- dirlist_parent->sub = head->parent;
+ dirlist_parent->parent = d;
+ dirlist_parent->sub = d;
head = dirlist_parent;
} else
dirlist_parent = NULL;
diff --git a/src/dirlist.h b/src/dirlist.h
index c69e117..f4bf1af 100644
--- a/src/dirlist.h
+++ b/src/dirlist.h
@@ -68,6 +68,9 @@ void dirlist_set_hidden(int hidden);
/* The 'reference to parent dir' */
extern struct dir *dirlist_parent;
+/* The actual parent dir */
+extern struct dir *dirlist_par;
+
/* current sorting configuration (set with dirlist_set_sort()) */
extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df;