aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-03-02 16:53:16 +0530
committerGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-03-02 18:32:23 +0530
commit62d1ff278f1059773d66da6366d632606354c0ef (patch)
treee6b9229cdc0577ba2f039d6fe8a7582624bf5b4e
parentbf7a5f25aab507c74d6aafa06cac72b10d22da13 (diff)
downloadnnn-62d1ff278f1059773d66da6366d632606354c0ef.tar.gz
Trash file when deleted
-rw-r--r--README.md9
-rw-r--r--nnn.17
-rw-r--r--src/nnn.c59
3 files changed, 55 insertions, 20 deletions
diff --git a/README.md b/README.md
index 533d4a8..270a17d 100644
--- a/README.md
+++ b/README.md
@@ -102,11 +102,11 @@ It runs on Linux, macOS, Raspberry Pi, BSD, Cygwin, Linux subsystem for Windows
- Convenience
- Create, rename files and directories
- Select files across dirs; all/range selection
- - Copy, move, delete, archive selection
+ - Copy, move, trash, delete, archive selection
- Show copy, move progress on Linux (needs avdcpmv)
- Create sym/hard link(s) to selection
- Transfer files using lftp
- - Batch rename/move/delete (needs vidir)
+ - Batch rename (needs vidir)
- Show directories in custom color (default: blue)
- Per-context directory color
- Spawn a subshell in the current directory
@@ -153,7 +153,7 @@ Intrigued? Find out [HOW](https://github.com/jarun/nnn/wiki/performance-factors)
| cp, mv, rm, xargs (from findutils on Linux) | copy, move and remove files |
| mediainfo, exiftool | multimedia file details |
| atool, patool ([integration](https://github.com/jarun/nnn/wiki/How-to#integrate-patool)) | create, list and extract archives |
-| vidir (from moreutils) | batch rename, move, delete dir entries |
+| vidir (from moreutils) | batch rename dir entries |
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | terminal locker |
| advcpmv (Linux) ([integration](https://github.com/jarun/nnn/wiki/How-to#show-cp-mv-progress)) | copy, move progress |
| $EDITOR (overridden by $VISUAL, if defined) | edit files (fallback vi) |
@@ -254,7 +254,7 @@ Press <kbd>?</kbd> in `nnn` to see the list anytime.
FILES
^O Open with... n Create new/link
D File details ^R Rename entry
- ⎵ ^K / Y Select entry/all r Open dir in vidir
+ ⎵ ^K / Y Select entry/all r Batch rename
K ^Y Toggle selection y List selection
P Copy selection X Delete selection
V Move selection ^X Delete entry
@@ -393,6 +393,7 @@ The following indicators are used in the detail view:
| `NNN_NO_AUTOSELECT=1` | do not auto-select matching dir in _nav-as-you-type` mode |
| `NNN_RESTRICT_NAV_OPEN=1` | open files on <kbd> ↵</kbd>, not <kbd>→</kbd> or <kbd>l</kbd> |
| `NNN_RESTRICT_0B=1` | do not open 0-byte files |
+| `NNN_TRASH=1` | move files to `~/.local/share/nnn/trash` on delete |
| `NNN_CP_MV_PROG=1` | show copy, move progress on Linux |
#### Help
diff --git a/nnn.1 b/nnn.1
index 8617a4d..e37b2a3 100644
--- a/nnn.1
+++ b/nnn.1
@@ -97,7 +97,7 @@ Show entry details
.It Ic ^R
Rename selected entry
.It Ic r
-Open directory in vidir
+Batch rename
.It Ic K, ^Y
Toggle selection mode
.It Ic Y
@@ -348,6 +348,11 @@ files.
export NNN_RESTRICT_0B=1
.Ed
.Pp
+\fBNNN_TRASH:\fR move files to \fB~/.local/share/nnn/trash\fR on delete.
+.Bd -literal
+ export NNN_TRASH=1
+.Ed
+.Pp
\fBNNN_CP_MV_PROG:\fR show progress of copy, move operations (Linux-only, needs advcpmv).
.Bd -literal
export NNN_CP_MV_PROG=1
diff --git a/src/nnn.c b/src/nnn.c
index 4038c6f..60d5dc5 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -285,7 +285,7 @@ typedef struct {
uint dircolor : 1; /* Current status of dir color */
uint metaviewer : 1; /* Index of metadata viewer in utils[] */
uint ctxactive : 1; /* Context active or not */
- uint reserved : 8;
+ uint reserved : 7;
/* The following settings are global */
uint curctx : 2; /* Current context number */
uint picker : 1; /* Write selection to user-specified file */
@@ -297,6 +297,7 @@ typedef struct {
uint restrict0b : 1; /* Restrict 0-byte file opening */
uint filter_re : 1; /* Use regex filters */
uint wild : 1; /* Do not sort entries on dir load */
+ uint trash : 1; /* Move removed files to trash */
} settings;
/* Contexts or workspaces */
@@ -311,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};
+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 context g_ctx[CTX_MAX] __attribute__ ((aligned));
static struct entry *dents;
@@ -446,8 +447,9 @@ static const char * const messages[] = {
#define NNN_NO_AUTOSELECT 11
#define NNN_RESTRICT_NAV_OPEN 12
#define NNN_RESTRICT_0B 13
+#define NNN_TRASH 14
#ifdef __linux__
-#define NNN_CP_MV_PROG 14
+#define NNN_CP_MV_PROG 15
#endif
static const char * const env_cfg[] = {
@@ -465,6 +467,7 @@ static const char * const env_cfg[] = {
"NNN_NO_AUTOSELECT",
"NNN_RESTRICT_NAV_OPEN",
"NNN_RESTRICT_0B",
+ "NNN_TRASH",
#ifdef __linux__
"NNN_CP_MV_PROG",
#endif
@@ -1152,18 +1155,26 @@ static void cpstr(char *buf)
#endif
}
-static void mvstr(char *buf)
+static void mvstr(char *buf, const char *dst)
{
snprintf(buf, CMD_LEN_MAX,
#ifdef __linux__
- "xargs -0 -a %s -%c src %s src .", g_cppath, REPLACE_STR, mv);
+ "xargs -0 -a %s -%c src %s src %s", g_cppath, REPLACE_STR, mv, dst);
#else
- "cat %s | xargs -0 -o -%c src mv -i src .", g_cppath, REPLACE_STR);
+ "cat %s | xargs -0 -o -%c src mv -i src %s", g_cppath, REPLACE_STR, dst);
#endif
}
-static void rmmulstr(char *buf)
+static bool rmmulstr(char *buf, const char *curpath)
{
+ if (cfg.trash && strcmp(curpath, g_trash) != 0) {
+ if (!xdiraccess(g_trash))
+ return FALSE;
+
+ mvstr(buf, g_trash);
+ return TRUE;
+ }
+
snprintf(buf, CMD_LEN_MAX,
#ifdef __linux__
"xargs -0 -a %s rm -%cr",
@@ -1171,13 +1182,27 @@ static void rmmulstr(char *buf)
"cat %s | xargs -0 -o rm -%cr",
#endif
g_cppath, confirm_force());
+ return TRUE;
}
-static void xrm(char *path)
+static bool xrm(char *path)
{
+ DPRINTF_S(path);
+ DPRINTF_S(xbasename(path));
+ DPRINTF_S(g_trash);
+ if (cfg.trash && strcmp(xdirname(path), g_trash) != 0) {
+ if (!xdiraccess(g_trash))
+ return FALSE;
+
+ spawn("mv", path, g_trash, NULL, F_NORMAL | F_SIGINT);
+ DPRINTF_S(g_buf);
+ return TRUE;
+ }
+
char rm_opts[] = {'-', confirm_force(), 'r'};
spawn("rm", rm_opts, path, NULL, F_NORMAL | F_SIGINT);
+ return TRUE;
}
static int digit_compare(const char *a, const char *b)
@@ -2332,7 +2357,7 @@ static bool show_help(const char *path)
"1FILES\n"
"b^O Open with... n Create new/link\n"
"cD File details ^R Rename entry\n"
- "5⎵ ^K / Y Select entry/all r Open dir in vidir\n"
+ "5⎵ ^K / Y Select entry/all r Batch rename\n"
"9K ^Y Toggle selection y List selection\n"
"cP Copy selection X Delete selection\n"
"cV Move selection ^X Delete entry\n"
@@ -2383,7 +2408,7 @@ static bool show_help(const char *path)
dprintf(fd, "\n");
}
- for (i = NNN_OPENER; i <= NNN_RESTRICT_0B; ++i) {
+ for (i = NNN_OPENER; i <= NNN_TRASH; ++i) {
start = getenv(env_cfg[i]);
if (start) {
if (i < NNN_USE_EDITOR)
@@ -3498,10 +3523,11 @@ nochange:
cpstr(g_buf);
break;
case SEL_MV:
- mvstr(g_buf);
+ mvstr(g_buf, ".");
break;
default: /* SEL_RMMUL */
- rmmulstr(g_buf);
+ if (!rmmulstr(g_buf, path))
+ goto nochange;
break;
}
@@ -3519,7 +3545,8 @@ nochange:
break;
mkpath(path, dents[cur].name, newpath);
- xrm(newpath);
+ if (!xrm(newpath))
+ goto nochange;
/* Don't optimize cur if filtering is on */
if (!cfg.filtermode && cur && access(newpath, F_OK) == -1)
@@ -4090,9 +4117,9 @@ int main(int argc, char *argv[])
home = getenv("HOME");
DPRINTF_S(home);
- if (getenv("NNN_TRASH")) {
+ if (getenv(env_cfg[NNN_TRASH])) {
if (!home) {
- fprintf(stderr, "trash! no HOME!\n");
+ fprintf(stderr, "trash: HOME!\n");
return 1;
}
@@ -4108,6 +4135,8 @@ int main(int argc, char *argv[])
DPRINTF_S(g_trash);
if (!createdir(g_trash, 0777))
return 1;
+
+ cfg.trash = 1;
}
if (home) {