Skip to content
Snippets Groups Projects
Commit fe932c7b authored by Yorhel's avatar Yorhel
Browse files

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
parent 3f29a46f
No related branches found
No related tags found
No related merge requests found
...@@ -187,9 +187,9 @@ void browse_draw() { ...@@ -187,9 +187,9 @@ void browse_draw() {
/* second line - the path */ /* second line - the path */
mvhline(1, 0, '-', wincols); mvhline(1, 0, '-', wincols);
if(t) { if(dirlist_par) {
mvaddch(1, 3, ' '); mvaddch(1, 3, ' ');
tmp = getpath(t->parent); tmp = getpath(dirlist_par);
mvaddstr(1, 4, cropstr(tmp, wincols-8)); mvaddstr(1, 4, cropstr(tmp, wincols-8));
mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' '); mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' ');
} }
...@@ -363,8 +363,8 @@ int browse_key(int ch) { ...@@ -363,8 +363,8 @@ int browse_key(int ch) {
case 10: case 10:
case KEY_RIGHT: case KEY_RIGHT:
case 'l': case 'l':
if(sel != NULL && sel->sub != NULL) { if(sel != NULL && sel->flags & FF_DIR) {
dirlist_open(sel->sub); dirlist_open(sel == dirlist_parent ? dirlist_par->parent : sel);
dirlist_top(-3); dirlist_top(-3);
} }
info_show = 0; info_show = 0;
...@@ -372,8 +372,8 @@ int browse_key(int ch) { ...@@ -372,8 +372,8 @@ int browse_key(int ch) {
case KEY_LEFT: case KEY_LEFT:
case 'h': case 'h':
case '<': case '<':
if(sel != NULL && sel->parent->parent != NULL) { if(dirlist_par && dirlist_par->parent != NULL) {
dirlist_open(sel->parent); dirlist_open(dirlist_par->parent);
dirlist_top(-3); dirlist_top(-3);
} }
info_show = 0; info_show = 0;
...@@ -385,10 +385,10 @@ int browse_key(int ch) { ...@@ -385,10 +385,10 @@ int browse_key(int ch) {
message = "Directory imported from file, won't refresh."; message = "Directory imported from file, won't refresh.";
break; break;
} }
if(sel != NULL) { if(dirlist_par) {
dir_ui = 2; dir_ui = 2;
dir_mem_init(sel->parent); dir_mem_init(dirlist_par);
dir_scan_init(getpath(sel->parent)); dir_scan_init(getpath(dirlist_par));
} }
info_show = 0; info_show = 0;
break; break;
...@@ -425,7 +425,7 @@ int browse_key(int ch) { ...@@ -425,7 +425,7 @@ int browse_key(int ch) {
info_show = 0; info_show = 0;
if((t = dirlist_get(1)) == sel) if((t = dirlist_get(1)) == sel)
if((t = dirlist_get(-1)) == sel || t == dirlist_parent) if((t = dirlist_get(-1)) == sel || t == dirlist_parent)
t = sel->parent; t = NULL;
delete_init(sel, t); delete_init(sel, t);
break; break;
} }
...@@ -441,9 +441,9 @@ int browse_key(int ch) { ...@@ -441,9 +441,9 @@ int browse_key(int ch) {
} }
void browse_init(struct dir *cur) { void browse_init(struct dir *par) {
pstate = ST_BROWSE; pstate = ST_BROWSE;
message = NULL; message = NULL;
dirlist_open(cur); dirlist_open(par);
} }
...@@ -209,11 +209,13 @@ delete_nxt: ...@@ -209,11 +209,13 @@ delete_nxt:
void delete_process() { void delete_process() {
struct dir *par;
/* confirm */ /* confirm */
seloption = 1; seloption = 1;
while(state == DS_CONFIRM && !noconfirm) while(state == DS_CONFIRM && !noconfirm)
if(input_handle(0)) { if(input_handle(0)) {
browse_init(root); browse_init(root->parent);
return; return;
} }
...@@ -229,13 +231,13 @@ void delete_process() { ...@@ -229,13 +231,13 @@ void delete_process() {
/* delete */ /* delete */
seloption = 0; seloption = 0;
state = DS_PROGRESS; state = DS_PROGRESS;
if(delete_dir(root)) par = root->parent;
browse_init(root); delete_dir(root);
else { if(nextsel)
nextsel->flags |= FF_BSEL; nextsel->flags |= FF_BSEL;
browse_init(nextsel); browse_init(par);
if(nextsel)
dirlist_top(-4); dirlist_top(-4);
}
} }
......
...@@ -547,8 +547,6 @@ static int item(uint64_t dev) { ...@@ -547,8 +547,6 @@ static int item(uint64_t dev) {
if(!isroot) if(!isroot)
dir_curpath_leave(); dir_curpath_leave();
else /* The root item must not be empty. */
E(ctx->items <= 1, "Empty directory");
return 0; return 0;
} }
......
...@@ -198,7 +198,7 @@ static int final(int fail) { ...@@ -198,7 +198,7 @@ static int final(int fail) {
freedir(orig); freedir(orig);
} }
browse_init(root->sub); browse_init(root);
dirlist_top(-3); dirlist_top(-3);
return 0; return 0;
} }
......
...@@ -266,12 +266,6 @@ static int process() { ...@@ -266,12 +266,6 @@ static int process() {
if(!dir_fatalerr && !(dir = dir_read(&fail))) if(!dir_fatalerr && !(dir = dir_read(&fail)))
dir_seterr("Error reading directory: %s", strerror(errno)); 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) { if(!dir_fatalerr) {
curdev = (uint64_t)fs.st_dev; curdev = (uint64_t)fs.st_dev;
d = dir_createstruct(dir_curpath); d = dir_createstruct(dir_curpath);
......
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
/* public variables */ /* public variables */
struct dir *dirlist_parent = NULL; struct dir *dirlist_parent = NULL,
*dirlist_par = NULL;
int64_t dirlist_maxs = 0, int64_t dirlist_maxs = 0,
dirlist_maxa = 0; dirlist_maxa = 0;
...@@ -186,29 +187,33 @@ static void dirlist_fixup() { ...@@ -186,29 +187,33 @@ static void dirlist_fixup() {
void dirlist_open(struct dir *d) { void dirlist_open(struct dir *d) {
dirlist_par = d;
/* set the head of the list */ /* 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 */ /* reset internal status */
dirlist_maxs = dirlist_maxa = 0; dirlist_maxs = dirlist_maxa = 0;
/* stop if this is not a directory list we can work with */ /* stop if this is not a directory list we can work with */
if(head == NULL) { if(d == NULL) {
dirlist_parent = NULL; dirlist_parent = NULL;
return; return;
} }
/* sort the dir listing */ /* 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 */ /* set the reference to the parent dir */
dirlist_parent_alloc.flags &= ~FF_BSEL; dirlist_parent_alloc.flags &= ~FF_BSEL;
if(head->parent->parent) { dirlist_parent_alloc.flags |= FF_DIR;
if(d->parent) {
dirlist_parent = &dirlist_parent_alloc; dirlist_parent = &dirlist_parent_alloc;
strcpy(dirlist_parent->name, ".."); strcpy(dirlist_parent->name, "..");
dirlist_parent->next = head; dirlist_parent->next = head;
dirlist_parent->parent = head->parent; dirlist_parent->parent = d;
dirlist_parent->sub = head->parent; dirlist_parent->sub = d;
head = dirlist_parent; head = dirlist_parent;
} else } else
dirlist_parent = NULL; dirlist_parent = NULL;
......
...@@ -68,6 +68,9 @@ void dirlist_set_hidden(int hidden); ...@@ -68,6 +68,9 @@ void dirlist_set_hidden(int hidden);
/* The 'reference to parent dir' */ /* The 'reference to parent dir' */
extern struct dir *dirlist_parent; extern struct dir *dirlist_parent;
/* The actual parent dir */
extern struct dir *dirlist_par;
/* current sorting configuration (set with dirlist_set_sort()) */ /* current sorting configuration (set with dirlist_set_sort()) */
extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df; extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment