diff --git a/README.md b/README.md index 9b3b8949..e17d9390 100644 --- a/README.md +++ b/README.md @@ -267,7 +267,7 @@ Press ? in `nnn` to see the list anytime. MISC ! ^] Spawn SHELL C Execute entry R ^V Run/pick script L Lock terminal - ^P Command prompt ^N Take note + ^P Prompt ^N Note T Empty trash ``` Help & settings, file details, media info and archive listing are shown in the PAGER. Please use the PAGER-specific keys in these screens. diff --git a/nnn.1 b/nnn.1 index c235b602..425cd09d 100644 --- a/nnn.1 +++ b/nnn.1 @@ -154,10 +154,12 @@ Execute entry Run or pick a script to run .It Ic L Lock terminal -.It Ic ^N -Take note .It Ic ^P Show command prompt +.It Ic ^N +Take note +.It Ic T +Empty trash .El .Pp Backing up one directory level will set the cursor position at the diff --git a/src/nnn.c b/src/nnn.c index d0533289..e91d40d9 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -312,7 +312,7 @@ typedef struct { /* GLOBALS */ /* Configuration, contexts */ -static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}; +static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}; static context g_ctx[CTX_MAX] __attribute__ ((aligned)); static struct entry *dents; @@ -1167,7 +1167,7 @@ static void mvstr(char *buf, const char *dst) static bool rmmulstr(char *buf, const char *curpath) { - if (cfg.trash && strcmp(curpath, g_trash) != 0) { + if (cfg.trash) { if (!xdiraccess(g_trash)) return FALSE; @@ -1205,6 +1205,40 @@ static bool xrm(char *path) return TRUE; } +/* + * Returns: + * FALSE - a message is shown + * TRUE - no message shown + */ +static bool empty_trash(const char *path) +{ + size_t r; + + if (!cfg.trash) { + printmsg("set NNN_TRASH"); + return FALSE; + } + + if (!xdiraccess(g_trash)) + return FALSE; + + r = xstrlcpy(g_buf, "rm -rf ", CMD_LEN_MAX); + r += xstrlcpy(g_buf + r - 1, g_trash, CMD_LEN_MAX - r); + g_buf[r - 2] = '/'; + g_buf[r - 1] = '*'; + g_buf[r] = '\0'; + + spawn("sh", "-c", g_buf, NULL, F_NORMAL | F_SIGINT); + + /* Show msg only if not in trash, else refresh trash */ + if (strcmp(path, g_trash) != 0) { + printmsg("trash emptied"); + return FALSE; + } + + return TRUE; +} + static int digit_compare(const char *a, const char *b) { while (*a && *b && *a == *b) @@ -2370,7 +2404,7 @@ static bool show_help(const char *path) "1MISC\n" "9! ^] Spawn SHELL C Execute entry\n" "9R ^V Run/pick script L Lock terminal\n" - "b^P Command prompt ^N Take note\n"}; + "b^P Prompt ^N Note T Empty trash\n"}; if (g_tmpfpath[0]) xstrlcpy(g_tmpfpath + g_tmpfplen - 1, messages[STR_TMPFILE], @@ -3539,18 +3573,29 @@ nochange: presel = FILTER; goto begin; } - case SEL_RM: + case SEL_RM: // fallthrough + case SEL_RMTRASH: { - if (!ndents) - break; + if (sel == SEL_RM) { + if (!ndents) + break; - mkpath(path, dents[cur].name, newpath); - if (!xrm(newpath)) - goto nochange; + mkpath(path, dents[cur].name, newpath); - /* Don't optimize cur if filtering is on */ - if (!cfg.filtermode && cur && access(newpath, F_OK) == -1) - --cur; + if (!xrm(newpath)) + goto nochange; + + /* Don't optimize cur if filtering is on */ + if (!cfg.filtermode && cur && access(newpath, F_OK) == -1) + --cur; + } else { + r = get_input("Empty trash? [y/Y]"); + if (!(r == 'y' || r == 'Y')) + break; + + if (!empty_trash(path)) + goto nochange; + } copycurname(); diff --git a/src/nnn.h b/src/nnn.h index a2a858bf..b535639b 100644 --- a/src/nnn.h +++ b/src/nnn.h @@ -80,6 +80,7 @@ enum action { SEL_MV, SEL_RMMUL, SEL_RM, + SEL_RMTRASH, SEL_OPENWITH, SEL_NEW, SEL_RENAME, @@ -206,6 +207,8 @@ static struct key bindings[] = { { 'X', SEL_RMMUL }, /* Delete currently selected */ { CONTROL('X'), SEL_RM }, + /* Clear trash */ + { 'T', SEL_RMTRASH }, /* Open in a custom application */ { CONTROL('O'), SEL_OPENWITH }, /* Create a new file */