Support bookmarks

This commit is contained in:
Arun Prakash Jana 2017-06-11 09:45:50 +05:30
parent e495886b59
commit 8c6ab7df02
No known key found for this signature in database
GPG key ID: A75979F35C080412
4 changed files with 147 additions and 5 deletions

View file

@ -31,6 +31,7 @@ Noice is Not Noice, a noicer fork...
- [Help](#help)
- [Quickstart](#quickstart)
- [How to](#how-to)
- [add bookmarks](#add-bookmarks)
- [use cd .....](#use-cd-)
- [cd on quit](#cd-on-quit)
- [copy file path to clipboard](#copy-file-path-to-clipboard)
@ -45,7 +46,7 @@ Noice is Not Noice, a noicer fork...
`nnn` is a fork of [noice](http://git.2f30.org/noice/), a blazing-fast lightweight terminal file browser with easy keyboard shortcuts for navigation, opening files and running tasks. noice is developed considering terminal based systems. There is no config file and mime associations are hard-coded. However, the incredible user-friendliness and speed make it a perfect candidate for modern distros.
`nnn` works with the desktop opener, adds new navigation options, [navigate-as-you-type](#navigate-as-you-type-mode) mode, enhanced DE integration, a disk usage analyzer mode, comprehensive file details and much more. Add to that a huge [performance](#performance) boost. For a detailed comparison, visit [nnn vs. noice](https://github.com/jarun/nnn/wiki/nnn-vs.-noice).
`nnn` works with the desktop opener, adds new navigation options, [navigate-as-you-type](#navigate-as-you-type-mode) mode, enhanced DE integration, bookmarks, a disk usage analyzer mode, comprehensive file details and much more. Add to that a huge [performance](#performance) boost. For a detailed comparison, visit [nnn vs. noice](https://github.com/jarun/nnn/wiki/nnn-vs.-noice).
If you want to edit a file in vim with some soothing music in the background while referring to a spec in your GUI PDF viewer, `nnn` got it! [Quickstart](#quickstart) and see how `nnn` simplifies those long desktop sessions...
@ -61,6 +62,7 @@ Have fun with it! PRs are welcome. Check out [#1](https://github.com/jarun/nnn/i
- Navigation
- Familiar shortcuts
- *Navigate-as-you-type* mode
- Bookmarks
- 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
@ -165,6 +167,7 @@ Right, Enter, l, ^M | Open file or enter dir
/ | Filter dir contents
^/ | Search dir in desktop search tool
. | Toggle hide .dot files
b | Show bookmark key prompt
c | Show change dir prompt
d | Toggle detail view
D | Toggle current file details screen
@ -247,6 +250,12 @@ Run `n`.
### How to
#### add bookmarks
Set environment variable `NNN_BMS` as a string of `key:location` pairs (max 10) separated by semicolons (`;`):
export NNN_BMS='doc:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/'
#### use cd .....
To jump to the n<sup>th</sup> level parent, with PWD at level 0, use `n + 1` dots. For example, to jump to the 6<th> parent of the current directory, use 7 dots. If the number of dots would take you *beyond* `/` (which isn't possible), you'll be placed at `/`.

View file

@ -69,6 +69,8 @@ static struct key bindings[] = {
{ '&', SEL_CDBEGIN, "", "" },
/* Last visited dir */
{ '-', SEL_CDLAST, "", "" },
/* Change dir using bookmark */
{ 'b', SEL_CDBM, "", "" },
/* Toggle hide .dot files */
{ '.', SEL_TOGGLEDOT, "", "" },
/* Detailed listing */

12
nnn.1
View file

@ -15,7 +15,7 @@
.Op Ar PATH
.Sh DESCRIPTION
.Nm
(Noice is Not Noice) is a performance-optimized fork of the noice terminal file browser with extensive desktop integration, simplified navigation, \fInavigate-as-you-type\fR mode, disk usage analyzer mode, comprehensive file details and much more. It remains a simple and efficient file browser that stays out of your way.
(Noice is Not Noice) is a performance-optimized fork of the noice terminal file browser with extensive desktop integration, simplified navigation, \fInavigate-as-you-type\fR mode, bookmarks, disk usage analyzer mode, comprehensive file details and much more. It remains a simple and efficient file browser that stays out of your way.
.Pp
.Nm
defaults to the current directory if
@ -57,8 +57,10 @@ Change filter (more information below)
Search directory in desktop search tool
.It Ic \&.
Toggle hide .dot files
.It Ic b
Show bookmark key prompt
.It Ic c
Change into the given directory
Show change dir prompt
.It Ic d
Toggle detail view
.It Ic D
@ -162,6 +164,12 @@ files.
export NNN_USE_EDITOR=1
.Ed
.Pp
\fBNNN_BMS:\fR bookmark string as \fIkey:location\fR pairs (max 10) separated by
\fI;\fR:
.Bd -literal
export NNN_BMS='doc:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/'
.Ed
.Pp
\fBNNN_DE_FILE_MANAGER:\fR set to a desktop file manager to open the current
directory with. E.g.:
.Bd -literal

127
nnn.c
View file

@ -78,6 +78,7 @@ xprintf(int fd, const char *fmt, ...)
#define MAX_CMD_LEN 5120
#define CURSYM(flag) (flag ? CURSR : EMPTY)
#define FILTER '/'
#define MAX_BM 10
struct assoc {
char *regex; /* Regex to match on filename */
@ -103,6 +104,7 @@ enum action {
SEL_CDHOME,
SEL_CDBEGIN,
SEL_CDLAST,
SEL_CDBM,
SEL_TOGGLEDOT,
SEL_DETAIL,
SEL_STATS,
@ -136,6 +138,11 @@ typedef struct entry {
off_t bsize;
} *pEntry;
typedef struct {
char *key;
char *loc;
} bm;
typedef unsigned long ulong;
/* Externs */
@ -158,8 +165,10 @@ static char *desktop_manager;
static off_t blk_size;
static size_t fs_free;
static int open_max;
static bm bookmark[MAX_BM];
static const double div_2_pow_10 = 1.0 / 1024.0;
static char *utils[] = {
#ifdef __APPLE__
"/usr/bin/open",
@ -842,6 +851,58 @@ mkpath(char *dir, char *name, char *out, size_t n)
return out;
}
static void
parsebmstr(char *bms)
{
int i = 0;
while (*bms && i < MAX_BM) {
bookmark[i].key = bms;
bms++;
while (*bms && *bms != ':')
bms++;
if (!*bms) {
bookmark[i].key = NULL;
break;
}
*bms = '\0';
bookmark[i].loc = ++bms;
if (bookmark[i].loc[0] == '\0' || bookmark[i].loc[0] == ';') {
bookmark[i].key = NULL;
break;
}
while (*bms && *bms != ';')
bms++;
if (*bms)
*bms = '\0';
else
break;
bms++;
i++;
}
}
static char *
readinput(void)
{
timeout(-1);
echo();
curs_set(TRUE);
memset(g_buf, 0, LINE_MAX);
wgetnstr(stdscr, g_buf, LINE_MAX - 1);
noecho();
curs_set(FALSE);
timeout(1000);
return g_buf[0] ? g_buf : NULL;
}
static char *
replace_escape(const char *str)
{
@ -1268,6 +1329,7 @@ show_help(void)
/ | Filter dir contents\n\
^/ | Search dir in desktop search tool\n\
. | Toggle hide .dot files\n\
b | Show bookmark key prompt\n\
c | Show change dir prompt\n\
d | Toggle detail view\n\
D | Toggle current file details screen\n\
@ -1745,7 +1807,7 @@ nochange:
break;
case SEL_CD:
{
static char *tmp, *input;
static char *input;
static int truecd;
/* Save the program start dir */
@ -1791,7 +1853,8 @@ nochange:
snprintf(newpath, PATH_MAX, "%s%s", home, tmp + 1);
else {
free(input);
break;
printmsg("HOME not set");
goto nochange;
}
} else if (tmp[0] == '-' && tmp[1] == '\0') {
if (lastdir[0] == '\0') {
@ -1943,6 +2006,61 @@ nochange:
/* Reset filter */
xstrlcpy(fltr, ifilter, LINE_MAX);
DPRINTF_S(path);
if (filtermode)
presel = FILTER;
goto begin;
case SEL_CDBM:
printprompt("key: ");
tmp = readinput();
if (tmp == NULL) {
clearprompt();
goto nochange;
}
clearprompt();
for (r = 0; bookmark[r].key && r < MAX_BM; r++) {
if (strcmp(bookmark[r].key, tmp) == 0) {
if (bookmark[r].loc[0] == '~') {
/* Expand ~ to HOME absolute path */
char *home = getenv("HOME");
if (home)
snprintf(newpath, PATH_MAX, "%s%s", home, bookmark[r].loc + 1);
else {
printmsg("HOME not set");
goto nochange;
}
} else
mkpath(path, bookmark[r].loc, newpath, PATH_MAX);
if (canopendir(newpath) == 0) {
printwarn();
goto nochange;
}
if (strcmp(path, newpath) == 0)
break;
oldpath[0] = '\0';
break;
}
}
if (!bookmark[r].key) {
printmsg("No matching bookmark");
goto nochange;
}
/* Save last working directory */
xstrlcpy(lastdir, path, PATH_MAX);
/* Save the newly opted dir in path */
xstrlcpy(path, newpath, PATH_MAX);
/* Reset filter */
xstrlcpy(fltr, ifilter, LINE_MAX);
DPRINTF_S(path);
if (filtermode)
presel = FILTER;
goto begin;
@ -2186,6 +2304,11 @@ main(int argc, char *argv[])
/* Get the default copier, if set */
copier = getenv("NNN_COPIER");
/* Parse bookmarks string, if available */
char *bms = getenv("NNN_BMS");
if (bms)
parsebmstr(bms);
signal(SIGINT, SIG_IGN);
/* Test initial path */