From 5bebd4ac67c760a846e0b6ff4e49dc338aeed50e Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Thu, 24 Oct 2019 12:39:31 +0530 Subject: [PATCH] Extend plugin mechanism to arbitrary commands --- README.md | 4 ++-- plugins/README.md | 10 +++++++--- src/nnn.c | 14 +++++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 04cae24c..af10e676 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Add to that an awesome [Wiki](https://github.com/jarun/nnn/wiki)! - Detailed file information - Media information (using plugin) - Convenience - - Plugins with configurable keybinds + - Run plugins (or commands) with configurable keybinds - FreeDesktop compliant trash (needs trash-cli) - SSHFS mounts (needs sshfs) - Cross-dir file/all/range selection @@ -147,7 +147,7 @@ There is no config file. Associated files are stored under `${XDG_CONFIG_HOME:-$ | Example `export` | Description | | --- | --- | | `NNN_BMS='d:~/Documents;D:~/Docs archive/'` | key-bookmark pairs [max 10] | -| `NNN_PLUG='o:fzy-open;p:mocplay;m:nmount;t:thumb'` | key-plugin pairs (:key to run) [max 10] | +| `NNN_PLUG='o:fzy-open;p:mocplay;m:nmount;t:thumb'` | key-plugin pairs (:key to run) [max 15] | | `NNN_USE_EDITOR=1` | open text files in `$VISUAL` (else `$EDITOR`, fallback vi) | | `NNN_CONTEXT_COLORS='1234'` | specify per context color [default: '4444' (all blue)] | | `NNN_SSHFS_OPTS='sshfs -o reconnect,idmap=user'` | specify SSHFS options | diff --git a/plugins/README.md b/plugins/README.md index 5c166767..7986fdb5 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -66,6 +66,10 @@ Plugins are installed to `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`. You ca With this, plugin `fzy-open` can be run with the keybind :o, `mocplay` can be run with :p and so on... The key vs. plugin pairs are shown in the help and config screen. Up to 10 plugins can have such keybinds. +To assign keys to arbitrary commands (non-shell interpreted) and invoke like plugins, add `_` (underscore) before the command. For example: + + export NNN_PLUG='x:_chmod +x;o:fzy-open' + **Method 2:** Use the _pick plugin_ shortcut to visit the plugin directory and execute a plugin. Repeating the same shortcut cancels the operation and puts you back in the original directory. ## Create your own plugins @@ -105,7 +109,7 @@ There are many plugins provided by `nnn` which can be used as examples. Here are #!/usr/bin/env sh git log -p -- "$1" ``` - + - Change to directory in clipboard using helper script ```sh #!/usr/bin/env sh @@ -121,13 +125,13 @@ There are many plugins provided by `nnn` which can be used as examples. Here are nnn_cd "$(dirname $(readlink -fn $1))" 0 ``` - + - Change to arbitrary directory without helper script ```sh #!/usr/bin/env sh echo -n "cd to: " read dir - + echo -n "0$dir" > $NNN_PIPE ``` diff --git a/src/nnn.c b/src/nnn.c index aa4c513e..c5a59c74 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -128,7 +128,7 @@ #define MSGWAIT '$' #define REGEX_MAX 48 #define BM_MAX 10 -#define PLUGIN_MAX 10 +#define PLUGIN_MAX 15 #define ENTRY_INCR 64 /* Number of dir 'entry' structures to allocate per shot */ #define NAMEBUF_INCR 0x800 /* 64 dir entries at once, avg. 32 chars per filename = 64*32B = 2KB */ #define DESCRIPTOR_LEN 32 @@ -4941,13 +4941,21 @@ nochange: } if (sel == SEL_PLUGKEY) { + uchar flag = F_NORMAL; + r = get_input(""); tmp = get_kv_val(plug, NULL, r, PLUGIN_MAX, FALSE); if (!tmp) goto nochange; - mkpath(plugindir, tmp, newpath); - spawn(newpath, (ndents ? dents[cur].name : NULL), path, path, F_NORMAL); + if (tmp[0] == '_' && tmp[1]) { + xstrlcpy(newpath, ++tmp, PATH_MAX); + flag = F_CLI | F_CONFIRM; + } else + mkpath(plugindir, tmp, newpath); + + spawn(newpath, (ndents ? dents[cur].name : NULL), + path, path, flag); if (cfg.filtermode) presel = FILTER;