From d9537e6d49121c9171f7a912944cfb89a04327f3 Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Sun, 24 Dec 2017 15:21:38 +0530 Subject: [PATCH] Add option -b to open bookmark directly --- README.md | 2 ++ nnn.1 | 4 +++ nnn.c | 100 ++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 9168eeea..c4edef05 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i - Familiar shortcuts - *Navigate-as-you-type* mode - Bookmarks support; pin and visit a directory + - Open a bookmarked directory on start - Jump HOME or to the last visited directory (as usual!) - Jump to initial dir, chdir prompt, cd ..... (with . as PWD) - Roll-over at edges, page through entries @@ -189,6 +190,7 @@ positional arguments: PATH directory to open [default: current dir] optional arguments: + -b key specify bookmark key to open -c N specify dir color, disables if N>7 -e use exiftool instead of mediainfo -i start in navigate-as-you-type mode diff --git a/nnn.1 b/nnn.1 index be86e4ee..7d6c3c10 100644 --- a/nnn.1 +++ b/nnn.1 @@ -6,6 +6,7 @@ .Nd the missing terminal file browser for X .Sh SYNOPSIS .Nm +.Op Ar -b key .Op Ar -c N .Op Ar -e .Op Ar -i @@ -118,6 +119,9 @@ PAGER. Please use the PAGER-specific keys in these screens. .Nm supports the following options: .Pp +.Fl "b key" + specify bookmark key to open +.Pp .Fl "c N" specify dir color (default blue), disables if N>7 0-black, 1-red, 2-green, 3-yellow, 4-blue, 5-magenta, 6-cyan, 7-white diff --git a/nnn.c b/nnn.c index 9dca26aa..82a944c7 100644 --- a/nnn.c +++ b/nnn.c @@ -268,6 +268,7 @@ static char *STR_NFTWFAIL = "nftw(3) failed"; static char *STR_ATROOT = "You are at /"; static char *STR_NOHOME = "HOME not set"; static char *STR_INPUT = "No traversal delimiter allowed"; +static char *STR_INVBM = "Invalid bookmark"; /* For use in functions which are isolated and don't return the buffer */ static char g_buf[MAX_CMD_LEN]; @@ -1155,6 +1156,39 @@ parsebmstr(char *bms) } } +/* + * Get the real path to a bookmark + * + * NULL is returned in case of no match, path resolution failure etc. + * buf would be modified, so check return value before access + */ +static char * +get_bm_loc(char *key, char *buf) +{ + if (!key || !key[0]) + return NULL; + + for (int r = 0; bookmark[r].key && r < BM_MAX; ++r) { + if (xstrcmp(bookmark[r].key, key) == 0) { + if (bookmark[r].loc[0] == '~') { + char *home = getenv("HOME"); + if (!home) { + DPRINTF_S(STR_NOHOME); + return NULL; + } + + snprintf(buf, PATH_MAX, "%s%s", home, bookmark[r].loc + 1); + } else + xstrlcpy(buf, bookmark[r].loc, PATH_MAX); + + return buf; + } + } + + DPRINTF_S("Invalid key"); + return NULL; +} + static void resetdircolor(mode_t mode) { @@ -2499,38 +2533,19 @@ nochange: if (tmp == NULL) break; - for (r = 0; bookmark[r].key && r < BM_MAX; ++r) { - if (xstrcmp(bookmark[r].key, tmp) != 0) - continue; - - if (bookmark[r].loc[0] == '~') { - /* Expand ~ to HOME */ - char *home = getenv("HOME"); - - if (home) - snprintf(newpath, PATH_MAX, "%s%s", home, bookmark[r].loc + 1); - else { - printmsg(STR_NOHOME); - goto nochange; - } - } else - mkpath(path, bookmark[r].loc, newpath, PATH_MAX); - - if (!xdiraccess(newpath)) - goto nochange; - - if (xstrcmp(path, newpath) == 0) - break; - - oldpath[0] = '\0'; - break; - } - - if (!bookmark[r].key) { - printmsg("No matching bookmark"); + if (get_bm_loc(tmp, newpath) == NULL) { + printmsg(STR_INVBM); goto nochange; } + if (!xdiraccess(newpath)) + goto nochange; + + if (xstrcmp(path, newpath) == 0) + break; + + oldpath[0] = '\0'; + /* Save last working directory */ xstrlcpy(lastdir, path, PATH_MAX); dir_changed = TRUE; @@ -2820,6 +2835,7 @@ The missing terminal file browser for X.\n\n\ positional arguments:\n\ PATH directory to open [default: current dir]\n\n\ optional arguments:\n\ + -b key specify bookmark key to open\n\ -c N specify dir color, disables if N>7\n\ -e use exiftool instead of mediainfo\n\ -i start in navigate-as-you-type mode\n\ @@ -2836,7 +2852,7 @@ int main(int argc, char *argv[]) { static char cwd[PATH_MAX]; - char *ipath, *ifilter, *bmstr; + char *ipath = NULL, *ifilter, *bmstr; int opt; /* Confirm we are in a terminal */ @@ -2845,7 +2861,7 @@ main(int argc, char *argv[]) exit(1); } - while ((opt = getopt(argc, argv, "Slic:ep:vh")) != -1) { + while ((opt = getopt(argc, argv, "Slib:c:ep:vh")) != -1) { switch (opt) { case 'S': cfg.blkorder = 1; @@ -2857,6 +2873,9 @@ main(int argc, char *argv[]) case 'i': cfg.filtermode = 1; break; + case 'b': + ipath = optarg; + break; case 'c': if (atoi(optarg) > 7) cfg.showcolor = 0; @@ -2878,7 +2897,19 @@ main(int argc, char *argv[]) } } - if (argc == optind) { + /* Parse bookmarks string, if available */ + bmstr = getenv("NNN_BMS"); + if (bmstr) + parsebmstr(bmstr); + + if (ipath) { /* Open a bookmark directly */ + if (get_bm_loc(ipath, cwd) == NULL) { + fprintf(stderr, "%s\n", STR_INVBM); + exit(1); + } + + ipath = cwd; + } else if (argc == optind) { /* Start in the current directory */ ipath = getcwd(cwd, PATH_MAX); if (ipath == NULL) @@ -2916,11 +2947,6 @@ main(int argc, char *argv[]) gtimeout.tv_nsec = 0; #endif - /* Parse bookmarks string, if available */ - bmstr = getenv("NNN_BMS"); - if (bmstr) - parsebmstr(bmstr); - /* Edit text in EDITOR, if opted */ if (getenv("NNN_USE_EDITOR")) editor = xgetenv("EDITOR", "vi");