You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
6.4KB

  1. # This is a sample commands.py. You can add your own commands here.
  2. #
  3. # Please refer to commands_full.py for all the default commands and a complete
  4. # documentation. Do NOT add them all here, or you may end up with defunct
  5. # commands when upgrading ranger.
  6. # You always need to import ranger.api.commands here to get the Command class:
  7. from ranger.api.commands import *
  8. # A simple command for demonstration purposes follows.
  9. #------------------------------------------------------------------------------
  10. # You can import any python module as needed.
  11. import os
  12. # Any class that is a subclass of "Command" will be integrated into ranger as a
  13. # command. Try typing ":my_edit<ENTER>" in ranger!
  14. class my_edit(Command):
  15. # The so-called doc-string of the class will be visible in the built-in
  16. # help that is accessible by typing "?c" inside ranger.
  17. """:my_edit <filename>
  18. A sample command for demonstration purposes that opens a file in an editor.
  19. """
  20. # The execute method is called when you run this command in ranger.
  21. def execute(self):
  22. # self.arg(1) is the first (space-separated) argument to the function.
  23. # This way you can write ":my_edit somefilename<ENTER>".
  24. if self.arg(1):
  25. # self.rest(1) contains self.arg(1) and everything that follows
  26. target_filename = self.rest(1)
  27. else:
  28. # self.fm is a ranger.core.filemanager.FileManager object and gives
  29. # you access to internals of ranger.
  30. # self.fm.thisfile is a ranger.container.file.File object and is a
  31. # reference to the currently selected file.
  32. target_filename = self.fm.thisfile.path
  33. # This is a generic function to print text in ranger.
  34. self.fm.notify("Let's edit the file " + target_filename + "!")
  35. # Using bad=True in fm.notify allows you to print error messages:
  36. if not os.path.exists(target_filename):
  37. self.fm.notify("The given file does not exist!", bad=True)
  38. return
  39. # This executes a function from ranger.core.acitons, a module with a
  40. # variety of subroutines that can help you construct commands.
  41. # Check out the source, or run "pydoc ranger.core.actions" for a list.
  42. self.fm.edit_file(target_filename)
  43. # The tab method is called when you press tab, and should return a list of
  44. # suggestions that the user will tab through.
  45. def tab(self):
  46. # This is a generic tab-completion function that iterates through the
  47. # content of the current directory.
  48. return self._tab_directory_content()
  49. class bulkrename(Command):
  50. """:bulkrename
  51. This command opens a list of selected files in an external editor.
  52. After you edit and save the file, it will generate a shell script
  53. which does bulk renaming according to the changes you did in the file.
  54. This shell script is opened in an editor for you to review.
  55. After you close it, it will be executed.
  56. """
  57. def execute(self):
  58. import sys
  59. import tempfile
  60. from ranger.container.file import File
  61. from ranger.ext.shell_escape import shell_escape as esc
  62. py3 = sys.version_info[0] >= 3
  63. # Create and edit the file list
  64. filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
  65. listfile = tempfile.NamedTemporaryFile(delete=False)
  66. listpath = listfile.name
  67. if py3:
  68. listfile.write("\n".join(filenames).encode("utf-8"))
  69. else:
  70. listfile.write("\n".join(filenames))
  71. listfile.close()
  72. self.fm.execute_file([File(listpath)], app='nvim')
  73. listfile = open(listpath, 'r')
  74. new_filenames = listfile.read().split("\n")
  75. listfile.close()
  76. os.unlink(listpath)
  77. if all(a == b for a, b in zip(filenames, new_filenames)):
  78. self.fm.notify("No renaming to be done!")
  79. return
  80. # Generate script
  81. cmdfile = tempfile.NamedTemporaryFile()
  82. script_lines = []
  83. script_lines.append("# This file will be executed when you close the editor.\n")
  84. script_lines.append("# Please double-check everything, clear the file to abort.\n")
  85. script_lines.extend("mv -vi -- %s %s\n" % (esc(old), esc(new)) \
  86. for old, new in zip(filenames, new_filenames) if old != new)
  87. script_content = "".join(script_lines)
  88. if py3:
  89. cmdfile.write(script_content.encode("utf-8"))
  90. else:
  91. cmdfile.write(script_content)
  92. cmdfile.flush()
  93. # Open the script and let the user review it, then check if the script
  94. # was modified by the user
  95. self.fm.execute_file([File(cmdfile.name)], app='nvim')
  96. cmdfile.seek(0)
  97. script_was_edited = (script_content != cmdfile.read())
  98. # Do the renaming
  99. self.fm.run(['/bin/sh', cmdfile.name], flags='w')
  100. cmdfile.close()
  101. # Retag the files, but only if the script wasn't changed during review,
  102. # because only then we know which are the source and destination files.
  103. if not script_was_edited:
  104. tags_changed = False
  105. for old, new in zip(filenames, new_filenames):
  106. if old != new:
  107. oldpath = self.fm.thisdir.path + '/' + old
  108. newpath = self.fm.thisdir.path + '/' + new
  109. if oldpath in self.fm.tags:
  110. old_tag = self.fm.tags.tags[oldpath]
  111. self.fm.tags.remove(oldpath)
  112. self.fm.tags.tags[newpath] = old_tag
  113. tags_changed = True
  114. if tags_changed:
  115. self.fm.tags.dump()
  116. else:
  117. fm.notify("files have not been retagged")
  118. class playlist(Command):
  119. """:playlist
  120. This script creates a playlist for mpv from selection
  121. """
  122. def execute(self):
  123. import sys
  124. from ranger.container.file import File
  125. from ranger.ext.shell_escape import shell_escape as esc
  126. py3 = sys.version_info[0] >= 3
  127. # Create and edit the file list
  128. filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
  129. listfile = open("playlist.play" ,'w')
  130. listfile.write("\n".join(filenames))
  131. listfile.close()
  132. self.fm.mark_files(all=True, val=False)
  133. self.fm.run('xdotool search --classname Ranger windowunmap')
  134. self.fm.run('mpv --playlist=' + listfile.name)
  135. os.unlink(listfile.name)