README.md | 2 +- plugins/README.md | 2 +- plugins/batchrename | 9 +++++++++ src/nnn.c | 25 ++++++++++++++++--------- diff --git a/README.md b/README.md index 408572cbfa721338b4c3854b1964bbbacfe44e62..1721d399cfafec905579c5d94665a66da5af49c5 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ - Convenience - Run plugins and custom commands with hotkeys - FreeDesktop compliant trash (needs trash-cli) - Cross-dir file/all/range selection - - Batch renamer (feature-limited) for selection or dir + - Batch renamer for selection or dir - Display a list of files from stdin - Copy (as), move (as), delete, archive, link selection - Dir updates, notification on cp, mv, rm completion diff --git a/plugins/README.md b/plugins/README.md index 0728fbf7ad78b3a62ad44f2a6883975d6cdaaa9e..dc6ec6459bb30a8aa4dcd6f7adaab611d01d83d7 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -27,7 +27,7 @@ | Plugin (a-z) | Description | Lang | Deps | | --- | --- | --- | --- | | autojump | Navigate to dir/path (**autojump stores navigation patterns**) | sh | autojump | -| batchrename | Batch file renamer | sh | mktemp | +| batchrename | Batch rename selection or dir entries | sh | mktemp | | boom | Play random music from dir | sh | [moc](http://moc.daper.net/) | | dups | List non-empty duplicate files in current dir | sh | find, md5sum,
sort uniq xargs | | chksum | Create and verify checksums | sh | md5sum,
sha256sum | diff --git a/plugins/batchrename b/plugins/batchrename index b22b9ae20336d5a46cb7af6390e179db5d2e833e..b9b9a845e2edc9ea613f9db4f05d35ba250ed735 100755 --- a/plugins/batchrename +++ b/plugins/batchrename @@ -2,6 +2,15 @@ #!/usr/bin/env sh # Description: An almost fully POSIX compliant batch file renamer # +# Note: nnn auto-detects and invokes this plugin if available +# +# Capabilities: +# 1. Basic file rename +# 2. Detects order change +# 3. Can move files +# 4. Can remove files +# 5. Switch number pairs to swap filenames +# # Shell: POSIX compliant # Author: KlzXS diff --git a/src/nnn.c b/src/nnn.c index d2370635d0ee0275bd844c9479995427f17f5196..c99af5a339a651c65e7713751968e0f53ab39688 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -431,6 +431,7 @@ #define UTIL_FZF 15 #define UTIL_FZY 16 #define UTIL_NTFY 17 #define UTIL_CBCP 18 +#define UTIL_BATCHRENAME 19 /* Utilities to open files, run actions */ static char * const utils[] = { @@ -469,6 +470,7 @@ "fzf", "fzy", ".ntfy", ".cbcp", + "batchrename", }; /* Common strings */ @@ -681,7 +683,7 @@ static void move_cursor(int target, int ignore_scrolloff); static inline bool getutil(char *util); static size_t mkpath(const char *dir, const char *name, char *out); static char *xgetenv(const char *name, char *fallback); -static void plugscript(const char *plugin, char *newpath, uchar flags); +static bool plugscript(const char *plugin, char *newpath, const char *path, uchar flags); /* Functions */ @@ -4206,11 +4208,15 @@ return TRUE; } -static void plugscript(const char *plugin, char *newpath, uchar flags) +static bool plugscript(const char *plugin, char *newpath, const char *path, uchar flags) { mkpath(plugindir, plugin, newpath); - if (!access(newpath, X_OK)) - spawn(newpath, NULL, NULL, NULL, flags); + if (!access(newpath, X_OK)) { + spawn(newpath, NULL, NULL, path, flags); + return TRUE; + } + + return FALSE; } static void launch_app(const char *path, char *newpath) @@ -5601,7 +5607,8 @@ break; case SEL_RENAMEMUL: endselection(); - if (!batch_rename(path)) { + if (!plugscript(utils[UTIL_BATCHRENAME], newpath, path, F_CLI) + && !batch_rename(path)) { printwait(messages[MSG_FAILED], &presel); goto nochange; } @@ -5657,7 +5664,7 @@ writesel(NULL, 0); } if (cfg.x11) - plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE); + plugscript(utils[UTIL_CBCP], newpath, NULL, F_NOWAIT | F_NOTRACE); if (!nselected) unlink(selpath); @@ -5733,7 +5740,7 @@ } writesel(pselbuf, selbufpos - 1); /* Truncate NULL from end */ if (cfg.x11) - plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE); + plugscript(utils[UTIL_CBCP], newpath, NULL, F_NOWAIT | F_NOTRACE); continue; case SEL_SELEDIT: r = editselection(); @@ -5742,7 +5749,7 @@ r = !r ? MSG_0_SELECTED : MSG_FAILED; printwait(messages[r], &presel); } else { if (cfg.x11) - plugscript(utils[UTIL_CBCP], newpath, F_NOWAIT | F_NOTRACE); + plugscript(utils[UTIL_CBCP], newpath, NULL, F_NOWAIT | F_NOTRACE); cfg.filtermode ? presel = FILTER : statusbar(path); } goto nochange; @@ -5788,7 +5795,7 @@ clearfilter(); /* Show notification on operation complete */ if (cfg.x11) - plugscript(utils[UTIL_NTFY], newpath, F_NOWAIT | F_NOTRACE); + plugscript(utils[UTIL_NTFY], newpath, NULL, F_NOWAIT | F_NOTRACE); if (ndents) copycurname();