nnn

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit b411dfe1ba6541e00cfc7372fe511f016cdd2237
parent 0c0afd4799721e0dc9311383015397a92adec93f
Author: Terminator X <engineerarun@gmail.com>
Date:   Sat, 23 Oct 2021 03:01:07 +0530

Merge pull request #1202 from KlzXS/cmd_selection

Added %s and %S for using selection in shell
Diffstat:
Msrc/nnn.c | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 53 insertions(+), 9 deletions(-)

diff --git a/src/nnn.c b/src/nnn.c @@ -5349,24 +5349,68 @@ static bool launch_app(char *newpath) static bool prompt_run(void) { bool ret = FALSE; - char *tmp; + char *cmdline, *next; + int cnt_j, cnt_J; + size_t len, tmplen; + + const char *xargs_j = "xargs -0 -t -I{} sh -c '%s' < %s"; + const char *xargs_J = "xargs -0 -t sh -c '%s' < %s"; + char tmpcmd[CMD_LEN_MAX]; + char cmd[CMD_LEN_MAX + 32]; // 32 for xargs format strings while (1) { #ifndef NORL if (g_state.picker) { #endif - tmp = xreadline(NULL, PROMPT); + cmdline = xreadline(NULL, PROMPT); #ifndef NORL } else - tmp = getreadline("\n"PROMPT); + cmdline = getreadline("\n"PROMPT); #endif - if (tmp && *tmp) { // NOLINT - free(lastcmd); - lastcmd = xstrdup(tmp); - ret = TRUE; - spawn(shell, "-c", tmp, NULL, F_CLI | F_CONFIRM); - } else + // Check for an empty command + if (!cmdline || !cmdline[0]) + break; + + free(lastcmd); + lastcmd = xstrdup(cmdline); + ret = TRUE; + + len = xstrlen(cmdline); + + cnt_j = 0; + next = cmdline; + while ((next = strstr(next, "%j"))) { + ++cnt_j; + + // replace %j with {} for xargs later + next[0] = '{'; + next[1] = '}'; + + ++next; + } + + cnt_J = 0; + next = cmdline; + while ((next = strstr(next, "%J"))) { + ++cnt_J; + + tmplen = xstrsncpy(tmpcmd, cmdline, next - cmdline + 1) - 1; + tmplen += xstrsncpy(tmpcmd + tmplen, "${0} ${@}", sizeof("${0} ${@}")) - 1; + xstrsncpy(tmpcmd + tmplen, next + 2, len - (next - cmdline + 2) + 1); + + ++next; + } + + // We can't handle both %j and %J in a single command + if (cnt_j && cnt_J) break; + + if (cnt_j) + snprintf(cmd, CMD_LEN_MAX + 32, xargs_j, cmdline, selpath); + else if (cnt_J) + snprintf(cmd, CMD_LEN_MAX + 32, xargs_J, tmpcmd, selpath); + + spawn(shell, "-c", (cnt_j || cnt_J) ? cmd : cmdline, NULL, F_CLI | F_CONFIRM); } return ret;