Fix #1369: limit symlinked bookmarks to bookmarks dir

This commit is contained in:
Arun Prakash Jana 2022-05-28 23:14:07 +05:30
parent ec7692bb9e
commit 3a50be93fd
No known key found for this signature in database
GPG key ID: A75979F35C080412
2 changed files with 29 additions and 24 deletions

24
nnn.1
View file

@ -348,23 +348,21 @@ selected entries from the listed results.
.Sh BOOKMARKS .Sh BOOKMARKS
There are 2 ways (can be used together) to manage bookmarks. There are 2 ways (can be used together) to manage bookmarks.
.Pp .Pp
(1) Bookmark keys: See \fINNN_BMS\fR under \fIENVIORNMENT\fR section on how to (1) Bookmark keys: See \fINNN_BMS\fR under \fIENVIORNMENT\fR section on how to set
set bookmark keys. bookmark keys.
.Pp
(2) Symlinked bookmarks: A symlinked bookmark to the current directory can be
created with the \fIB\fR key.
Add prefix \fBn_\fR to the name to open the target of the symlink.
Press '-' to return to the original directory.
Symlinks can also be created manually under the "bookmarks" directory in The select bookmark key \fIb\fR lists all the bookmark keys set in \fINNN_BMS\fR
the nnn config directory (~/.config/nnn/bookmarks). in the bookmarks prompt.
.Pp
(2) Symlinked bookmarks: A symlinked bookmark to the current directory can
be created with the \fIB\fR key (or manually under ~/.config/nnn/bookmarks).
Pressing 'Enter' at the bookmarks prompt takes to this directory. Pressing 'Enter' at the bookmarks prompt takes to this directory.
If \fINNN_BMS\fR is not set, it happens directly on select bookmark key. If \fINNN_BMS\fR is not set, the select bookmark key directly opens it.
Press '-' to return to the original directory right after entering a
symlinked bookmark.
.Pp .Pp
Pressing \fIb\fR will list all the bookmark keys set in NNN_BMS. Pressing
\fIEnter\fR at this prompt will take to the symlink bookmark directory, if
NNN_BMS is not set, it happens directly on bookmarks key.
.Sh UNITS .Sh UNITS
The minimum file size unit is byte (B). The rest are K, M, G, T, P, E, Z, Y 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. (powers of 1024), same as the default units in \fIls\fR.

View file

@ -178,8 +178,6 @@
#define MSGWAIT '$' #define MSGWAIT '$'
#define SELECT ' ' #define SELECT ' '
#define PROMPT ">>> " #define PROMPT ">>> "
#define BM_PREFIX "n_"
#define BM_PREFIX_LEN (sizeof BM_PREFIX - 1)
#define REGEX_MAX 48 #define REGEX_MAX 48
#define ENTRY_INCR 64 /* Number of dir 'entry' structures to allocate per shot */ #define ENTRY_INCR 64 /* Number of dir 'entry' structures to allocate per shot */
#define NAMEBUF_INCR 0x800 /* 64 dir entries at once, avg. 32 chars per file name = 64*32B = 2KB */ #define NAMEBUF_INCR 0x800 /* 64 dir entries at once, avg. 32 chars per file name = 64*32B = 2KB */
@ -369,11 +367,12 @@ typedef struct {
uint_t rangesel : 1; /* Range selection on */ uint_t rangesel : 1; /* Range selection on */
uint_t runctx : 3; /* The context in which plugin is to be run */ uint_t runctx : 3; /* The context in which plugin is to be run */
uint_t runplugin : 1; /* Choose plugin mode */ uint_t runplugin : 1; /* Choose plugin mode */
uint_t selbm : 1; /* Select a bookmark from bookmarks directory */
uint_t selmode : 1; /* Set when selecting files */ uint_t selmode : 1; /* Set when selecting files */
uint_t stayonsel : 1; /* Disable auto-jump on select */ uint_t stayonsel : 1; /* Disable auto-jump on select */
uint_t trash : 2; /* Trash method 0: rm -rf, 1: trash-cli, 2: gio trash */ uint_t trash : 2; /* Trash method 0: rm -rf, 1: trash-cli, 2: gio trash */
uint_t uidgid : 1; /* Show owner and group info */ uint_t uidgid : 1; /* Show owner and group info */
uint_t reserved : 7; /* Adjust when adding/removing a field */ uint_t reserved : 6; /* Adjust when adding/removing a field */
} runstate; } runstate;
/* Contexts or workspaces */ /* Contexts or workspaces */
@ -686,7 +685,7 @@ static const char * const messages[] = {
"invalid key", "invalid key",
"unchanged", "unchanged",
"dir changed, range sel off", "dir changed, range sel off",
"name (prefix n_ to identify): ", "name: ",
}; };
/* Supported configuration environment variables */ /* Supported configuration environment variables */
@ -4987,13 +4986,17 @@ static size_t handle_bookmark(const char *bmark, char *newpath)
r = FALSE; r = FALSE;
if (fd == ',') /* Visit marked directory */ if (fd == ',') /* Visit marked directory */
bmark ? xstrsncpy(newpath, bmark, PATH_MAX) : (r = MSG_NOT_SET); bmark ? xstrsncpy(newpath, bmark, PATH_MAX) : (r = MSG_NOT_SET);
else if (fd == '\r') /* Visit bookmarks directory */ else if (fd == '\r') { /* Visit bookmarks directory */
mkpath(cfgpath, toks[TOK_BM], newpath); mkpath(cfgpath, toks[TOK_BM], newpath);
else if (!get_kv_val(bookmark, newpath, fd, maxbm, NNN_BMS)) g_state.selbm = TRUE;
} else if (!get_kv_val(bookmark, newpath, fd, maxbm, NNN_BMS))
r = MSG_INVALID_KEY; r = MSG_INVALID_KEY;
if (!r && chdir(newpath) == -1) if (!r && chdir(newpath) == -1) {
r = MSG_ACCESS; r = MSG_ACCESS;
if (g_state.selbm)
g_state.selbm = FALSE;
}
return r; return r;
} }
@ -6907,10 +6910,14 @@ nochange:
pent = &pdents[cur]; pent = &pdents[cur];
r = FALSE; r = FALSE;
/* Check if it's a symlinked boookmark */
(S_ISLNK(pent->mode) && is_prefix(pent->name, BM_PREFIX, BM_PREFIX_LEN)) if (g_state.selbm) {
? (realpath(pent->name, newpath) && xstrsncpy(path, lastdir, PATH_MAX)) S_ISLNK(pent->mode)
: mkpath(path, pent->name, newpath); ? (realpath(pent->name, newpath) && xstrsncpy(path, lastdir, PATH_MAX))
: mkpath(path, pent->name, newpath);
g_state.selbm = FALSE;
} else
mkpath(path, pent->name, newpath);
DPRINTF_S(newpath); DPRINTF_S(newpath);
/* Visit directory */ /* Visit directory */