@@ -63,19 +63,19 @@ Plugins are installed to `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`. | |||||
| vidthumb | Show video thumbnails in terminal | sh | [ffmpegthumbnailer](https://github.com/dirkvdb/ffmpegthumbnailer),<br>[lsix](https://github.com/hackerb9/lsix) | | | vidthumb | Show video thumbnails in terminal | sh | [ffmpegthumbnailer](https://github.com/dirkvdb/ffmpegthumbnailer),<br>[lsix](https://github.com/hackerb9/lsix) | | ||||
| wall | Set wallpaper or change colorscheme | sh | nitrogen/pywal | | | wall | Set wallpaper or change colorscheme | sh | nitrogen/pywal | | ||||
## Ways to invoke a plugin | ## Invoking a plugin | ||||
1. Fire directly with <kbd>;key</kbd> or <kbd>^Fkey</kbd>: | Use the plugin shortcut (<kbd>;key</kbd> or <kbd>;key</kbd>) to list the defined plugin keys and press the required key. E.g., with the below config: | ||||
export NNN_PLUG='o:fzopen;p:mocplay;d:diffs;m:nmount;n:notes;v:imgviu;t:imgthumb' | export NNN_PLUG='o:fzopen;p:mocplay;d:diffs;m:nmount;n:notes;v:imgviu;t:imgthumb' | ||||
Now plugin `fzopen` can be run with the keybind <kbd>;o</kbd>, `mocplay` can be run with <kbd>;p</kbd> and so on... The key vs. plugin pairs are shown in the help and config screen. | Plugin `fzopen` can be run with the keybind <kbd>;o</kbd>, `mocplay` can be run with <kbd>;p</kbd> and so on... The key vs. plugin pairs are shown in the help and config screen. | ||||
2. Use the _pick plugin_ keybind to visit the plugin directory, select and run a plugin. Repeat the keybind to cancel and return to the original directory. | A maximum of 15 keys can be defined. To select and invoke a plugin from the plugin directory, press <kbd>Enter</kbd> (to _enter_ the plugin dir) after the plugin shortcut. | ||||
#### Skip directory refresh after running a plugin | #### Skip directory refresh after running a plugin | ||||
`nnn` refreshes a directory after running a plugin by key (method 1 above) to reflect any changes by the plugin. To disable this (say while running the `mediainfo` plugin on some filtered files), add a `-` before the plugin name: | `nnn` refreshes the directory after running a plugin to reflect any changes by the plugin. To disable this (say while running the `mediainfo` plugin on some filtered files), add a `-` before the plugin name: | ||||
export NNN_PLUG='m:-mediainfo' | export NNN_PLUG='m:-mediainfo' | ||||
@@ -3613,10 +3613,10 @@ static void show_help(const char *path) | |||||
"cX Delete sel%-13c^X Delete entry\n" | "cX Delete sel%-13c^X Delete entry\n" | ||||
"9o ^T Order toggle%-11c^Y List, edit sel\n" | "9o ^T Order toggle%-11c^Y List, edit sel\n" | ||||
"1MISC\n" | "1MISC\n" | ||||
"9! ^] Shell%-16c; ^F Fire plugin\n" | "9; ^P Plugin%-18c= Launch app\n" | ||||
"c] Cmd prompt%-13c^P Pick plugin\n" | "9! ^] Shell%-19c] Cmd prompt\n" | ||||
"cs Manage session%-10c= Launch app\n" | "cs Manage session%-10cu Unmount\n" | ||||
"cc Connect remote%-10cu Unmount\n" | "cc Connect remote%-0c\n" | ||||
}; | }; | ||||
fd = create_tmp_file(); | fd = create_tmp_file(); | ||||
@@ -5477,7 +5477,6 @@ nochange: | |||||
goto begin; | goto begin; | ||||
} | } | ||||
case SEL_PLUGKEY: // fallthrough | |||||
case SEL_PLUGIN: | case SEL_PLUGIN: | ||||
/* Check if directory is accessible */ | /* Check if directory is accessible */ | ||||
if (!xdiraccess(plugindir)) { | if (!xdiraccess(plugindir)) { | ||||
@@ -5485,12 +5484,12 @@ nochange: | |||||
goto nochange; | goto nochange; | ||||
} | } | ||||
if (sel == SEL_PLUGKEY) { | r = xstrlcpy(g_buf, messages[MSG_PLUGIN_KEYS], CMD_LEN_MAX); | ||||
printkeys(plug, g_buf + r - 1, PLUGIN_MAX); | |||||
printprompt(g_buf); | |||||
r = get_input(NULL); | |||||
if (r != '\r') { | |||||
endselection(); | endselection(); | ||||
r = xstrlcpy(g_buf, messages[MSG_PLUGIN_KEYS], CMD_LEN_MAX); | |||||
printkeys(plug, g_buf + r - 1, PLUGIN_MAX); | |||||
printprompt(g_buf); | |||||
r = get_input(NULL); | |||||
tmp = get_kv_val(plug, NULL, r, PLUGIN_MAX, FALSE); | tmp = get_kv_val(plug, NULL, r, PLUGIN_MAX, FALSE); | ||||
if (!tmp) { | if (!tmp) { | ||||
printwait(messages[MSG_INVALID_KEY], &presel); | printwait(messages[MSG_INVALID_KEY], &presel); | ||||
@@ -5517,7 +5516,7 @@ nochange: | |||||
if (ndents) | if (ndents) | ||||
copycurname(); | copycurname(); | ||||
} else { | } else { /* 'Return/Enter' enters the plugin directory */ | ||||
cfg.runplugin ^= 1; | cfg.runplugin ^= 1; | ||||
if (!cfg.runplugin && rundir[0]) { | if (!cfg.runplugin && rundir[0]) { | ||||
/* | /* | ||||
@@ -85,7 +85,6 @@ enum action { | |||||
SEL_REMOTE, | SEL_REMOTE, | ||||
SEL_UMOUNT, | SEL_UMOUNT, | ||||
SEL_HELP, | SEL_HELP, | ||||
SEL_PLUGKEY, | |||||
SEL_PLUGIN, | SEL_PLUGIN, | ||||
SEL_SHELL, | SEL_SHELL, | ||||
SEL_LAUNCH, | SEL_LAUNCH, | ||||
@@ -217,10 +216,8 @@ static struct key bindings[] = { | |||||
{ 'u', SEL_UMOUNT }, | { 'u', SEL_UMOUNT }, | ||||
/* Show help */ | /* Show help */ | ||||
{ '?', SEL_HELP }, | { '?', SEL_HELP }, | ||||
/* Plugin key */ | |||||
{ ';', SEL_PLUGKEY }, | |||||
{ CONTROL('F'), SEL_PLUGKEY }, | |||||
/* Run a plugin */ | /* Run a plugin */ | ||||
{ ';', SEL_PLUGIN }, | |||||
{ CONTROL('P'), SEL_PLUGIN }, | { CONTROL('P'), SEL_PLUGIN }, | ||||
/* Run command */ | /* Run command */ | ||||
{ '!', SEL_SHELL }, | { '!', SEL_SHELL }, | ||||