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
This commit is contained in:
Yorhel 2014-01-22 13:30:51 +01:00
parent 3f29a46f3a
commit fe932c7b22
7 changed files with 36 additions and 34 deletions

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -198,7 +198,7 @@ static int final(int fail) {
freedir(orig);
}
browse_init(root->sub);
browse_init(root);
dirlist_top(-3);
return 0;
}

View file

@ -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);

View file

@ -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;

View file

@ -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;