diff --git a/README.md b/README.md index b1a204d6..e442851f 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,8 @@ 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, trash, delete, archive selection + - Copy, move, delete, archive selection + - Freedeskp compliant trash (needs trash-cli) - Show copy, move progress on Linux (needs avdcpmv) - Create sym/hard link(s) to selection - Transfer files using lftp @@ -135,6 +136,7 @@ It runs on Linux, macOS, Raspberry Pi, BSD, Cygwin, Linux subsystem for Windows | xdg-open (Linux), open(1) (macOS), cygstart (Cygwin) | desktop opener | | file | determine file type | | coreutils (cp, mv, rm), findutils (xargs) | copy, move and remove files | +| trash-cli | trash files instead of delete | | mediainfo or 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 dir entries | @@ -250,7 +252,7 @@ Press ? in `nnn` to see the list anytime. MISC ! ^] Spawn SHELL C Execute entry R ^V Run/pick script L Lock terminal - ^P Prompt ^N Note T Empty trash + ^P Prompt ^N Note ``` Help & settings, file details, media info and archive listing are shown in the PAGER. Use the PAGER-specific keys in these screens. @@ -376,7 +378,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 , not or l | | `NNN_RESTRICT_0B=1` | do not open 0-byte files | -| `NNN_TRASH=1` | move files to `~/.local/trash` on delete | +| `NNN_TRASH=1` | trash (instead of _delete_) files to desktop Trash | | `NNN_CP_MV_PROG=1` | show copy, move progress on Linux | #### Help diff --git a/nnn.1 b/nnn.1 index 9efb0da2..c4c16849 100644 --- a/nnn.1 +++ b/nnn.1 @@ -158,8 +158,6 @@ Lock terminal 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 @@ -350,7 +348,7 @@ files. export NNN_RESTRICT_0B=1 .Ed .Pp -\fBNNN_TRASH:\fR move files to \fB~/.local/trash\fR on delete. +\fBNNN_TRASH:\fR trash (instead of \fIdelete\fR) files to desktop Trash. .Bd -literal export NNN_TRASH=1 .Ed diff --git a/src/nnn.c b/src/nnn.c index a7b73d4e..c66a69e2 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -342,9 +342,6 @@ static char g_buf[CMD_LEN_MAX] __attribute__ ((aligned)); /* Buffer for file path copy file */ static char g_cppath[PATH_MAX] __attribute__ ((aligned)); -/* Buffer for trash dir */ -static char g_trash[PATH_MAX] __attribute__ ((aligned)); - /* Buffer to store tmp file path */ static char g_tmpfpath[HOME_LEN_MAX] __attribute__ ((aligned)); @@ -1122,25 +1119,6 @@ static bool xdiraccess(const char *path) return TRUE; } -/* - * Creates a dir if not present - */ -static bool createdir(const char *path, mode_t mode) -{ - DIR *dirp = opendir(path); - - if (dirp) { - closedir(dirp); - return TRUE; - } - - if (errno == ENOENT && !mkdir(path, mode)) - return TRUE; - - fprintf(stderr, "create %s %s\n", path, strerror(errno)); - return FALSE; -} - static void cpstr(char *buf) { snprintf(buf, CMD_LEN_MAX, @@ -1151,26 +1129,18 @@ static void cpstr(char *buf) #endif } -static void mvstr(char *buf, const char *dst) +static void mvstr(char *buf) { snprintf(buf, CMD_LEN_MAX, #ifdef __linux__ - "xargs -0 -a %s -%c src %s src %s", g_cppath, REPLACE_STR, mv, dst); + "xargs -0 -a %s -%c src %s src .", g_cppath, REPLACE_STR, mv); #else - "cat %s | xargs -0 -o -%c src mv -i src %s", g_cppath, REPLACE_STR, dst); + "cat %s | xargs -0 -o -%c src mv -i src .", g_cppath, REPLACE_STR); #endif } -static bool rmmulstr(char *buf, const char *curpath) +static void rmmulstr(char *buf) { - if (cfg.trash) { - 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", @@ -1178,27 +1148,13 @@ static bool rmmulstr(char *buf, const char *curpath) "cat %s | xargs -0 -o rm -%cr", #endif g_cppath, confirm_force()); - return TRUE; } -static bool xrm(char *path) +static void 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 void archive_selection(const char *archive, const char *curpath) @@ -1232,40 +1188,6 @@ static bool write_lastdir(const char *curpath) 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) @@ -2435,7 +2357,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 Prompt ^N Note T Empty trash\n"}; + "b^P Prompt ^N Note\n"}; if (g_tmpfpath[0]) xstrlcpy(g_tmpfpath + g_tmpfplen - 1, messages[STR_TMPFILE], @@ -3570,11 +3492,10 @@ nochange: cpstr(g_buf); break; case SEL_MV: - mvstr(g_buf, "."); + mvstr(g_buf); break; default: /* SEL_RMMUL */ - if (!rmmulstr(g_buf, path)) - goto nochange; + rmmulstr(g_buf); break; } @@ -3586,29 +3507,17 @@ nochange: presel = FILTER; goto begin; } - case SEL_RM: // fallthrough - case SEL_RMTRASH: + case SEL_RM: { - if (sel == SEL_RM) { - if (!ndents) - break; + if (!ndents) + break; - mkpath(path, dents[cur].name, newpath); + 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) - --cur; - } else { - r = get_input("Empty trash? [y/Y]"); - if (!(r == 'y' || r == 'Y')) - break; - - if (!empty_trash(path)) - goto nochange; - } + /* Don't optimize cur if filtering is on */ + if (!cfg.filtermode && cur && access(newpath, F_OK) == -1) + --cur; copycurname(); @@ -4149,21 +4058,8 @@ int main(int argc, char *argv[]) home = getenv("HOME"); DPRINTF_S(home); - if (getenv(env_cfg[NNN_TRASH])) { - if (!home) { - fprintf(stderr, "trash: HOME!\n"); - return 1; - } - - /* Create trash dir if missing */ - g_tmpfplen = xstrlcpy(g_trash, home, PATH_MAX); - xstrlcpy(g_trash + g_tmpfplen - 1, "/.local/trash", PATH_MAX - g_tmpfplen); - DPRINTF_S(g_trash); - if (!createdir(g_trash, 0777)) - return 1; - + if (getenv(env_cfg[NNN_TRASH])) cfg.trash = 1; - } /* Prefix for other temporary ops */ if (home) diff --git a/src/nnn.h b/src/nnn.h index d278466e..c593685b 100644 --- a/src/nnn.h +++ b/src/nnn.h @@ -80,7 +80,6 @@ enum action { SEL_MV, SEL_RMMUL, SEL_RM, - SEL_RMTRASH, SEL_OPENWITH, SEL_NEW, SEL_RENAME, @@ -207,8 +206,6 @@ 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 */