aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-05-22 20:32:29 +0530
committerGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-05-22 20:51:53 +0530
commit6ce511cddb8b05e6db1ee0764de63fbea253d589 (patch)
tree110ceff539be3666c97d063c34cf77cac818cfc7 /src
parent93a2d174f050c3e81e5d194d3dbdc5557340c808 (diff)
downloadnnn-6ce511cddb8b05e6db1ee0764de63fbea253d589.tar.gz
Simplify batch rename
Diffstat (limited to 'src')
-rw-r--r--src/nnn.c110
1 files changed, 63 insertions, 47 deletions
diff --git a/src/nnn.c b/src/nnn.c
index 1a106ce..75201d5 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -769,12 +769,20 @@ static void appendfpath(const char *path, const size_t len)
}
/* Write selected file paths to fd, linefeed separated */
-static ssize_t selectiontofd(int fd)
+static ssize_t selectiontofd(int fd, uint *pcount)
{
- uint lastpos = copybufpos - 1;
+ uint lastpos, count = 0;
char *pbuf = pcopybuf;
ssize_t pos = 0, len, r;
+ if (pcount)
+ *pcount = 0;
+
+ if (!copybufpos)
+ return 0;
+
+ lastpos = copybufpos - 1;
+
while (pos <= lastpos) {
len = strlen(pbuf);
pos += len;
@@ -789,8 +797,12 @@ static ssize_t selectiontofd(int fd)
pbuf += len + 1;
}
++pos;
+ ++count;
}
+ if (pcount)
+ *pcount = count;
+
return pos;
}
@@ -808,7 +820,7 @@ static void showcplist(void)
return;
}
- pos = selectiontofd(fd);
+ pos = selectiontofd(fd, NULL);
close(fd);
if (pos && pos == copybufpos)
@@ -1121,78 +1133,79 @@ static void xrm(char *path)
}
}
-static void rename_selection(const char *path)
+static bool batch_rename(const char *path)
{
+ int fd1 = -1, fd2 = -1, i;
+ uint count = 0, lines = 0;
+ bool dir = FALSE, ret = FALSE;
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;
+ char buf[sizeof(renamecmd) + (PATH_MAX << 1)];
if ((fd1 = create_tmp_file()) == -1)
- return;
+ return ret;
xstrlcpy(foriginal, g_tmpfpath, strlen(g_tmpfpath)+1);
if ((fd2 = create_tmp_file()) == -1) {
unlink(foriginal);
close(fd1);
- return;
+ return ret;
}
- 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;
- }
+ if (!copybufpos) {
+ if (!ndents)
+ return TRUE;
+
+ for (i = 0; i < ndents; ++i)
+ appendfpath(dents[i].name, NAME_MAX);
+
+ dir = TRUE;
}
+ selectiontofd(fd1, &count);
+ selectiontofd(fd2, NULL);
close(fd2);
- fd2 = -1;
- spawn(editor, g_tmpfpath, NULL, path, F_CLI);
+ if (dir)
+ copybufpos = 0;
- // 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;
+ spawn(editor, g_tmpfpath, NULL, path, F_CLI);
// Reopen file descriptor to get updated contents:
if ((fd2 = open(g_tmpfpath, O_RDONLY)) == -1)
- goto finished_renaming;
+ goto finish;
+
while ((i = read(fd2, buf, sizeof(buf))) > 0) {
- while (i) len2 += buf[--i] == '\n';
+ while (i)
+ lines += (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;
+ if (i < 0)
+ goto finish;
+
+ DPRINTF_U(count);
+ DPRINTF_U(lines);
+
+ if (count != lines) {
+ DPRINTF_S("cannot delete files");
+ goto finish;
}
snprintf(buf, sizeof(buf), renamecmd, foriginal, g_tmpfpath);
spawn("sh", "-c", buf, path, F_NORMAL);
+ ret = TRUE;
-finished_renaming:
- if (fd2 >= 0) close(fd1);
+finish:
+ if (fd1 >= 0)
+ close(fd1);
unlink(foriginal);
- if (fd2 >= 0) close(fd2);
+
+ if (fd2 >= 0)
+ close(fd2);
unlink(g_tmpfpath);
+
+ return ret;
}
static void archive_selection(const char *cmd, const char *archive, const char *curpath)
@@ -3659,12 +3672,12 @@ nochange:
case SEL_FMEDIA: // fallthrough
case SEL_ARCHIVELS: // fallthrough
case SEL_EXTRACT: // fallthrough
- case SEL_RENAMEALL: // fallthrough
case SEL_RUNEDIT: // fallthrough
case SEL_RUNPAGE:
if (!ndents)
break; // fallthrough
case SEL_REDRAW: // fallthrough
+ case SEL_RENAMEALL: // fallthrough
case SEL_HELP: // fallthrough
case SEL_NOTE: // fallthrough
case SEL_LOCK:
@@ -3691,7 +3704,10 @@ nochange:
copycurname();
goto begin;
case SEL_RENAMEALL:
- rename_selection(path);
+ if (!batch_rename(path)) {
+ printwait("batch rename failed", &presel);
+ goto nochange;
+ }
break;
case SEL_HELP:
r = show_help(path);
@@ -4635,7 +4651,7 @@ int main(int argc, char *argv[])
if (cfg.pickraw) {
if (copybufpos) {
- opt = selectiontofd(1);
+ opt = selectiontofd(1, NULL);
if (opt != (int)(copybufpos))
xerror();
}