mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
Revert native trashing
This commit is contained in:
parent
38fe392c43
commit
090e55c74a
|
@ -100,7 +100,8 @@ It runs on Linux, macOS, Raspberry Pi, BSD, Cygwin, Linux subsystem for Windows
|
||||||
- Convenience
|
- Convenience
|
||||||
- Create, rename files and directories
|
- Create, rename files and directories
|
||||||
- Select files across dirs; all/range selection
|
- 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)
|
- Show copy, move progress on Linux (needs avdcpmv)
|
||||||
- Create sym/hard link(s) to selection
|
- Create sym/hard link(s) to selection
|
||||||
- Transfer files using lftp
|
- 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 |
|
| xdg-open (Linux), open(1) (macOS), cygstart (Cygwin) | desktop opener |
|
||||||
| file | determine file type |
|
| file | determine file type |
|
||||||
| coreutils (cp, mv, rm), findutils (xargs) | copy, move and remove files |
|
| coreutils (cp, mv, rm), findutils (xargs) | copy, move and remove files |
|
||||||
|
| trash-cli | trash files instead of delete |
|
||||||
| mediainfo or exiftool | multimedia file details |
|
| mediainfo or exiftool | multimedia file details |
|
||||||
| atool, patool ([integration](https://github.com/jarun/nnn/wiki/How-to#integrate-patool)) | create, list and extract archives |
|
| 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 |
|
| vidir (from moreutils) | batch rename dir entries |
|
||||||
|
@ -250,7 +252,7 @@ Press <kbd>?</kbd> in `nnn` to see the list anytime.
|
||||||
MISC
|
MISC
|
||||||
! ^] Spawn SHELL C Execute entry
|
! ^] Spawn SHELL C Execute entry
|
||||||
R ^V Run/pick script L Lock terminal
|
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.
|
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_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_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_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 |
|
| `NNN_CP_MV_PROG=1` | show copy, move progress on Linux |
|
||||||
|
|
||||||
#### Help
|
#### Help
|
||||||
|
|
4
nnn.1
4
nnn.1
|
@ -158,8 +158,6 @@ Lock terminal
|
||||||
Show command prompt
|
Show command prompt
|
||||||
.It Ic ^N
|
.It Ic ^N
|
||||||
Take note
|
Take note
|
||||||
.It Ic T
|
|
||||||
Empty trash
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Backing up one directory level will set the cursor position at the
|
Backing up one directory level will set the cursor position at the
|
||||||
|
@ -350,7 +348,7 @@ files.
|
||||||
export NNN_RESTRICT_0B=1
|
export NNN_RESTRICT_0B=1
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.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
|
.Bd -literal
|
||||||
export NNN_TRASH=1
|
export NNN_TRASH=1
|
||||||
.Ed
|
.Ed
|
||||||
|
|
126
src/nnn.c
126
src/nnn.c
|
@ -342,9 +342,6 @@ static char g_buf[CMD_LEN_MAX] __attribute__ ((aligned));
|
||||||
/* Buffer for file path copy file */
|
/* Buffer for file path copy file */
|
||||||
static char g_cppath[PATH_MAX] __attribute__ ((aligned));
|
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 */
|
/* Buffer to store tmp file path */
|
||||||
static char g_tmpfpath[HOME_LEN_MAX] __attribute__ ((aligned));
|
static char g_tmpfpath[HOME_LEN_MAX] __attribute__ ((aligned));
|
||||||
|
|
||||||
|
@ -1122,25 +1119,6 @@ static bool xdiraccess(const char *path)
|
||||||
return TRUE;
|
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)
|
static void cpstr(char *buf)
|
||||||
{
|
{
|
||||||
snprintf(buf, CMD_LEN_MAX,
|
snprintf(buf, CMD_LEN_MAX,
|
||||||
|
@ -1151,26 +1129,18 @@ static void cpstr(char *buf)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mvstr(char *buf, const char *dst)
|
static void mvstr(char *buf)
|
||||||
{
|
{
|
||||||
snprintf(buf, CMD_LEN_MAX,
|
snprintf(buf, CMD_LEN_MAX,
|
||||||
#ifdef __linux__
|
#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
|
#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
|
#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,
|
snprintf(buf, CMD_LEN_MAX,
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
"xargs -0 -a %s rm -%cr",
|
"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",
|
"cat %s | xargs -0 -o rm -%cr",
|
||||||
#endif
|
#endif
|
||||||
g_cppath, confirm_force());
|
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'};
|
char rm_opts[] = {'-', confirm_force(), 'r'};
|
||||||
|
|
||||||
spawn("rm", rm_opts, path, NULL, F_NORMAL | F_SIGINT);
|
spawn("rm", rm_opts, path, NULL, F_NORMAL | F_SIGINT);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void archive_selection(const char *archive, const char *curpath)
|
static void archive_selection(const char *archive, const char *curpath)
|
||||||
|
@ -1232,40 +1188,6 @@ static bool write_lastdir(const char *curpath)
|
||||||
return TRUE;
|
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)
|
static int digit_compare(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
while (*a && *b && *a == *b)
|
while (*a && *b && *a == *b)
|
||||||
|
@ -2435,7 +2357,7 @@ static bool show_help(const char *path)
|
||||||
"1MISC\n"
|
"1MISC\n"
|
||||||
"9! ^] Spawn SHELL C Execute entry\n"
|
"9! ^] Spawn SHELL C Execute entry\n"
|
||||||
"9R ^V Run/pick script L Lock terminal\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])
|
if (g_tmpfpath[0])
|
||||||
xstrlcpy(g_tmpfpath + g_tmpfplen - 1, messages[STR_TMPFILE],
|
xstrlcpy(g_tmpfpath + g_tmpfplen - 1, messages[STR_TMPFILE],
|
||||||
|
@ -3570,11 +3492,10 @@ nochange:
|
||||||
cpstr(g_buf);
|
cpstr(g_buf);
|
||||||
break;
|
break;
|
||||||
case SEL_MV:
|
case SEL_MV:
|
||||||
mvstr(g_buf, ".");
|
mvstr(g_buf);
|
||||||
break;
|
break;
|
||||||
default: /* SEL_RMMUL */
|
default: /* SEL_RMMUL */
|
||||||
if (!rmmulstr(g_buf, path))
|
rmmulstr(g_buf);
|
||||||
goto nochange;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3586,29 +3507,17 @@ nochange:
|
||||||
presel = FILTER;
|
presel = FILTER;
|
||||||
goto begin;
|
goto begin;
|
||||||
}
|
}
|
||||||
case SEL_RM: // fallthrough
|
case SEL_RM:
|
||||||
case SEL_RMTRASH:
|
|
||||||
{
|
{
|
||||||
if (sel == SEL_RM) {
|
|
||||||
if (!ndents)
|
if (!ndents)
|
||||||
break;
|
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 */
|
/* Don't optimize cur if filtering is on */
|
||||||
if (!cfg.filtermode && cur && access(newpath, F_OK) == -1)
|
if (!cfg.filtermode && cur && access(newpath, F_OK) == -1)
|
||||||
--cur;
|
--cur;
|
||||||
} else {
|
|
||||||
r = get_input("Empty trash? [y/Y]");
|
|
||||||
if (!(r == 'y' || r == 'Y'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!empty_trash(path))
|
|
||||||
goto nochange;
|
|
||||||
}
|
|
||||||
|
|
||||||
copycurname();
|
copycurname();
|
||||||
|
|
||||||
|
@ -4149,21 +4058,8 @@ int main(int argc, char *argv[])
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
DPRINTF_S(home);
|
DPRINTF_S(home);
|
||||||
|
|
||||||
if (getenv(env_cfg[NNN_TRASH])) {
|
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;
|
|
||||||
|
|
||||||
cfg.trash = 1;
|
cfg.trash = 1;
|
||||||
}
|
|
||||||
|
|
||||||
/* Prefix for other temporary ops */
|
/* Prefix for other temporary ops */
|
||||||
if (home)
|
if (home)
|
||||||
|
|
|
@ -80,7 +80,6 @@ enum action {
|
||||||
SEL_MV,
|
SEL_MV,
|
||||||
SEL_RMMUL,
|
SEL_RMMUL,
|
||||||
SEL_RM,
|
SEL_RM,
|
||||||
SEL_RMTRASH,
|
|
||||||
SEL_OPENWITH,
|
SEL_OPENWITH,
|
||||||
SEL_NEW,
|
SEL_NEW,
|
||||||
SEL_RENAME,
|
SEL_RENAME,
|
||||||
|
@ -207,8 +206,6 @@ static struct key bindings[] = {
|
||||||
{ 'X', SEL_RMMUL },
|
{ 'X', SEL_RMMUL },
|
||||||
/* Delete currently selected */
|
/* Delete currently selected */
|
||||||
{ CONTROL('X'), SEL_RM },
|
{ CONTROL('X'), SEL_RM },
|
||||||
/* Clear trash */
|
|
||||||
{ 'T', SEL_RMTRASH },
|
|
||||||
/* Open in a custom application */
|
/* Open in a custom application */
|
||||||
{ CONTROL('O'), SEL_OPENWITH },
|
{ CONTROL('O'), SEL_OPENWITH },
|
||||||
/* Create a new file */
|
/* Create a new file */
|
||||||
|
|
Loading…
Reference in a new issue