]> Sergey Matveev's repositories - nnn.git/commitdiff
handle script dir with NNN_SCRIPT
authorArun Prakash Jana <engineerarun@gmail.com>
Sat, 15 Dec 2018 18:54:45 +0000 (00:24 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Sat, 15 Dec 2018 18:54:45 +0000 (00:24 +0530)
README.md
nnn.1
src/nnn.c

index e68a047974ef0b7fade9de3baff05c021559a139..8072c0c4cc7b2ec06dd294a930715e277efd3823 100644 (file)
--- a/README.md
+++ b/README.md
@@ -137,7 +137,7 @@ Stripped binary (or script) size and memory usage of `nnn` and some other simila
 <b>   1M</b>   50496  <b>15328</b>   4076 S   0.2   vifm
 <b>   1M</b>   72152  <b>12468</b>   7336 S   0.2   mc
 <b>  70K</b>   16068  <b> 4620</b>   2408 S   0.1   ncdu
-<b>  52K</b>   15720  <b> 4200</b>   2344 S   0.1   nnn -S
+<b>  55K</b>   15720  <b> 4200</b>   2344 S   0.1   nnn -S
 </pre>
 
 Intrigued? Find out [HOW](https://github.com/jarun/nnn/wiki/performance-factors).
@@ -467,25 +467,13 @@ As you might notice, `nnn` uses the environment variable `NNN_TMPFILE` to write
 
 `nnn` can invoke custom scripts with the currently selected file name as argument 1.
 
-Export the path to the custom executable script:
+Export the absolute path to the directory with your scripts or a single script:
 
-    export NNN_SCRIPT=/usr/local/bin/nscript
+    export NNN_SCRIPT=/home/user/scripts
+    OR
+    export NNN_SCRIPT=/usr/local/bin/nscript.sh
 
-Press <kbd>R</kbd> to run the script in the current directory.
-
-It's possible to run multiple scripts with `nnn` as long as the scripts are in the same location and share the same prefix. To enable multiple scripts,
-
-    export NNN_MULTISCRIPT=1
-
-With the example of `NNN_SCRIPT` above, some more scripts could be:
-
-    /usr/local/bin/nscript1
-    /usr/local/bin/nscript2
-    /usr/local/bin/nscriptcustom1
-    /usr/local/bin/nscriptcustom2
-    and so on...
-
-Type the correct suffix  when prompted on pressing the keybind <kbd>R</kbd>. To use the base script (`NNN_SCRIPT`), just press <kbd>Enter</kbd>.
+Press <kbd>R</kbd> to run the script in the current directory. You can also use this key to cancel choosing a script from the script directory.
 
 ##### sample scripts
 
diff --git a/nnn.1 b/nnn.1
index b411f67cafb540829936cb50c7656474d976ca48..2875bed3e59ce107db71a6a7bd4c1ebfc4bf36dd 100644 (file)
--- a/nnn.1
+++ b/nnn.1
@@ -150,7 +150,7 @@ Launch an application (takes 2 combined arguments)
 .It Ic ^S
 Run a command
 .It Ic R
-Run a custom script
+Run or choose a custom script
 .It Ic C
 Execute entry
 .It Ic L
@@ -301,14 +301,11 @@ files.
     The path is shown in the help and configuration screen.
 .Ed
 .Pp
-\fBNNN_SCRIPT:\fR path to a custom script to invoke with currently selected file name as argument 1.
+\fBNNN_SCRIPT:\fR absolute path to a directory to select a script from or a single script to invoke with currently selected file name as argument 1.
 .Bd -literal
-    export NNN_SCRIPT=/usr/local/bin/nscript
-.Ed
-.Pp
-\fBNNN_MULTISCRIPT:\fR run multiple custom scripts (default: disabled).
-.Bd -literal
-    export NNN_MULTISCRIPT=1
+    export NNN_SCRIPT=/home/user/scripts
+    OR
+    export NNN_SCRIPT=/usr/local/bin/nscript.sh
 .Ed
 .Pp
 \fBNNN_SHOW_HIDDEN:\fR show hidden files.
index ffae7cbb2a2e666b89360ef01a1fd2d47555fd1b..5778bb54d5b4afd1bed7d8a7243f9b2d7dd811d1 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -259,13 +259,15 @@ typedef struct {
        uint dircolor   : 1;  /* Current status of dir color */
        uint metaviewer : 1;  /* Index of metadata viewer in utils[] */
        uint ctxactive  : 1;  /* Context active or not */
-       uint reserved   : 13;
+       uint reserved   : 10;
        /* The following settings are global */
        uint curctx     : 2;  /* Current context number */
        uint picker     : 1;  /* Write selection to user-specified file */
        uint pickraw    : 1;  /* Write selection to sdtout before exit */
        uint nonavopen  : 1;  /* Open file on right arrow or `l` */
        uint useeditor  : 1;  /* Use VISUAL to open text files */
+       uint runscript  : 1;  /* Choose script to run mode */
+       uint runctx     : 2;  /* The context in which script is to be run */
 } settings;
 
 /* Contexts or workspaces */
@@ -281,7 +283,7 @@ typedef struct {
 /* GLOBALS */
 
 /* Configuration, contexts */
-static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0};
+static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
 static context g_ctx[CTX_MAX] __attribute__ ((aligned));
 
 static struct entry *dents;
@@ -2105,8 +2107,6 @@ static bool show_help(char *path)
                dprintf(fd, "copy file: %s\n", g_cppath);
        if (getenv("NNN_SCRIPT"))
                dprintf(fd, "NNN_SCRIPT: %s\n", getenv("NNN_SCRIPT"));
-       if (getenv("NNN_MULTISCRIPT"))
-               dprintf(fd, "NNN_MULTISCRIPT: 1\n");
        if (getenv("NNN_SHOW_HIDDEN"))
                dprintf(fd, "NNN_SHOW_HIDDEN: 1\n");
        if (getenv("NNN_NO_AUTOSELECT"))
@@ -2537,6 +2537,8 @@ static void browse(char *ipath)
 {
        static char newpath[PATH_MAX] __attribute__ ((aligned));
        static char mark[PATH_MAX] __attribute__ ((aligned));
+       static char rundir[PATH_MAX] __attribute__ ((aligned));
+       static char runfile[NAME_MAX + 1] __attribute__ ((aligned));
        char *path, *lastdir, *lastname;
        char *dir, *tmp;
        struct stat sb;
@@ -2549,6 +2551,7 @@ static void browse(char *ipath)
        path = g_ctx[0].c_path;
        xstrlcpy(g_ctx[0].c_init, ipath, PATH_MAX); /* start directory */
        g_ctx[0].c_last[0] = g_ctx[0].c_name[0] = newpath[0] = mark[0] = '\0';
+       rundir[0] = runfile[0] = '\0';
        lastdir = g_ctx[0].c_last; /* last visited directory */
        lastname = g_ctx[0].c_name; /* last visited filename */
        g_ctx[0].c_cfg = cfg; /* current configuration */
@@ -2687,6 +2690,28 @@ nochange:
                                if (cfg.nonavopen && sel == SEL_NAV_IN)
                                        continue;
 
+                               /* Handle script selection mode */
+                               if (cfg.runscript) {
+                                       if (cfg.runctx != cfg.curctx)
+                                               continue;
+
+                                       if (!getenv("NNN_SCRIPT") || strcmp(path, getenv("NNN_SCRIPT")) != 0)
+                                               continue;
+
+                                       mkpath(path, dents[cur].name, newpath, PATH_MAX);
+                                       xstrlcpy(path, rundir, PATH_MAX);
+                                       if (runfile[0]) {
+                                               xstrlcpy(lastname, runfile, NAME_MAX);
+                                               spawn(shell, newpath, lastname, path, F_NORMAL | F_SIGINT);
+                                               runfile[0] = '\0';
+                                       } else
+                                               spawn(shell, newpath, NULL, path, F_NORMAL | F_SIGINT);
+                                       rundir[0] = '\0';
+                                       cfg.runscript = 0;
+                                       setdirwatch();
+                                       goto begin;
+                               }
+
                                /* If NNN_USE_EDITOR is set, open text in EDITOR */
                                if (cfg.useeditor &&
                                    get_output(g_buf, CMD_LEN_MAX, "file", FILE_OPTS, newpath, FALSE) &&
@@ -2749,7 +2774,6 @@ nochange:
 
                        /* Save last working directory */
                        xstrlcpy(lastdir, path, PATH_MAX);
-
                        xstrlcpy(path, dir, PATH_MAX);
                        lastname[0] = '\0';
                        DPRINTF_S(path);
@@ -2840,6 +2864,7 @@ nochange:
                                        g_ctx[r].c_last[0] = '\0';
                                        xstrlcpy(g_ctx[r].c_name, dents[cur].name, NAME_MAX + 1);
                                        g_ctx[r].c_cfg = cfg;
+                                       g_ctx[r].c_cfg.runscript = 0;
                                }
 
                                /* Reset the pointers */
@@ -3390,36 +3415,51 @@ nochange:
                                mkpath(path, dents[cur].name, newpath, PATH_MAX);
                                spawn(newpath, NULL, NULL, path, F_NORMAL | F_SIGINT);
                        } else if (sel == SEL_SCRIPT) {
-                               tmp = getenv("NNN_SCRIPT");
-                               if (!tmp) {
+                               dir = getenv("NNN_SCRIPT");
+                               if (!dir) {
                                        printmsg("set NNN_SCRIPT");
                                        goto nochange;
                                }
 
-                               if (getenv("NNN_MULTISCRIPT")) {
-                                       size_t _len = xstrlcpy(newpath, tmp, PATH_MAX);
-
-                                       tmp = xreadline(NULL, "script suffix: ");
-                                       if (tmp && tmp[0])
-                                               xstrlcpy(newpath + _len - 1, tmp, PATH_MAX - _len);
-                                       tmp = newpath;
-                               }
-
-                               if (lstat(tmp, &sb) == -1) {
+                               if (stat(dir, &sb) == -1) {
                                        printwarn();
                                        goto nochange;
                                }
 
-                               /* Check if it's a directory */
-                               if (S_ISDIR(sb.st_mode)) {
-                                       printmsg("directory");
-                                       goto nochange;
-                               }
+                               if (!S_ISDIR(sb.st_mode)) {
+                                       if (ndents)
+                                               tmp = dents[cur].name;
+                                       else
+                                               tmp = NULL;
+                                       spawn(shell, dir, tmp, path, F_NORMAL | F_SIGINT);
+                               } else {
+                                       cfg.runscript ^= 1;
+                                       if (!cfg.runscript && rundir[0]) {
+                                               /* If reset, switch to original dir */
+                                               if (strcmp(path, getenv("NNN_SCRIPT")) == 0) {
+                                                       xstrlcpy(path, rundir, PATH_MAX);
+                                                       xstrlcpy(lastname, runfile, NAME_MAX);
+                                                       rundir[0] = '\0';
+                                                       runfile[0] = '\0';
+                                                       setdirwatch();
+                                                       goto begin;
+                                               }
+                                               break;
+                                       }
 
-                               dir = NULL; /* dir used as temp var */
-                               if (ndents)
-                                       dir = dents[cur].name;
-                               spawn(shell, tmp, dir, path, F_NORMAL | F_SIGINT);
+                                       /* Check if directory is accessible */
+                                       if (!xdiraccess(dir))
+                                               goto nochange;
+
+                                       xstrlcpy(rundir, path, PATH_MAX);
+                                       xstrlcpy(path, dir, PATH_MAX);
+                                       if (ndents)
+                                               xstrlcpy(runfile, dents[cur].name, NAME_MAX);
+                                       cfg.runctx = cfg.curctx;
+                                       lastname[0] = '\0';
+                                       setdirwatch();
+                                       goto begin;
+                               }
                        } else if (sel == SEL_RUNCMD) {
                                tmp = xreadline(NULL, "> ");
                                if (tmp && tmp[0])