From 78115189034ac52eefa4e51931108b9904ea23fb Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Sat, 2 Mar 2019 21:59:12 +0530
Subject: [PATCH] Add empty trash key T

---
 README.md |  2 +-
 nnn.1     |  6 +++--
 src/nnn.c | 69 +++++++++++++++++++++++++++++++++++++++++++++----------
 src/nnn.h |  3 +++
 4 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index 9b3b8949..e17d9390 100644
--- a/README.md
+++ b/README.md
@@ -267,7 +267,7 @@ Press <kbd>?</kbd> 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 */
-- 
2.51.0