Document that filenames are not unquoted

This commit is contained in:
Arun Prakash Jana 2018-08-15 08:39:31 +05:30
parent 1d6a36ae18
commit f0ca1e7785
No known key found for this signature in database
GPG Key ID: A75979F35C080412
3 changed files with 25 additions and 6 deletions

View File

@ -389,6 +389,8 @@ To wrap each file path within single quotes, export `NNN_QUOTE_ON`:
export NNN_QUOTE_ON=1 export NNN_QUOTE_ON=1
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 <kbd>^T</kbd>. 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 <kbd>^T</kbd>.
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 #### copy file paths 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 `/tmp/nnncp$USER`. 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 `/tmp/nnncp$USER`.

3
nnn.1
View File

@ -263,7 +263,8 @@ screensaver.
.Ed .Ed
.Pp .Pp
\fBNNN_QUOTE_ON:\fR wrap copied paths within single quotes. Useful for pasting \fBNNN_QUOTE_ON:\fR wrap copied paths within single quotes. Useful for pasting
names in the shell. names in the shell. Note that the filename is not escaped. So copying may still fail
for filenames having quote(s) in them.
.Pp .Pp
\fBNNN_SCRIPT:\fR path to a custom script to invoke with currently selected file name as argument 1. \fBNNN_SCRIPT:\fR path to a custom script to invoke with currently selected file name as argument 1.
.Bd -literal .Bd -literal

26
nnn.c
View File

@ -1752,6 +1752,19 @@ xgetgrgid(gid_t gid)
return grp->gr_name; return grp->gr_name;
} }
static bool
istgtdir(const char *tgtpath)
{
if (tgtpath) {
struct stat tgtsb;
int r = stat(tgtpath, &tgtsb);
if ((r == 0) && (tgtsb.st_mode & S_IFMT) == S_IFDIR)
return TRUE;
}
return FALSE;
}
/* /*
* Follows the stat(1) output closely * Follows the stat(1) output closely
*/ */
@ -1772,16 +1785,19 @@ show_stats(char *fpath, char *fname, struct stat *sb)
/* Show file name or 'symlink' -> 'target' */ /* Show file name or 'symlink' -> 'target' */
if (perms[0] == 'l') { if (perms[0] == 'l') {
/* Note that MAX_CMD_LEN > PATH_MAX */ /* Note that MAX_CMD_LEN > PATH_MAX */
ssize_t len = readlink(fpath, g_buf, MAX_CMD_LEN); char *tgt = realpath(fpath, g_buf);
if (tgt) {
if (len != -1) { char ch[] = {'\'', '\0', '\0'};
g_buf[len] = '\0'; if (istgtdir(g_buf)) {
ch[1] = ch[0];
ch[0] = '/';
}
/* /*
* We pass g_buf but unescape() operates on g_buf too! * We pass g_buf but unescape() operates on g_buf too!
* Read the API notes for information on how this works. * Read the API notes for information on how this works.
*/ */
dprintf(fd, " -> '%s'", unescape(g_buf, 0)); dprintf(fd, " -> '%s%s", unescape(g_buf, 0), ch);
} }
} }