diff options
-rw-r--r-- | doc/ranger.pod | 9 | ||||
-rw-r--r-- | ranger/defaults/commands.py | 54 | ||||
-rw-r--r-- | ranger/help/console.py | 5 |
3 files changed, 68 insertions, 0 deletions
diff --git a/doc/ranger.pod b/doc/ranger.pod index 4bd12889..38b3ca17 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -493,6 +493,15 @@ Enable this if key combinations with the Alt Key don't work for you. =over 2 +=item bulkrename + +This command opens a list of selected files in an external editor. After you +edit and save the file, it will generate a shell script which does bulk +renaming according to the changes you did in the file. + +This shell script is opened in an editor for you to review. After you close +it, it will be executed. + =item cd [I<directory>] The cd command changes the directory. The command C<:cd -> is equivalent to diff --git a/ranger/defaults/commands.py b/ranger/defaults/commands.py index 8ab9b353..cb39ddf9 100644 --- a/ranger/defaults/commands.py +++ b/ranger/defaults/commands.py @@ -684,6 +684,60 @@ class chmod(Command): pass +class bulkrename(Command): + """ + :bulkrename + + This command opens a list of selected files in an external editor. + After you edit and save the file, it will generate a shell script + which does bulk renaming according to the changes you did in the file. + + This shell script is opened in an editor for you to review. + After you close it, it will be executed. + """ + def execute(self): + import sys + import tempfile + from ranger.fsobject.file import File + from ranger.ext.shell_escape import shell_escape as esc + py3 = sys.version > "3" + + # Create and edit the file list + filenames = [f.basename for f in self.fm.env.get_selection()] + listfile = tempfile.NamedTemporaryFile() + + if py3: + listfile.write("\n".join(filenames).encode("utf-8")) + else: + listfile.write("\n".join(filenames)) + listfile.flush() + self.fm.execute_file([File(listfile.name)], app='editor') + listfile.seek(0) + if py3: + new_filenames = listfile.read().decode("utf-8").split("\n") + else: + new_filenames = listfile.read().split("\n") + listfile.close() + if all(a == b for a, b in zip(filenames, new_filenames)): + self.fm.notify("No renaming to be done!") + return + + # Generate and execute script + cmdfile = tempfile.NamedTemporaryFile() + cmdfile.write(b"# This file will be executed when you close the editor.\n") + cmdfile.write(b"# Please double-check everything, clear the file to abort.\n") + if py3: + cmdfile.write("\n".join("mv -vi " + esc(old) + " " + esc(new) \ + for old, new in zip(filenames, new_filenames) if old != new).encode("utf-8")) + else: + cmdfile.write("\n".join("mv -vi " + esc(old) + " " + esc(new) \ + for old, new in zip(filenames, new_filenames) if old != new)) + cmdfile.flush() + self.fm.run(['vim', cmdfile.name]) + self.fm.run(['/bin/sh', cmdfile.name], flags='w') + cmdfile.close() + + class filter(Command): """ :filter <string> diff --git a/ranger/help/console.py b/ranger/help/console.py index 2f3a75c8..7ae4df28 100644 --- a/ranger/help/console.py +++ b/ranger/help/console.py @@ -39,6 +39,11 @@ unambiguous name, e.g. ":chmod" can be written as ":ch" but not as ":c" since it conflicts with ":cd". +:bulkrename + This command opens a list of selected files in an external editor. + After you edit and save the file, it will generate a shell script which + does bulk renaming according to the changes you did in the file. + :cd <dirname> Changes the directory to <dirname> |