mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
handle script dir with NNN_SCRIPT
This commit is contained in:
parent
64efd6528c
commit
94ae45b391
24
README.md
24
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> 50496 <b>15328</b> 4076 S 0.2 vifm
|
||||||
<b> 1M</b> 72152 <b>12468</b> 7336 S 0.2 mc
|
<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> 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>
|
</pre>
|
||||||
|
|
||||||
Intrigued? Find out [HOW](https://github.com/jarun/nnn/wiki/performance-factors).
|
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.
|
`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.
|
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.
|
||||||
|
|
||||||
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>.
|
|
||||||
|
|
||||||
##### sample scripts
|
##### sample scripts
|
||||||
|
|
||||||
|
|
13
nnn.1
13
nnn.1
|
@ -150,7 +150,7 @@ Launch an application (takes 2 combined arguments)
|
||||||
.It Ic ^S
|
.It Ic ^S
|
||||||
Run a command
|
Run a command
|
||||||
.It Ic R
|
.It Ic R
|
||||||
Run a custom script
|
Run or choose a custom script
|
||||||
.It Ic C
|
.It Ic C
|
||||||
Execute entry
|
Execute entry
|
||||||
.It Ic L
|
.It Ic L
|
||||||
|
@ -301,14 +301,11 @@ files.
|
||||||
The path is shown in the help and configuration screen.
|
The path is shown in the help and configuration screen.
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.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
|
.Bd -literal
|
||||||
export NNN_SCRIPT=/usr/local/bin/nscript
|
export NNN_SCRIPT=/home/user/scripts
|
||||||
.Ed
|
OR
|
||||||
.Pp
|
export NNN_SCRIPT=/usr/local/bin/nscript.sh
|
||||||
\fBNNN_MULTISCRIPT:\fR run multiple custom scripts (default: disabled).
|
|
||||||
.Bd -literal
|
|
||||||
export NNN_MULTISCRIPT=1
|
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
\fBNNN_SHOW_HIDDEN:\fR show hidden files.
|
\fBNNN_SHOW_HIDDEN:\fR show hidden files.
|
||||||
|
|
88
src/nnn.c
88
src/nnn.c
|
@ -259,13 +259,15 @@ typedef struct {
|
||||||
uint dircolor : 1; /* Current status of dir color */
|
uint dircolor : 1; /* Current status of dir color */
|
||||||
uint metaviewer : 1; /* Index of metadata viewer in utils[] */
|
uint metaviewer : 1; /* Index of metadata viewer in utils[] */
|
||||||
uint ctxactive : 1; /* Context active or not */
|
uint ctxactive : 1; /* Context active or not */
|
||||||
uint reserved : 13;
|
uint reserved : 10;
|
||||||
/* The following settings are global */
|
/* The following settings are global */
|
||||||
uint curctx : 2; /* Current context number */
|
uint curctx : 2; /* Current context number */
|
||||||
uint picker : 1; /* Write selection to user-specified file */
|
uint picker : 1; /* Write selection to user-specified file */
|
||||||
uint pickraw : 1; /* Write selection to sdtout before exit */
|
uint pickraw : 1; /* Write selection to sdtout before exit */
|
||||||
uint nonavopen : 1; /* Open file on right arrow or `l` */
|
uint nonavopen : 1; /* Open file on right arrow or `l` */
|
||||||
uint useeditor : 1; /* Use VISUAL to open text files */
|
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;
|
} settings;
|
||||||
|
|
||||||
/* Contexts or workspaces */
|
/* Contexts or workspaces */
|
||||||
|
@ -281,7 +283,7 @@ typedef struct {
|
||||||
/* GLOBALS */
|
/* GLOBALS */
|
||||||
|
|
||||||
/* Configuration, contexts */
|
/* 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 context g_ctx[CTX_MAX] __attribute__ ((aligned));
|
||||||
|
|
||||||
static struct entry *dents;
|
static struct entry *dents;
|
||||||
|
@ -2105,8 +2107,6 @@ static bool show_help(char *path)
|
||||||
dprintf(fd, "copy file: %s\n", g_cppath);
|
dprintf(fd, "copy file: %s\n", g_cppath);
|
||||||
if (getenv("NNN_SCRIPT"))
|
if (getenv("NNN_SCRIPT"))
|
||||||
dprintf(fd, "NNN_SCRIPT: %s\n", 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"))
|
if (getenv("NNN_SHOW_HIDDEN"))
|
||||||
dprintf(fd, "NNN_SHOW_HIDDEN: 1\n");
|
dprintf(fd, "NNN_SHOW_HIDDEN: 1\n");
|
||||||
if (getenv("NNN_NO_AUTOSELECT"))
|
if (getenv("NNN_NO_AUTOSELECT"))
|
||||||
|
@ -2537,6 +2537,8 @@ static void browse(char *ipath)
|
||||||
{
|
{
|
||||||
static char newpath[PATH_MAX] __attribute__ ((aligned));
|
static char newpath[PATH_MAX] __attribute__ ((aligned));
|
||||||
static char mark[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 *path, *lastdir, *lastname;
|
||||||
char *dir, *tmp;
|
char *dir, *tmp;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
@ -2549,6 +2551,7 @@ static void browse(char *ipath)
|
||||||
path = g_ctx[0].c_path;
|
path = g_ctx[0].c_path;
|
||||||
xstrlcpy(g_ctx[0].c_init, ipath, PATH_MAX); /* start directory */
|
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';
|
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 */
|
lastdir = g_ctx[0].c_last; /* last visited directory */
|
||||||
lastname = g_ctx[0].c_name; /* last visited filename */
|
lastname = g_ctx[0].c_name; /* last visited filename */
|
||||||
g_ctx[0].c_cfg = cfg; /* current configuration */
|
g_ctx[0].c_cfg = cfg; /* current configuration */
|
||||||
|
@ -2687,6 +2690,28 @@ nochange:
|
||||||
if (cfg.nonavopen && sel == SEL_NAV_IN)
|
if (cfg.nonavopen && sel == SEL_NAV_IN)
|
||||||
continue;
|
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 NNN_USE_EDITOR is set, open text in EDITOR */
|
||||||
if (cfg.useeditor &&
|
if (cfg.useeditor &&
|
||||||
get_output(g_buf, CMD_LEN_MAX, "file", FILE_OPTS, newpath, FALSE) &&
|
get_output(g_buf, CMD_LEN_MAX, "file", FILE_OPTS, newpath, FALSE) &&
|
||||||
|
@ -2749,7 +2774,6 @@ nochange:
|
||||||
|
|
||||||
/* Save last working directory */
|
/* Save last working directory */
|
||||||
xstrlcpy(lastdir, path, PATH_MAX);
|
xstrlcpy(lastdir, path, PATH_MAX);
|
||||||
|
|
||||||
xstrlcpy(path, dir, PATH_MAX);
|
xstrlcpy(path, dir, PATH_MAX);
|
||||||
lastname[0] = '\0';
|
lastname[0] = '\0';
|
||||||
DPRINTF_S(path);
|
DPRINTF_S(path);
|
||||||
|
@ -2840,6 +2864,7 @@ nochange:
|
||||||
g_ctx[r].c_last[0] = '\0';
|
g_ctx[r].c_last[0] = '\0';
|
||||||
xstrlcpy(g_ctx[r].c_name, dents[cur].name, NAME_MAX + 1);
|
xstrlcpy(g_ctx[r].c_name, dents[cur].name, NAME_MAX + 1);
|
||||||
g_ctx[r].c_cfg = cfg;
|
g_ctx[r].c_cfg = cfg;
|
||||||
|
g_ctx[r].c_cfg.runscript = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the pointers */
|
/* Reset the pointers */
|
||||||
|
@ -3390,36 +3415,51 @@ nochange:
|
||||||
mkpath(path, dents[cur].name, newpath, PATH_MAX);
|
mkpath(path, dents[cur].name, newpath, PATH_MAX);
|
||||||
spawn(newpath, NULL, NULL, path, F_NORMAL | F_SIGINT);
|
spawn(newpath, NULL, NULL, path, F_NORMAL | F_SIGINT);
|
||||||
} else if (sel == SEL_SCRIPT) {
|
} else if (sel == SEL_SCRIPT) {
|
||||||
tmp = getenv("NNN_SCRIPT");
|
dir = getenv("NNN_SCRIPT");
|
||||||
if (!tmp) {
|
if (!dir) {
|
||||||
printmsg("set NNN_SCRIPT");
|
printmsg("set NNN_SCRIPT");
|
||||||
goto nochange;
|
goto nochange;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv("NNN_MULTISCRIPT")) {
|
if (stat(dir, &sb) == -1) {
|
||||||
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) {
|
|
||||||
printwarn();
|
printwarn();
|
||||||
goto nochange;
|
goto nochange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if it's a directory */
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
if (S_ISDIR(sb.st_mode)) {
|
if (ndents)
|
||||||
printmsg("directory");
|
tmp = dents[cur].name;
|
||||||
goto nochange;
|
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 */
|
/* Check if directory is accessible */
|
||||||
|
if (!xdiraccess(dir))
|
||||||
|
goto nochange;
|
||||||
|
|
||||||
|
xstrlcpy(rundir, path, PATH_MAX);
|
||||||
|
xstrlcpy(path, dir, PATH_MAX);
|
||||||
if (ndents)
|
if (ndents)
|
||||||
dir = dents[cur].name;
|
xstrlcpy(runfile, dents[cur].name, NAME_MAX);
|
||||||
spawn(shell, tmp, dir, path, F_NORMAL | F_SIGINT);
|
cfg.runctx = cfg.curctx;
|
||||||
|
lastname[0] = '\0';
|
||||||
|
setdirwatch();
|
||||||
|
goto begin;
|
||||||
|
}
|
||||||
} else if (sel == SEL_RUNCMD) {
|
} else if (sel == SEL_RUNCMD) {
|
||||||
tmp = xreadline(NULL, "> ");
|
tmp = xreadline(NULL, "> ");
|
||||||
if (tmp && tmp[0])
|
if (tmp && tmp[0])
|
||||||
|
|
Loading…
Reference in a new issue