diff --git a/plugins/README.md b/plugins/README.md
index c139da1b..bcd01cab 100644
--- a/plugins/README.md
+++ b/plugins/README.md
@@ -14,7 +14,6 @@ Plugins extend the capabilities of `nnn`. They are _executable_ scripts (or bina
| Plugin (a-z) | Description [Clears selection1] | Lang | Dependencies |
| --- | --- | --- | --- |
| [autojump](autojump) | Navigate to dir/path | sh | [jump](https://github.com/gsamokovarov/jump)/autojump/
zoxide/z (needs fzf) |
-| [bookmarks](bookmarks) | Use named bookmarks managed with symlinks | sh | fzf |
| [boom](boom) | Play random music from dir | sh | [moc](http://moc.daper.net/) |
| [bulknew](bulknew) | Create multiple files/dirs at once | bash | sed, xargs, mktemp |
| [cdpath](cdpath) | `cd` to the directory from `CDPATH` | sh | fzf |
@@ -117,14 +116,14 @@ If the plugins list gets too long, try breaking them up into sections:
NNN_PLUG_PERSONAL='g:personal/convert2zoom;p:personal/echo'
NNN_PLUG_WORK='j:work/prettyjson;d:work/foobar'
NNN_PLUG_INLINE='e:!go run $nnn*'
-NNN_PLUG_DEFAULT='1:bookmarks;2:ipinfo;p:preview-tui;o:fzz;b:nbak'
+NNN_PLUG_DEFAULT='1:ipinfo;p:preview-tui;o:fzz;b:nbak'
NNN_PLUG="$NNN_PLUG_PERSONAL;$NNN_PLUG_WORK;$NNN_PLUG_DEFAULT;$NNN_PLUG_INLINE"
export NNN_PLUG
```
Note:
- `'g:personal/convert2zoom'` will look in the personal sub-folder inside the plugin folder.
-- `'b:boom;b:bookmarks` will result in only the first definition of *b* (`b:boom`) being used.
+- `'b:boom;b:bulknew` will result in only the first definition of *b* (`b:boom`) being used.
- A keybinding definition of more than 1 character will prevent nnn from starting.
diff --git a/plugins/bookmarks b/plugins/bookmarks
deleted file mode 100755
index 8cb3ea24..00000000
--- a/plugins/bookmarks
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env sh
-
-# Description: Use named bookmarks using symlinks
-#
-# Dependencies: fzf
-#
-# Usage:
-# 1. Create a $BOOKMARKS_DIR directory
-# By default, $BOOKMARKS_DIR is set to: ${XDG_CACHE_HOME:-$HOME/.cache}/nnn/bookmarks
-# 2. Create symlinks to directories
-# `cd $BOOKMARKS_DIR`
-# `ln -s /path/to/useful/directory bookmark_name`
-# `ln -s $XDG_CONFIG_HOME/nnn/plugins nnn_plugins"
-# `ln -s /path/to/documents docs`
-# `ln -s /path/to/media media`
-# `ln -s /path/to/movies movies`
-#
-# Bonus tip: Add `$BOOKMARKS_DIR` to your `$CDPATH`
-# https://linux.101hacks.com/cd-command/cdpath/
-#
-# TODO:
-# - Remove `fzf` dependency
-#
-# Shell: POSIX compliant
-# Author: Todd Yamakawa
-
-if [ -z "$BOOKMARKS_DIR" ]; then
- BOOKMARKS_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/nnn/bookmarks"
-fi
-
-# Check if NNN_PIPE is set
-if [ -z "$NNN_PIPE" ]; then
- printf 'ERROR: NNN_PIPE is not set!'
- read -r _
- exit 2
-fi
-
-# Get all directory symlinks
-get_links() {
- for entry in "$1"/*; do
-
- # Skip unless directory symlink
- [ -h "$entry" ] || continue
- [ -d "$entry" ] || continue
-
- printf "%20s -> %s\n" "$(basename "$entry")" "$(readlink -f "$entry")"
- done | fzf |
- awk 'END {
- if (length($1) == 0) { print "'"$PWD"'" }
- else { print "'"$BOOKMARKS_DIR"'/"$1 }
- }'
-}
-
-# Choose symlink with fzf
-cddir="$(get_links "$BOOKMARKS_DIR")"
-
-# Writing result to NNN_PIPE will change nnn's active directory
-# https://github.com/jarun/nnn/tree/master/plugins#send-data-to-nnn
-context=0
-printf "%s" "${context}c$(readlink -f "$cddir")" > "$NNN_PIPE"
diff --git a/src/nnn.c b/src/nnn.c
index fe5d6508..88993ad1 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -729,11 +729,13 @@ static char mv[] = "mv -i";
static const char * const archive_cmd[] = {"atool -a", "bsdtar -acvf", "zip -r", "tar -acvf"};
/* Tokens used for path creation */
-#define TOK_SSN 0
-#define TOK_MNT 1
-#define TOK_PLG 2
+#define TOK_BM 0
+#define TOK_SSN 1
+#define TOK_MNT 2
+#define TOK_PLG 3
static const char * const toks[] = {
+ "bookmarks",
"sessions",
"mounts",
"plugins", /* must be the last entry */
@@ -4889,22 +4891,28 @@ static void printkeys(kv *kvarr, char *buf, uchar_t max)
static size_t handle_bookmark(const char *bmark, char *newpath)
{
- int fd;
- size_t r = xstrsncpy(g_buf, messages[MSG_KEYS], CMD_LEN_MAX);
+ int fd = '\r';
+ size_t r;
- if (bmark) { /* There is a marked directory */
- g_buf[--r] = ' ';
- g_buf[++r] = ',';
- g_buf[++r] = '\0';
- ++r;
+ if (maxbm || bmark) {
+ r = xstrsncpy(g_buf, messages[MSG_KEYS], CMD_LEN_MAX);
+
+ if (bmark) { /* There is a marked directory */
+ g_buf[--r] = ' ';
+ g_buf[++r] = ',';
+ g_buf[++r] = '\0';
+ ++r;
+ }
+ printkeys(bookmark, g_buf + r - 1, maxbm);
+ printmsg(g_buf);
+ fd = get_input(NULL);
}
- printkeys(bookmark, g_buf + r - 1, maxbm);
- printmsg(g_buf);
r = FALSE;
- fd = get_input(NULL);
if (fd == ',') /* Visit marked directory */
bmark ? xstrsncpy(newpath, bmark, PATH_MAX) : (r = MSG_NOT_SET);
+ else if (fd == '\r') /* Visit bookmarks directory */
+ mkpath(cfgpath, toks[TOK_BM], newpath);
else if (!get_kv_val(bookmark, newpath, fd, maxbm, NNN_BMS))
r = MSG_INVALID_KEY;
@@ -7994,7 +8002,7 @@ static bool setup_config(void)
xstrsncpy(cfgpath + r - 1, "/nnn", len - r);
DPRINTF_S(cfgpath);
- /* Create sessions, mounts and plugins directories */
+ /* Create bookmarks, sessions, mounts and plugins directories */
for (r = 0; r < ELEMENTS(toks); ++r) {
mkpath(cfgpath, toks[r], plgpath);
if (!xmktree(plgpath, TRUE)) {