@@ -49,7 +49,7 @@ It runs on Linux, OS X, Raspberry Pi, Cygwin, Linux subsystem for Windows and Te | |||||
- [Usage](#usage) | - [Usage](#usage) | ||||
- [Cmdline options](#cmdline-options) | - [Cmdline options](#cmdline-options) | ||||
- [Keyboard shortcuts](#keyboard-shortcuts) | - [Keyboard shortcuts](#keyboard-shortcuts) | ||||
- [Key prompt](#key-prompt) | - [Leader key](#leader-key) | ||||
- [Contexts](#contexts) | - [Contexts](#contexts) | ||||
- [Filters](#filters) | - [Filters](#filters) | ||||
- [Navigate-as-you-type mode](#navigate-as-you-type-mode) | - [Navigate-as-you-type mode](#navigate-as-you-type-mode) | ||||
@@ -84,7 +84,8 @@ It runs on Linux, OS X, Raspberry Pi, Cygwin, Linux subsystem for Windows and Te | |||||
- Familiar, easy shortcuts (arrows, `~`, `-`, `&`) | - Familiar, easy shortcuts (arrows, `~`, `-`, `&`) | ||||
- *Navigate-as-you-type* with auto-select directory | - *Navigate-as-you-type* with auto-select directory | ||||
- Contexts (_aka_ tabs _aka_ workspaces) | - Contexts (_aka_ tabs _aka_ workspaces) | ||||
- Bookmarks, pin and visit directory | - Bookmarks | ||||
- Pin and visit a directory | |||||
- Sorting | - Sorting | ||||
- Directories always listed on top | - Directories always listed on top | ||||
- Sort by file name, modification time, size | - Sort by file name, modification time, size | ||||
@@ -103,7 +104,7 @@ It runs on Linux, OS X, Raspberry Pi, Cygwin, Linux subsystem for Windows and Te | |||||
- Select multiple files; copy, move, delete selection | - Select multiple files; copy, move, delete selection | ||||
- Batch rename/move/delete (needs vidir) | - Batch rename/move/delete (needs vidir) | ||||
- Show directories in custom color (default: blue) | - Show directories in custom color (default: blue) | ||||
- Spawn SHELL in the current directory | - Spawn a subshell in the current directory | ||||
- Run custom scripts in the current directory | - Run custom scripts in the current directory | ||||
- Change directory at exit (*easy* shell integration) | - Change directory at exit (*easy* shell integration) | ||||
- Edit file in EDITOR or open in PAGER | - Edit file in EDITOR or open in PAGER | ||||
@@ -217,8 +218,8 @@ Press <kbd>?</kbd> in `nnn` to see the list anytime. | |||||
→, ↵, l, ^M Open file/enter dir . Toggle show hidden | →, ↵, l, ^M Open file/enter dir . Toggle show hidden | ||||
/ Filter Ins, ^I Toggle nav-as-you-type | / Filter Ins, ^I Toggle nav-as-you-type | ||||
b Pin current dir ^V Go to pinned dir | b Pin current dir ^V Go to pinned dir | ||||
^B Key prompt ^L Redraw, clear prompt | ^B Leader key LeaderN Switch to context N | ||||
Esc Exit prompt ^Bn Switch to context n | Esc Exit prompt ^L Redraw, clear prompt | ||||
^G Quit and cd q Quit context | ^G Quit and cd q Quit context | ||||
Q, ^Q Quit ? Help, settings | Q, ^Q Quit ? Help, settings | ||||
FILES | FILES | ||||
@@ -242,9 +243,9 @@ Press <kbd>?</kbd> in `nnn` to see the list anytime. | |||||
Help & settings, file details, media info and archive listing are shown in the PAGER. Please use the PAGER-specific keys in these screens. | Help & settings, file details, media info and archive listing are shown in the PAGER. Please use the PAGER-specific keys in these screens. | ||||
#### Key prompt | #### Leader key | ||||
The key prompt, invoked by <kbd>^B</kbd>, provides a powerful multi-functional navigation mechanism. It is case-sensitive and understands contexts, bookmarks and handy location shortcuts. | The Leader key <kbd>^B</kbd> provides a powerful multi-functional navigation mechanism. It is case-sensitive and understands contexts, bookmarks and handy location shortcuts. | ||||
| Key | Function | | | Key | Function | | ||||
|:---:| --- | | |:---:| --- | | ||||
@@ -257,8 +258,6 @@ The key prompt, invoked by <kbd>^B</kbd>, provides a powerful multi-functional n | |||||
| <kbd>&</kbd> | Go to start directory | | | <kbd>&</kbd> | Go to start directory | | ||||
| <kbd>q</kbd> | Quit context | | | <kbd>q</kbd> | Quit context | | ||||
If all the configured bookmark keys are single character, the prompt is not shown and <kbd>Enter</kbd> is not required; just press <kbd>^B</kbd> followed by the key (like the vim Leader key). | |||||
#### Contexts | #### Contexts | ||||
Contexts serve the purpose of exploring multiple directories simultaneously. 4 contexts are available. The status of the contexts are shown in the top left corner: | Contexts serve the purpose of exploring multiple directories simultaneously. 4 contexts are available. The status of the contexts are shown in the top left corner: | ||||
@@ -349,9 +348,11 @@ To lookup keyboard shortcuts at runtime, press <kbd>?</kbd>. | |||||
#### add bookmarks | #### add bookmarks | ||||
Set environment variable `NNN_BMS` as a string of `key:location` pairs (max 10) separated by semicolons (`;`): | Set environment variable `NNN_BMS` as a string of `key_char:location` pairs (max 10) separated by semicolons (`;`): | ||||
export NNN_BMS='d:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/' | |||||
export NNN_BMS='doc:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/' | NOTE: Bookmark keys should be single-character to use them in combination with the Leader key. | ||||
#### copy file paths | #### copy file paths | ||||
@@ -64,13 +64,13 @@ Pin current directory | |||||
.It Ic ^V | .It Ic ^V | ||||
Visit pinned directory | Visit pinned directory | ||||
.It Ic ^B | .It Ic ^B | ||||
Show key prompt (recognizes bookmark keys, ~, -, & and context IDs) | Leader key | ||||
.It Ic ^L | .It Ic LeaderN | ||||
Force a redraw, clear prompt | Switch to context N | ||||
.It Ic Esc | .It Ic Esc | ||||
Exit prompt | Exit prompt | ||||
.It Ic ^Bn | .It Ic ^L | ||||
Switch to context n | Force a redraw, clear prompt | ||||
.It Ic q | .It Ic q | ||||
Quit the current context | Quit the current context | ||||
.It Ic ^G | .It Ic ^G | ||||
@@ -261,10 +261,12 @@ To list the file paths copied to memory press \fIy\fR. | |||||
The SHELL, EDITOR (VISUAL, if defined) and PAGER environment variables take precedence | The SHELL, EDITOR (VISUAL, if defined) and PAGER environment variables take precedence | ||||
when dealing with the !, e and p commands respectively. | when dealing with the !, e and p commands respectively. | ||||
.Pp | .Pp | ||||
\fBNNN_BMS:\fR bookmark string as \fIkey:location\fR pairs (max 10) separated by | \fBNNN_BMS:\fR bookmark string as \fIkey_char:location\fR pairs (max 10) separated by | ||||
\fI;\fR: | \fI;\fR: | ||||
.Bd -literal | .Bd -literal | ||||
export NNN_BMS='doc:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/' | export NNN_BMS='d:~/Documents;u:/home/user/Cam Uploads;D:~/Downloads/' | ||||
NOTE: Bookmark keys should be single-character to use them in combination with the Leader key. | |||||
.Ed | .Ed | ||||
.Pp | .Pp | ||||
\fBNNN_USE_EDITOR:\fR use EDITOR (preferably CLI, fallback vi) to handle text | \fBNNN_USE_EDITOR:\fR use EDITOR (preferably CLI, fallback vi) to handle text | ||||
@@ -284,9 +286,9 @@ files. | |||||
IFS= | IFS= | ||||
echo -n $1 | xsel --clipboard --input | echo -n $1 | xsel --clipboard --input | ||||
------------------------------------- | ------------------------------------- | ||||
If it's not set, by default file paths are copied to the tmp file \fBDIR/.nnncp\fR, where 'DIR' (by priority) is: \fI$HOME\fR or, \fI$TMPDIR\fR or, \fI/tmp\fR. | |||||
.Ed | .Ed | ||||
.br | |||||
If it's not set, by default file paths are copied to the tmp file \fBDIR/.nnncp\fR, where 'DIR' (by priority) is: \fI$HOME\fR or, \fI$TMPDIR\fR or, \fI/tmp\fR. | |||||
.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. Note that the filename is not escaped. So copying may still fail | names in the shell. Note that the filename is not escaped. So copying may still fail | ||||
@@ -257,10 +257,9 @@ typedef struct { | |||||
uint quote : 1; /* Copy paths within quotes */ | uint quote : 1; /* Copy paths within quotes */ | ||||
uint color : 3; /* Color code for directories */ | uint color : 3; /* Color code for directories */ | ||||
uint ctxactive : 1; /* Context active or not */ | uint ctxactive : 1; /* Context active or not */ | ||||
uint reserved : 12; | uint reserved : 13; | ||||
/* The following settings are global */ | /* The following settings are global */ | ||||
uint curctx : 2; /* Current context number */ | uint curctx : 2; /* Current context number */ | ||||
uint char_key : 1; /* All keys are single character long */ | |||||
} settings; | } settings; | ||||
/* Contexts or workspaces */ | /* Contexts or workspaces */ | ||||
@@ -276,7 +275,7 @@ typedef struct { | |||||
/* GLOBALS */ | /* GLOBALS */ | ||||
/* Configuration, contexts */ | /* Configuration, contexts */ | ||||
static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 4, 1, 0, 0, 1}; | static settings cfg = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 4, 1, 0, 0}; | ||||
static context g_ctx[MAX_CTX] __attribute__ ((aligned)); | static context g_ctx[MAX_CTX] __attribute__ ((aligned)); | ||||
static struct entry *dents; | static struct entry *dents; | ||||
@@ -1357,12 +1356,12 @@ static size_t mkpath(char *dir, char *name, char *out, size_t n) | |||||
return (xstrlcpy(out + len, name, n - len) + len); | return (xstrlcpy(out + len, name, n - len) + len); | ||||
} | } | ||||
static void parsebmstr() | static int parsebmstr() | ||||
{ | { | ||||
int i = 0; | int i = 0; | ||||
char *bms = getenv("NNN_BMS"); | char *bms = getenv("NNN_BMS"); | ||||
if (!bms) | if (!bms) | ||||
return; | return 0; | ||||
while (*bms && i < BM_MAX) { | while (*bms && i < BM_MAX) { | ||||
bookmark[i].key = bms; | bookmark[i].key = bms; | ||||
@@ -1371,8 +1370,13 @@ static void parsebmstr() | |||||
while (*bms && *bms != ':') { | while (*bms && *bms != ':') { | ||||
++bms; | ++bms; | ||||
if (cfg.char_key) | /* | ||||
cfg.char_key = 0; | * Use single-char keys to use ^B like vim Leader key. | ||||
* Fail here to ensure keys are single char. | |||||
* To support multiple char keys remove the return | |||||
* and add appropriate check to enable smart-detect. | |||||
*/ | |||||
return -1; | |||||
} | } | ||||
if (!*bms) { | if (!*bms) { | ||||
@@ -1399,6 +1403,8 @@ static void parsebmstr() | |||||
++bms; | ++bms; | ||||
++i; | ++i; | ||||
} | } | ||||
return 0; | |||||
} | } | ||||
/* | /* | ||||
@@ -1970,8 +1976,8 @@ static int show_help(char *path) | |||||
"4→, ↵, l, ^M Open file/enter dir . Toggle show hidden\n" | "4→, ↵, l, ^M Open file/enter dir . Toggle show hidden\n" | ||||
"e/ Filter Ins, ^I Toggle nav-as-you-type\n" | "e/ Filter Ins, ^I Toggle nav-as-you-type\n" | ||||
"eb Pin current dir ^V Go to pinned dir\n" | "eb Pin current dir ^V Go to pinned dir\n" | ||||
"d^B Key prompt ^L Redraw, clear prompt\n" | "d^B Leader key LeaderN Switch to context N\n" | ||||
"cEsc Exit prompt ^Bn Switch to context n\n" | "cEsc Exit prompt ^L Redraw, clear prompt\n" | ||||
"d^G Quit and cd q Quit context\n" | "d^G Quit and cd q Quit context\n" | ||||
"aQ, ^Q Quit ? Help, settings\n" | "aQ, ^Q Quit ? Help, settings\n" | ||||
"1FILES\n" | "1FILES\n" | ||||
@@ -2711,8 +2717,8 @@ nochange: | |||||
DPRINTF_S(path); | DPRINTF_S(path); | ||||
setdirwatch(); | setdirwatch(); | ||||
goto begin; | goto begin; | ||||
case SEL_CDBM: | case SEL_LEADER: | ||||
tmp = xreadline(NULL, "key: ", cfg.char_key); | tmp = xreadline(NULL, "key: ", TRUE); | ||||
if (tmp == NULL || tmp[0] == '\0') | if (tmp == NULL || tmp[0] == '\0') | ||||
break; | break; | ||||
@@ -3453,7 +3459,10 @@ int main(int argc, char *argv[]) | |||||
} | } | ||||
/* Parse bookmarks string */ | /* Parse bookmarks string */ | ||||
parsebmstr(); | if (parsebmstr() < 0) { | ||||
fprintf(stderr, "ERROR parsing NNN_BMS: set single-char bookmark keys only\n"); | |||||
exit(1); | |||||
} | |||||
if (ipath) { /* Open a bookmark directly */ | if (ipath) { /* Open a bookmark directly */ | ||||
if (get_bm_loc(ipath, cwd) == NULL) { | if (get_bm_loc(ipath, cwd) == NULL) { | ||||
@@ -47,7 +47,7 @@ enum action { | |||||
SEL_CDHOME, | SEL_CDHOME, | ||||
SEL_CDBEGIN, | SEL_CDBEGIN, | ||||
SEL_CDLAST, | SEL_CDLAST, | ||||
SEL_CDBM, | SEL_LEADER, | ||||
SEL_PIN, | SEL_PIN, | ||||
SEL_VISIT, | SEL_VISIT, | ||||
SEL_FLTR, | SEL_FLTR, | ||||
@@ -149,8 +149,8 @@ static struct key bindings[] = { | |||||
{ '&', SEL_CDBEGIN, "", "" }, | { '&', SEL_CDBEGIN, "", "" }, | ||||
/* Last visited dir */ | /* Last visited dir */ | ||||
{ '-', SEL_CDLAST, "", "" }, | { '-', SEL_CDLAST, "", "" }, | ||||
/* Change dir using bookmark */ | /* Leader key */ | ||||
{ CONTROL('B'), SEL_CDBM, "", "" }, | { CONTROL('B'), SEL_LEADER, "", "" }, | ||||
/* Mark a path to visit later */ | /* Mark a path to visit later */ | ||||
{ 'b', SEL_PIN, "", "" }, | { 'b', SEL_PIN, "", "" }, | ||||
/* Visit marked directory */ | /* Visit marked directory */ | ||||