]> Sergey Matveev's repositories - nnn.git/commitdiff
Fix #532: support picker and list modes together
authorArun Prakash Jana <engineerarun@gmail.com>
Fri, 24 Apr 2020 18:05:43 +0000 (23:35 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Fri, 24 Apr 2020 19:16:25 +0000 (00:46 +0530)
src/nnn.c

index b9bb23c9fc2dc98d90374f1e1552d6e00d18d2f9..fb32aa1485170900df040533977c672e12ffc5c8 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -1141,12 +1141,12 @@ static void appendfpath(const char *path, const size_t len)
 }
 
 /* Write selected file paths to fd, linefeed separated */
-static size_t seltofile(int fd, uint *pcount)
+static size_t seltofile(int fd, uint *pcount, bool tgt)
 {
        uint lastpos, count = 0;
        char *pbuf = pselbuf;
        size_t pos = 0, len;
-       ssize_t r;
+       ssize_t r, prefixlen, initlen, tgtlen;
 
        if (pcount)
                *pcount = 0;
@@ -1156,13 +1156,33 @@ static size_t seltofile(int fd, uint *pcount)
 
        lastpos = selbufpos - 1;
 
+       if (tgt) {
+               prefixlen = (ssize_t)xstrsncpy(g_buf, prefixpath, PATH_MAX) - 1;
+               initlen = strlen(initpath);
+       }
+
        while (pos <= lastpos) {
                len = xstrlen(pbuf);
                pos += len;
 
-               r = write(fd, pbuf, len);
-               if (r != (ssize_t)len)
-                       return pos;
+               if (!tgt) {
+                       r = write(fd, pbuf, len);
+                       if (r != (ssize_t)len)
+                               return pos;
+               } else {
+                       if (!strncmp(initpath, pbuf, initlen)) {
+                               tgtlen = xstrsncpy(g_buf + prefixlen, pbuf + initlen, PATH_MAX - prefixlen - 1);
+                               tgtlen += prefixlen - 1;
+                       } else
+                               tgtlen = (ssize_t)xstrsncpy(g_buf, pbuf, PATH_MAX) - 1;
+
+                       r = write(fd, g_buf, tgtlen);
+                       if (r != tgtlen) {
+                               DPRINTF_S(pbuf);
+                               DPRINTF_S(g_buf);
+                               return 0;
+                       }
+               }
 
                if (pos <= lastpos) {
                        if (write(fd, "\n", 1) != 1)
@@ -1251,7 +1271,7 @@ static void endselection(void)
                return;
        }
 
-       seltofile(fd, NULL);
+       seltofile(fd, NULL, FALSE);
        if (close(fd)) {
                DPRINTF_S(strerror(errno));
                printwarn(NULL);
@@ -1323,7 +1343,7 @@ static int editselection(void)
                return -1;
        }
 
-       seltofile(fd, NULL);
+       seltofile(fd, NULL, FALSE);
        if (close(fd)) {
                DPRINTF_S(strerror(errno));
                return -1;
@@ -1794,7 +1814,7 @@ static bool cpmv_rename(int choice, const char *path)
                if (!count)
                        goto finish;
        } else
-               seltofile(fd, &count);
+               seltofile(fd, &count, FALSE);
 
        close(fd);
 
@@ -1904,8 +1924,8 @@ static bool batch_rename(const char *path)
                for (i = 0; i < ndents; ++i)
                        appendfpath(dents[i].name, NAME_MAX);
 
-       seltofile(fd1, &count);
-       seltofile(fd2, NULL);
+       seltofile(fd1, &count, FALSE);
+       seltofile(fd2, NULL, FALSE);
        close(fd2);
 
        if (dir) /* Don't retain dir entries in selection */
@@ -6742,9 +6762,13 @@ int main(int argc, char *argv[])
                                break;
 
                        cfg.picker = 1;
-                       if (optarg[0] == '-' && optarg[1] == '\0')
+                       if (optarg[0] == '-' && optarg[1] == '\0') {
                                cfg.pickraw = 1;
-                       else {
+                               if (!isatty(STDOUT_FILENO)) {
+                                       fprintf(stderr, "stdout !tty\n");
+                                       return _FAILURE;
+                               }
+                       } else {
                                int fd = open(optarg, O_WRONLY | O_CREAT, 0600);
 
                                if (fd == -1) {
@@ -6810,27 +6834,17 @@ int main(int argc, char *argv[])
 
        atexit(cleanup);
 
-       if (!cfg.picker) {
-               /* Confirm we are in a terminal */
-               if (!isatty(STDOUT_FILENO))
-                       exit(1);
-
-               /* Now we are in path list mode */
-               if (!isatty(STDIN_FILENO)) {
-                       /* This is the same as listpath */
-                       initpath = load_input();
-                       if (!initpath)
-                               exit(1);
-
-                       /* We return to tty */
-                       dup2(STDOUT_FILENO, STDIN_FILENO);
+       /* Check if we are in path list mode */
+       if (!isatty(STDIN_FILENO)) {
+               /* This is the same as listpath */
+               initpath = load_input();
+               if (!initpath) {
+                       fprintf(stderr, "!initpath\n");
+                       return _FAILURE;
                }
-       }
 
-       /* Prevent picker and list mode conflict */
-       if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) {
-               fprintf(stderr, "stdin/out conflict\n");
-               return _FAILURE;
+               /* We return to tty */
+               dup2(STDOUT_FILENO, STDIN_FILENO);
        }
 
        home = getenv("HOME");
@@ -7015,9 +7029,6 @@ int main(int argc, char *argv[])
        mousemask(mask, NULL);
 #endif
 
-       if (listpath)
-               spawn("rm -rf", initpath, NULL, NULL, F_SILENT);
-
        exitcurses();
 
 #ifndef NORL
@@ -7027,15 +7038,23 @@ int main(int argc, char *argv[])
        }
 #endif
 
-       if (cfg.pickraw) {
-               if (selbufpos && (seltofile(1, NULL) != (size_t)(selbufpos)))
-                       xerror();
-       } else if (cfg.picker) {
-               if (selbufpos)
-                       writesel(pselbuf, selbufpos - 1);
+       if (cfg.pickraw || cfg.picker) {
+               if (selbufpos) {
+                       int fd = cfg.pickraw ? 1 : open(selpath, O_WRONLY | O_CREAT, 0600);
+
+                       if ((fd == -1) || (seltofile(fd, NULL, TRUE) != (size_t)(selbufpos)))
+                               xerror();
+
+                       if (fd > 1)
+                               close(fd);
+               }
        } else if (selpath)
                unlink(selpath);
 
+       /* Remove tmp dir in list mode */
+       if (listpath)
+               spawn("rm -rf", initpath, NULL, NULL, F_NOTRACE | F_MULTI);
+
        /* Free the regex */
 #ifdef PCRE
        pcre_free(archive_pcre);