]> Sergey Matveev's repositories - nnn.git/commitdiff
Support in-place file rename
authorArun Prakash Jana <engineerarun@gmail.com>
Tue, 22 Aug 2017 19:16:58 +0000 (00:46 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Tue, 22 Aug 2017 19:21:59 +0000 (00:51 +0530)
README.md
config.h
nnn.1
nnn.c

index 53605c9673f02b649e737322aa86f606519a1403..325dd987701b23df68e59b669022c1f1cfb9a958 100644 (file)
--- a/README.md
+++ b/README.md
@@ -210,6 +210,7 @@ To cook yourself, download the [latest stable release](https://github.com/jarun/
               D | Show current file details
               m | Show concise media info
               M | Show full media info
+             ^R | Rename selected entry
               s | Toggle sort by file size
               S | Toggle disk usage mode
               t | Toggle sort by mtime
index 275de033c56469c6f5aae326fc0accb04c2e1dfd..31ea672cab8357071b76995b4ae95b15da596743 100644 (file)
--- a/config.h
+++ b/config.h
@@ -34,6 +34,7 @@ enum action {
        SEL_MTIME,
        SEL_REDRAW,
        SEL_COPY,
+       SEL_RENAME,
        SEL_HELP,
        SEL_RUN,
        SEL_RUNARG,
@@ -140,6 +141,8 @@ static struct key bindings[] = {
        { KEY_F(2),       SEL_REDRAW,    "",     "" },
        /* Copy currently selected file path */
        { CONTROL('K'),   SEL_COPY,      "",     "" },
+       /* Show rename prompt */
+       { CONTROL('R'),   SEL_RENAME,    "",     "" },
        /* Show help */
        { '?',            SEL_HELP,      "",     "" },
        /* Run command */
diff --git a/nnn.1 b/nnn.1
index 7cece0d151aed4b228d4f90936a3b8bbbc9576b0..7e91970ac5ef5f0dc200ee1dff26a31d465bc8fc 100644 (file)
--- a/nnn.1
+++ b/nnn.1
@@ -75,6 +75,8 @@ Show current file details screen
 Show concise media info
 .It Ic M
 Show full media info
+.It Ic ^R
+Rename selected entry
 .It Ic s
 Toggle sort by file size
 .It Ic S
diff --git a/nnn.c b/nnn.c
index 816bbfb0b328c8e92a2b213ecd22d30f7a07f7e5..c8de442a2bab0436d3b1b4e21347dde376563050 100644 (file)
--- a/nnn.c
+++ b/nnn.c
@@ -1541,6 +1541,7 @@ show_help(char *path)
              "eD | Show current file details\n"
              "em | Show concise media info\n"
              "eM | Show full media info\n"
+            "d^R | Rename selected entry\n"
              "es | Toggle sort by file size\n"
              "eS | Toggle disk usage mode\n"
              "et | Toggle sort by mtime\n"
@@ -2322,7 +2323,7 @@ nochange:
                        tmp = readinput();
                        clearprompt();
                        if (tmp == NULL)
-                               goto nochange;
+                               break;
 
                        for (r = 0; bookmark[r].key && r < MAX_BM; ++r) {
                                if (xstrcmp(bookmark[r].key, tmp) == -1)
@@ -2389,9 +2390,6 @@ nochange:
                                mkpath(path, dents[cur].name, oldpath, PATH_MAX);
                        goto begin;
                case SEL_STATS:
-               {
-                       struct stat sb;
-
                        if (ndents > 0) {
                                mkpath(path, dents[cur].name, oldpath, PATH_MAX);
 
@@ -2403,14 +2401,12 @@ nochange:
                                } else {
                                        r = show_stats(oldpath, dents[cur].name, &sb);
                                        if (r < 0) {
-                                               printmsg(strerror(errno));
+                                               printwarn();
                                                goto nochange;
                                        }
                                }
                        }
-
                        break;
-               }
                case SEL_MEDIA: // fallthrough
                case SEL_FMEDIA:
                        if (ndents > 0) {
@@ -2475,6 +2471,59 @@ nochange:
                        } else if (!copier)
                                printmsg("NNN_COPIER is not set");
                        goto nochange;
+               case SEL_RENAME:
+                       if (ndents <= 0)
+                               break;
+
+                       printprompt("rename to: ");
+                       tmp = readinput();
+                       clearprompt();
+                       if (tmp == NULL)
+                               break;
+
+                       /* Allow only relative paths */
+                       if (tmp[0] == '/' || basename(tmp) != tmp) {
+                               printmsg("relative paths only");
+                               goto nochange;
+                       }
+
+                       /* Skip renaming to same name */
+                       if (xstrcmp(tmp, dents[cur].name) == 0)
+                               break;
+
+                       /* Open the descriptor to currently open directory */
+                       fd = open(path, O_RDONLY | O_DIRECTORY | O_NOATIME);
+                       if (fd == -1) {
+                               printwarn();
+                               goto nochange;
+                       }
+
+                       /* Check if another file with same name exists */
+                       if (faccessat(fd, tmp, F_OK, AT_SYMLINK_NOFOLLOW) != -1) {
+                               /* File with the same name exists */
+                               xstrlcpy(g_buf, tmp, NAME_MAX);
+
+                               printprompt("overwrite? (y): ");
+                               tmp = readinput();
+                               if (tmp == NULL || tmp[0] != 'y' || tmp[1] != '\0') {
+                                       close(fd);
+                                       break;
+                               }
+
+                               tmp = g_buf;
+                       }
+
+                       /* Rename the file */
+                       r = renameat(fd, dents[cur].name, fd, tmp);
+                       if (r != 0) {
+                               printwarn();
+                               close(fd);
+                               goto nochange;
+                       }
+
+                       close(fd);
+                       mkpath(path, tmp, oldpath, PATH_MAX);
+                       goto begin;
                case SEL_HELP:
                        show_help(path);
                        break;