From 827e84a56f17770982f543bcd2053a7e2fcd5add Mon Sep 17 00:00:00 2001 From: KlzXS Date: Wed, 25 Jan 2023 17:15:38 +0100 Subject: [PATCH] Simplify commands as plugins Remove restrictions on $nnn Update the plugin README --- plugins/README.md | 36 ++++++++++++++++-------------------- src/nnn.c | 14 ++++++++------ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/plugins/README.md b/plugins/README.md index ca5af90b..2a7aeef9 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -119,7 +119,7 @@ If the plugins list gets too long, try breaking them up into sections: ``` NNN_PLUG_PERSONAL='g:personal/convert2zoom;p:personal/echo' NNN_PLUG_WORK='j:work/prettyjson;d:work/foobar' -NNN_PLUG_INLINE='e:!go run $nnn*' +NNN_PLUG_INLINE='e:!go run "$nnn"*' NNN_PLUG_DEFAULT='1:ipinfo;p:preview-tui;o:fzz;b:nbak' NNN_PLUG="$NNN_PLUG_PERSONAL;$NNN_PLUG_WORK;$NNN_PLUG_DEFAULT;$NNN_PLUG_INLINE" export NNN_PLUG @@ -144,7 +144,7 @@ export NNN_PLUG='p:-plugin' To assign keys to arbitrary non-background cli commands and invoke like plugins, add `!` (underscore) before the command. ```sh -export NNN_PLUG='x:!chmod +x $nnn;g:!git log;s:!smplayer $nnn' +export NNN_PLUG='x:!chmod +x "$nnn";g:!git log;s:!smplayer "$nnn"' ``` Now ;x can be used to make a file executable, ;g can be used to the git log of a git project directory, ;s can be used to preview a partially downloaded media file. @@ -154,56 +154,52 @@ Now ;x can be used to make a file executable, ;g can be us `nnn` waits for user confirmation (the prompt `Press Enter to continue`) after it executes a command as plugin (unlike plugins which can add a `read` to wait). To skip this, add a `*` after the command. ```sh -export NNN_PLUG='s:!smplayer $nnn*;n:-!vim /home/vaio/Dropbox/Public/synced_note*' +export NNN_PLUG='s:!smplayer "$nnn"*;n:-!vim /home/vaio/Dropbox/Public/synced_note*' ``` Now there will be no prompt after ;s and ;n. -Note: Do not use `*` with programs those run and exit e.g. cat. +Note: Do not use `*` with programs that run and exit e.g. cat. #### Run a GUI app as plugin [`&`] To run a GUI app as plugin, add a `&` after `!`. ```sh -export NNN_PLUG='m:-!&mousepad $nnn' +export NNN_PLUG='m:-!&mousepad "$nnn"' ``` -`$nnn` must be the last argument in this case. - #### Page non-interactive command output [`|`] To show the output of run-and-exit commands which do not need user input, add `|` (pipe) after `!`. ```sh -export NNN_PLUG='m:-!|mediainfo $nnn;t:-!|tree -ps;l:-!|ls -lah --group-directories-first' +export NNN_PLUG='m:-!|mediainfo "$nnn";t:-!|tree -ps;l:-!|ls -lah --group-directories-first' ``` This option is incompatible with `&` (terminal output is masked for GUI programs) and ignores `*` (output is already paged for user). -`$nnn` must be the last argument in this case as well. Notes: -1. Use single quotes for `$NNN_PLUG` so `$nnn` is not interpreted -2. `$nnn` must be the last argument (if used) to run a _GUI app as plugin_ or to page non-interactive command output -3. (_Again_) add `!` before the command -4. To disable directory refresh after running a _command as plugin_, prefix with `-!` +1. Use single quotes for `$NNN_PLUG` so `"$nnn"` is not interpreted +2. (_Again_) add `!` before the command +3. To disable directory refresh after running a _command as plugin_, prefix with `-!` #### Some useful key-command examples | Key:Command | Description | |---|---| -| `c:!convert $nnn png:- \| xclip -sel clipboard -t image/png*` | Copy image to clipboard | +| `c:!convert "$nnn" png:- \| xclip -sel clipboard -t image/png*` | Copy image to clipboard | | `C:!cp -rv "$nnn" "$nnn".cp` | Create a copy of the hovered file | -| `e:-!sudo -E vim $nnn*` | Edit file as root in vim | +| `e:-!sudo -E vim "$nnn"*` | Edit file as root in vim | | `g:-!git diff` | Show git diff | -| `h:-!hx $nnn*` | Open hovered file in [hx](https://github.com/krpors/hx) hex editor | -| `k:-!fuser -kiv $nnn*` | Interactively kill process(es) using hovered file | +| `h:-!hx "$nnn"*` | Open hovered file in [hx](https://github.com/krpors/hx) hex editor | +| `k:-!fuser -kiv "$nnn"*` | Interactively kill process(es) using hovered file | | `l:-!git log` | Show git log | | `n:-!vi /home/user/Dropbox/dir/note*` | Take quick notes in a synced file/dir of notes | -| `p:-!less -iR $nnn*` | Page through hovered file in less | -| `s:-!&smplayer -minigui $nnn` | Play hovered media file, even unfinished download | -| `x:!chmod +x $nnn` | Make the hovered file executable | +| `p:-!less -iR "$nnn"*` | Page through hovered file in less | +| `s:-!&smplayer -minigui "$nnn"` | Play hovered media file, even unfinished download | +| `x:!chmod +x "$nnn"` | Make the hovered file executable | | `y:-!sync*` | Flush cached writes | ## Access level of plugins diff --git a/src/nnn.c b/src/nnn.c index a5a8d770..24e6d72d 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -5172,17 +5172,19 @@ static void run_cmd_as_plugin(const char *file, char *runfile, uchar_t flags) --len; } - if ((flags & F_PAGE) || (flags & F_NOTRACE)) { - if (is_suffix(g_buf, " $nnn")) - g_buf[len - 5] = '\0'; - else - runfile = NULL; + /* This is to catch the old way of doing things so we don't break users' configs */ + if ((flags & (F_PAGE | F_NOTRACE)) && is_suffix(g_buf, " $nnn")) { + g_buf[len - 5] = '\0'; if (flags & F_PAGE) get_output(g_buf, runfile, NULL, -1, TRUE, TRUE); else // F_NOTRACE spawn(g_buf, runfile, NULL, NULL, flags); - } else + } + + if (flags & F_PAGE) + get_output(utils[UTIL_SH_EXEC], g_buf, NULL, -1, TRUE); + else spawn(utils[UTIL_SH_EXEC], g_buf, NULL, NULL, flags); }