From cafcf1c4859c7a43eed0e2489142166195078d5d Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Sun, 17 May 2020 22:54:39 +0530 Subject: [PATCH] Take to target on Right/l on symlink in list dir --- nnn.1 | 7 +++++-- src/nnn.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/nnn.1 b/nnn.1 index 84f907e..7a34f3b 100644 --- a/nnn.1 +++ b/nnn.1 @@ -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. diff --git a/src/nnn.c b/src/nnn.c index 46b43bc..7da974c 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -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