README.md | 14 ++++++++++---- nnn.1 | 2 ++ nnn.c | 38 ++++++++++++++++++++++++++++++++++++++ nnn.h | 3 +++ diff --git a/README.md b/README.md index 4e302706e03b804e89a723c564aa23d8aca7db0d..b575a110a76f7e6ad6048a650c686b0456043d86 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,9 @@ - [How to](#how-to) - [add bookmarks](#add-bookmarks) - [use cd .....](#use-cd-) - [cd on quit](#cd-on-quit) - - [copy file paths to clipboard](#copy-file-paths-to-clipboard) - - [copy file paths when X is missing](#copy-file-paths-when-x-is-missing) + - [copy file paths](#copy-file-paths) + - [to clipboard](#to-clipboard) + - [when X is missing](#when-x-is-missing) - [run custom scripts](#run-custom-scripts) - [sample scripts](#sample-scripts) - [dual-pane or multi-pane](#dual-pane-or-multi-pane) @@ -248,6 +249,7 @@ F List archive ^F Extract archive Space, ^K Copy file path ^Y Toggle multi-copy + y Show copy buffer ^T Toggle path quote ^L Redraw, clear prompt L Lock terminal @@ -359,7 +361,11 @@ Pick the appropriate file for your shell from [`scripts/quitcd`](scripts/quitcd) and add the contents to your shell's rc file. You'll need to spawn a new shell for the change to take effect. You should start `nnn` as `n` (or modify the function name to something else). To change directory on quit press `Q` (it's _capital_) or `^G` while exiting. As you might notice, `nnn` uses the environment variable `NNN_TMPFILE` to write the last visited directory path. You can change it. -#### copy file paths to clipboard +#### copy file paths + +File paths can be copied to the clipboard or to a specific temporary file (if X is unavailable, for example). When in multi-copy mode, currently copied file paths can be listed by pressing `y`. + +##### to clipboard `nnn` can pipe the absolute path of the current file or multiple files to a copier script. For example, you can use `xsel` on Linux or `pbcopy` on OS X. @@ -392,7 +398,7 @@ This is particularly useful if you are planning to copy the whole string to the shell to run a command. Quotes can be toggled at runtime using ^T. Note that the filename is not escaped. So copying may still fail for filenames having quote(s) in them. -#### copy file paths when X is missing +##### when X is missing A very common scenario on headless remote servers connected via SSH. As the clipboard is missing, `nnn` copies the path names to the tmp file `DIR/.nnncp`, where `DIR` (by priority) is: diff --git a/nnn.1 b/nnn.1 index 99b2bdbba9bf291d432cd5afb930b44259dca03e..e2aa33578b800cd18caeb04a70279faa37be00e5 100644 --- a/nnn.1 +++ b/nnn.1 @@ -111,6 +111,8 @@ .It Ic Space, ^K Invoke file path copier .It Ic ^Y Toggle multiple file path copy mode +.It Ic y +Show copy buffer .It Ic ^T Toggle path quote .It Ic ^L diff --git a/nnn.c b/nnn.c index 76f11bb9f192e4f30561f66cfd61b2e70f2c8fbf..84434017c071bc2da04c9811c2297ee4eb3b688e 100644 --- a/nnn.c +++ b/nnn.c @@ -351,6 +351,7 @@ }; /* Forward declarations */ static void redraw(char *path); +static char * get_output(char *buf, size_t bytes, char *file, char *arg1, char *arg2, int pager); /* Functions */ @@ -674,6 +675,36 @@ return TRUE; } +static bool +showcplist() +{ + ssize_t len; + + if (!copybufpos) + return FALSE; + + if (g_tmpfpath[0]) + xstrlcpy(g_tmpfpath + g_tmpfplen - 1, "/.nnnXXXXXX", MAX_HOME_LEN - g_tmpfplen); + else { + printmsg(messages[STR_NOHOME_ID]); + return -1; + } + + int fd = mkstemp(g_tmpfpath); + if (fd == -1) + return FALSE; + + len = write(fd, pcopybuf, copybufpos - 1); + close(fd); + + exitcurses(); + if (len == copybufpos - 1) + get_output(NULL, 0, "cat", g_tmpfpath, NULL, 1); + unlink(g_tmpfpath); + refresh(); + return TRUE; +} + /* * Return number of dots if all chars in a string are dots, else 0 */ @@ -1992,6 +2023,7 @@ "eF List archive\n" "d^F Extract archive\n" "6Space, ^K Copy file path\n" "d^Y Toggle multi-copy\n" + "ey Show copy buffer\n" "d^T Toggle path quote\n" "d^L Redraw, clear prompt\n" "eL Lock terminal\n" @@ -3102,6 +3134,12 @@ snprintf(newpath, PATH_MAX, "%d files copied", ncp); printmsg(newpath); } } else + printmsg("multi-copy off"); + goto nochange; + case SEL_COPYLIST: + if (cfg.copymode) + showcplist(); + else printmsg("multi-copy off"); goto nochange; case SEL_QUOTE: diff --git a/nnn.h b/nnn.h index 537cb71d0f1099cdbcc9729e1fb55302dddcf5eb..420bd1337e5ef6199f84de602307271289d908c3 100644 --- a/nnn.h +++ b/nnn.h @@ -66,6 +66,7 @@ SEL_MTIME, SEL_REDRAW, SEL_COPY, SEL_COPYMUL, + SEL_COPYLIST, SEL_QUOTE, SEL_OPEN, SEL_NEW, @@ -188,6 +189,8 @@ { CONTROL('K'), SEL_COPY, "", "" }, { ' ', SEL_COPY, "", "" }, /* Toggle copy multiple file paths */ { CONTROL('Y'), SEL_COPYMUL, "", "" }, + /* Show list of copied files */ + { 'y', SEL_COPYLIST, "", "" }, /* Toggle quote on while copy */ { CONTROL('T'), SEL_QUOTE, "", "" }, /* Open in a custom application */