Take to target on Right/l on symlink in list dir

This commit is contained in:
Arun Prakash Jana 2020-05-17 22:54:39 +05:30
parent 54d9a6e4f9
commit cafcf1c485
No known key found for this signature in database
GPG key ID: A75979F35C080412
2 changed files with 45 additions and 13 deletions

7
nnn.1
View file

@ -272,7 +272,7 @@ list again. If no file is selected in the current session, this option attempts
to list the selection file.
.Sh LIST INPUT
.Nm
can receive a list of NUL-separated ('\\0') file pathss as input. Paths and can
can receive a list of NUL-separated ('\\0') file paths as input. Paths and can
be relative to the current directory or absolute.
.Pp
Input is limited by 65,536 paths or 256 MiB of input.
@ -305,7 +305,10 @@ A temporary directory will be created containing symlinks to the given
paths. Any action performed on these symlinks will be performed only on their
targets, after which they might become invalid.
.Pp
\fBInvalid paths in the iput are ignored.\fR
Right arrow or 'l' on a symlink in the listing dir takes to the target file.
Press '-' to return to the listing dir. Press 'Enter' to open the symlink.
.Pp
\fBInvalid paths in the input are ignored.\fR
.Sh UNITS
The minimum file size unit is byte (B). The rest are K, M, G, T, P, E, Z, Y
(powers of 1024), same as the default units in \fIls\fR.

View file

@ -3548,6 +3548,17 @@ END:
return status;
}
static uchar get_free_ctx(void)
{
uchar r = cfg.curctx;
do
r = (r + 1) & ~CTX_MAX;
while (g_ctx[r].c_cfg.ctxactive && (r != cfg.curctx));
return r;
}
/*
* Gets only a single line (that's what we need
* for now) or shows full command output in pager.
@ -4250,13 +4261,9 @@ static void readpipe(int fd, char **path, char **lastname, char **lastdir)
if (len != 1)
return;
if (g_buf[0] == '+') {
r = cfg.curctx;
do
r = (r + 1) & ~CTX_MAX;
while (g_ctx[r].c_cfg.ctxactive && (r != cfg.curctx));
ctx = r + 1;
} else {
if (g_buf[0] == '+')
ctx = (char)(get_free_ctx() + 1);
else {
ctx = g_buf[0] - '0';
if (ctx < 0 || ctx > CTX_MAX)
return;
@ -5525,9 +5532,29 @@ nochange:
return EXIT_SUCCESS;
}
/* If open file is disabled on right arrow or `l`, return */
if (cfg.nonavopen && sel == SEL_NAV_IN)
goto nochange;
if (sel == SEL_NAV_IN) {
/* If in listing dir, go to target on `l` or Right on symlink */
if (listpath && S_ISLNK(dents[cur].mode)
&& is_prefix(path, listpath, strlen(listpath))) {
if (!realpath(dents[cur].name, newpath)) {
printwarn(&presel);
goto nochange;
}
xdirname(newpath);
if (chdir(newpath) == -1) {
printwarn(&presel);
goto nochange;
}
cdprep(lastdir, NULL, path, newpath)
? (presel = FILTER) : (watch = TRUE);
xstrsncpy(lastname, dents[cur].name, NAME_MAX + 1);
goto begin;
} else if (cfg.nonavopen)
goto nochange; /* Open file disabled on right arrow or `l` */
}
/* Handle plugin selection mode */
if (cfg.runplugin) {
@ -5688,7 +5715,9 @@ nochange:
goto nochange;
}
cdprep(lastdir, lastname, path, newpath) ? (presel = FILTER) : (watch = TRUE);
/* In list mode, retain the last file name to highlight it, if possible */
cdprep(lastdir, listpath && sel == SEL_CDLAST ? NULL : lastname, path, newpath)
? (presel = FILTER) : (watch = TRUE);
goto begin;
case SEL_CYCLE: // fallthrough
case SEL_CYCLER: // fallthrough