mirror of
https://github.com/jarun/nnn.git
synced 2024-12-01 02:49:44 +00:00
parent
2c2d497809
commit
93a2d174f0
|
@ -105,7 +105,7 @@ It runs on Linux, macOS, Raspberry Pi, BSD, Cygwin, Linux subsystem for Windows
|
||||||
- FreeDesktop compliant trash (needs trash-cli)
|
- FreeDesktop compliant trash (needs trash-cli)
|
||||||
- Plugin repository
|
- Plugin repository
|
||||||
- SSHFS mounts (needs sshfs)
|
- SSHFS mounts (needs sshfs)
|
||||||
- Batch rename (needs vidir)
|
- Batch rename
|
||||||
- Show copy, move progress on Linux (needs avdcpmv)
|
- Show copy, move progress on Linux (needs avdcpmv)
|
||||||
- Per-context directory color (default: blue)
|
- Per-context directory color (default: blue)
|
||||||
- Spawn a shell in the current directory
|
- Spawn a shell in the current directory
|
||||||
|
@ -139,7 +139,6 @@ The following table is a complete list. Some of the utilities may be installed b
|
||||||
| trash-cli | trash files (default: delete) |
|
| trash-cli | trash files (default: delete) |
|
||||||
| mediainfo / exiftool | multimedia file details |
|
| mediainfo / exiftool | multimedia file details |
|
||||||
| atool / bsdtar / patool ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#integrate-patool)) | create, list and extract archives |
|
| atool / bsdtar / patool ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#integrate-patool)) | create, list and extract archives |
|
||||||
| vidir (from moreutils) | batch rename dir entries |
|
|
||||||
| sshfs, fusermount(3) | mount, unmount remote over SSHFS |
|
| sshfs, fusermount(3) | mount, unmount remote over SSHFS |
|
||||||
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | terminal locker |
|
| vlock (Linux), bashlock (macOS), lock(1) (BSD) | terminal locker |
|
||||||
| advcpmv (Linux) ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#show-cp-mv-progress)) | copy, move progress |
|
| advcpmv (Linux) ([integration](https://github.com/jarun/nnn/wiki/hacking-nnn#show-cp-mv-progress)) | copy, move progress |
|
||||||
|
|
86
src/nnn.c
86
src/nnn.c
|
@ -334,10 +334,9 @@ static char g_tmpfpath[TMP_LEN_MAX] __attribute__ ((aligned));
|
||||||
#define OPENER 2
|
#define OPENER 2
|
||||||
#define ATOOL 3
|
#define ATOOL 3
|
||||||
#define BSDTAR 4
|
#define BSDTAR 4
|
||||||
#define VIDIR 5
|
#define LOCKER 5
|
||||||
#define LOCKER 6
|
#define NLAUNCH 6
|
||||||
#define NLAUNCH 7
|
#define UNKNOWN 7
|
||||||
#define UNKNOWN 8
|
|
||||||
|
|
||||||
/* Utilities to open files, run actions */
|
/* Utilities to open files, run actions */
|
||||||
static char * const utils[] = {
|
static char * const utils[] = {
|
||||||
|
@ -352,7 +351,6 @@ static char * const utils[] = {
|
||||||
#endif
|
#endif
|
||||||
"atool",
|
"atool",
|
||||||
"bsdtar",
|
"bsdtar",
|
||||||
"vidir",
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
"bashlock",
|
"bashlock",
|
||||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
@ -1123,6 +1121,80 @@ static void xrm(char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rename_selection(const char *path)
|
||||||
|
{
|
||||||
|
const char renamecmd[] = "paste -d'\n' %s %s | xargs -d'\n' -n2 mv 2>/dev/null";
|
||||||
|
char buf[sizeof(renamecmd) + 2 * PATH_MAX];
|
||||||
|
char foriginal[TMP_LEN_MAX] = {0};
|
||||||
|
int fd1 = -1, fd2 = -1, i;
|
||||||
|
ssize_t len, len2;
|
||||||
|
|
||||||
|
if ((fd1 = create_tmp_file()) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xstrlcpy(foriginal, g_tmpfpath, strlen(g_tmpfpath)+1);
|
||||||
|
|
||||||
|
if ((fd2 = create_tmp_file()) == -1) {
|
||||||
|
unlink(foriginal);
|
||||||
|
close(fd1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copybufpos > 0) {
|
||||||
|
// Rename selected files with absolute paths:
|
||||||
|
selectiontofd(fd1);
|
||||||
|
if (write(fd1, "\n", 1) < 1)
|
||||||
|
goto finished_renaming;
|
||||||
|
selectiontofd(fd2);
|
||||||
|
if (write(fd2, "\n", 1) < 1)
|
||||||
|
goto finished_renaming;
|
||||||
|
} else {
|
||||||
|
// If nothing is selected, use the directory contents with relative paths:
|
||||||
|
for (i = 0; i < ndents; ++i) {
|
||||||
|
len = strlen(dents[i].name);
|
||||||
|
if (write(fd1, dents[i].name, len) != len || write(fd1, "\n", 1) != 1)
|
||||||
|
goto finished_renaming;
|
||||||
|
if (write(fd2, dents[i].name, len) != len || write(fd2, "\n", 1) != 1)
|
||||||
|
goto finished_renaming;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd2);
|
||||||
|
fd2 = -1;
|
||||||
|
|
||||||
|
spawn(editor, g_tmpfpath, NULL, path, F_CLI);
|
||||||
|
|
||||||
|
// Check that the number of filenames is unchanged:
|
||||||
|
len = 0, len2 = 0;
|
||||||
|
lseek(fd1, 0, SEEK_SET);
|
||||||
|
while ((i = read(fd1, buf, sizeof(buf))) > 0) {
|
||||||
|
while (i) len += buf[--i] == '\n';
|
||||||
|
}
|
||||||
|
if (i < 0) goto finished_renaming;
|
||||||
|
|
||||||
|
// Reopen file descriptor to get updated contents:
|
||||||
|
if ((fd2 = open(g_tmpfpath, O_RDONLY)) == -1)
|
||||||
|
goto finished_renaming;
|
||||||
|
while ((i = read(fd2, buf, sizeof(buf))) > 0) {
|
||||||
|
while (i) len2 += buf[--i] == '\n';
|
||||||
|
}
|
||||||
|
if (i < 0) goto finished_renaming;
|
||||||
|
|
||||||
|
if (len2 != len) {
|
||||||
|
get_input("Error: wrong number of filenames. Press any key to continue...");
|
||||||
|
goto finished_renaming;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), renamecmd, foriginal, g_tmpfpath);
|
||||||
|
spawn("sh", "-c", buf, path, F_NORMAL);
|
||||||
|
|
||||||
|
finished_renaming:
|
||||||
|
if (fd2 >= 0) close(fd1);
|
||||||
|
unlink(foriginal);
|
||||||
|
if (fd2 >= 0) close(fd2);
|
||||||
|
unlink(g_tmpfpath);
|
||||||
|
}
|
||||||
|
|
||||||
static void archive_selection(const char *cmd, const char *archive, const char *curpath)
|
static void archive_selection(const char *cmd, const char *archive, const char *curpath)
|
||||||
{
|
{
|
||||||
snprintf(g_buf, CMD_LEN_MAX,
|
snprintf(g_buf, CMD_LEN_MAX,
|
||||||
|
@ -3619,9 +3691,7 @@ nochange:
|
||||||
copycurname();
|
copycurname();
|
||||||
goto begin;
|
goto begin;
|
||||||
case SEL_RENAMEALL:
|
case SEL_RENAMEALL:
|
||||||
r = getutil(utils[VIDIR]);
|
rename_selection(path);
|
||||||
if (r)
|
|
||||||
spawn(utils[VIDIR], ".", NULL, path, F_NORMAL);
|
|
||||||
break;
|
break;
|
||||||
case SEL_HELP:
|
case SEL_HELP:
|
||||||
r = show_help(path);
|
r = show_help(path);
|
||||||
|
|
Loading…
Reference in a new issue