]> Sergey Matveev's repositories - nnn.git/commitdiff
Trash file when deleted
authorArun Prakash Jana <engineerarun@gmail.com>
Sat, 2 Mar 2019 11:23:16 +0000 (16:53 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Sat, 2 Mar 2019 13:02:23 +0000 (18:32 +0530)
README.md
nnn.1
src/nnn.c

index 533d4a81425d24aca7d72cb5f364f297a907eb8c..270a17de1dbe0c05d2a4e063faa2bb4b47cd360b 100644 (file)
--- 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 8617a4d45510a9d3c2af48adb8ac9a2f967bb0ba..e37b2a38971d34ac8aee764a707b1d77e05145dc 100644 (file)
--- 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
index 4038c6fc4ab2cac06ad7bb9a9cbd93f1509407a2..60d5dc59d64f6fc5e09798a23474a30e0a133854 100644 (file)
--- 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) {