Advertisement
mosaid

command.py

Feb 28th, 2020
452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.93 KB | None | 0 0
  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.  
  7. # A simple command for demonstration purposes follows.
  8. # -----------------------------------------------------------------------------
  9.  
  10. from __future__ import absolute_import, division, print_function
  11.  
  12. # You can import any python module as needed.
  13. import os
  14.  
  15. # You always need to import ranger.api.commands here to get the Command class:
  16. from ranger.api.commands import Command
  17.  
  18.  
  19. # Any class that is a subclass of "Command" will be integrated into ranger as a
  20. # command.  Try typing ":my_edit<ENTER>" in ranger!
  21. class my_edit(Command):
  22.     # The so-called doc-string of the class will be visible in the built-in
  23.     # help that is accessible by typing "?c" inside ranger.
  24.     """:my_edit <filename>
  25.  
  26.    A sample command for demonstration purposes that opens a file in an editor.
  27.    """
  28.  
  29.     # The execute method is called when you run this command in ranger.
  30.     def execute(self):
  31.         # self.arg(1) is the first (space-separated) argument to the function.
  32.         # This way you can write ":my_edit somefilename<ENTER>".
  33.         if self.arg(1):
  34.             # self.rest(1) contains self.arg(1) and everything that follows
  35.             target_filename = self.rest(1)
  36.         else:
  37.             # self.fm is a ranger.core.filemanager.FileManager object and gives
  38.             # you access to internals of ranger.
  39.             # self.fm.thisfile is a ranger.container.file.File object and is a
  40.             # reference to the currently selected file.
  41.             target_filename = self.fm.thisfile.path
  42.  
  43.         # This is a generic function to print text in ranger.
  44.         self.fm.notify("Let's edit the file " + target_filename + "!")
  45.  
  46.         # Using bad=True in fm.notify allows you to print error messages:
  47.         if not os.path.exists(target_filename):
  48.             self.fm.notify("The given file does not exist!", bad=True)
  49.             return
  50.  
  51.         # This executes a function from ranger.core.acitons, a module with a
  52.         # variety of subroutines that can help you construct commands.
  53.         # Check out the source, or run "pydoc ranger.core.actions" for a list.
  54.         self.fm.edit_file(target_filename)
  55.  
  56.     # The tab method is called when you press tab, and should return a list of
  57.     # suggestions that the user will tab through.
  58.     # tabnum is 1 for <TAB> and -1 for <S-TAB> by default
  59.     def tab(self, tabnum):
  60.         # This is a generic tab-completion function that iterates through the
  61.         # content of the current directory.
  62.         return self._tab_directory_content()
  63.  
  64.  
  65. class terminal(Command):
  66.     """
  67.    :terminal
  68.  
  69.    Open new tmux split in the current directory.
  70.    """
  71.  
  72.     def execute(self):
  73.         import os
  74.         from ranger.ext.get_executables import get_executables
  75.  
  76.         command = "lxterminal"
  77.         self.fm.run(command, flags="f")
  78.  
  79.  
  80. # https://github.com/ranger/ranger/wiki/Integrating-File-Search-with-fzf
  81. # Now, simply bind this function to a key, by adding this to your ~/.config/ranger/rc.conf:
  82. # map <C-f> fzf_select
  83. class fzf_select(Command):
  84.     """
  85.    :fzf_select
  86.  
  87.    Find a file using fzf.
  88.  
  89.    With a prefix argument select only directories.
  90.  
  91.    See: https://github.com/junegunn/fzf
  92.    """
  93.  
  94.     def execute(self):
  95.         import subprocess
  96.  
  97.         if self.quantifier:
  98.             # match only directories
  99.             command = "find -L . \( -path '*/\.*' -o -fstype 'dev' -o -fstype 'proc' \) -prune \
  100.            -o -type d -print 2> /dev/null | sed 1d | cut -b3- | fzf +m"
  101.         else:
  102.             # match files and directories
  103.             command = "find -L . \( -path '*/\.*' -o -fstype 'dev' -o -fstype 'proc' \) -prune \
  104.            -o -print 2> /dev/null | sed 1d | cut -b3- | fzf +m"
  105.         fzf = self.fm.execute_command(command, stdout=subprocess.PIPE)
  106.         stdout, stderr = fzf.communicate()
  107.         if fzf.returncode == 0:
  108.             fzf_file = os.path.abspath(stdout.decode("utf-8").rstrip("\n"))
  109.             if os.path.isdir(fzf_file):
  110.                 self.fm.cd(fzf_file)
  111.             else:
  112.                 self.fm.select_file(fzf_file)
  113.  
  114.  
  115. # fzf_locate
  116. class fzf_locate(Command):
  117.     """
  118.    :fzf_locate
  119.  
  120.    Find a file using fzf.
  121.  
  122.    With a prefix argument select only directories.
  123.  
  124.    See: https://github.com/junegunn/fzf
  125.    """
  126.  
  127.     def execute(self):
  128.         import subprocess
  129.  
  130.         if self.quantifier:
  131.             command = "locate home media | fzf -e -i"
  132.         else:
  133.             command = "locate home media | fzf -e -i"
  134.         fzf = self.fm.execute_command(command, stdout=subprocess.PIPE)
  135.         stdout, stderr = fzf.communicate()
  136.         if fzf.returncode == 0:
  137.             fzf_file = os.path.abspath(stdout.decode("utf-8").rstrip("\n"))
  138.             if os.path.isdir(fzf_file):
  139.                 self.fm.cd(fzf_file)
  140.             else:
  141.                 self.fm.select_file(fzf_file)
  142.  
  143.  
  144. # fzf_fasd - Fasd + Fzf + Ranger (Interactive Style)
  145. class fzf_fasd(Command):
  146.     """
  147.    :fzf_fasd
  148.  
  149.    Jump to a file or folder using Fasd and fzf
  150.  
  151.    URL: https://github.com/clvv/fasd
  152.    URL: https://github.com/junegunn/fzf
  153.    """
  154.  
  155.     def execute(self):
  156.         import subprocess
  157.  
  158.         if self.quantifier:
  159.             command = "fasd | fzf -e -i --tac --no-sort | awk '{print $2}'"
  160.         else:
  161.             command = "fasd | fzf -e -i --tac --no-sort | awk '{print $2}'"
  162.         fzf = self.fm.execute_command(command, stdout=subprocess.PIPE)
  163.         stdout, stderr = fzf.communicate()
  164.         if fzf.returncode == 0:
  165.             fzf_file = os.path.abspath(stdout.decode("utf-8").rstrip("\n"))
  166.             if os.path.isdir(fzf_file):
  167.                 self.fm.cd(fzf_file)
  168.             else:
  169.                 self.fm.select_file(fzf_file)
  170.  
  171.  
  172. # Fasd with ranger (Command Line Style)
  173. # https://github.com/ranger/ranger/wiki/Commands
  174.  
  175.  
  176. class fasd(Command):
  177.     """
  178.    :fasd
  179.  
  180.    Jump to directory using fasd
  181.    URL: https://github.com/clvv/fasd
  182.    """
  183.  
  184.     def execute(self):
  185.         import subprocess
  186.  
  187.         arg = self.rest(1)
  188.         if arg:
  189.             directory = subprocess.check_output(
  190.                 ["fasd", "-d"] + arg.split(), universal_newlines=True
  191.             ).strip()
  192.             self.fm.cd(directory)
  193.  
  194.  
  195. from collections import deque
  196.  
  197. fd_deq = deque()
  198.  
  199.  
  200. class fd_search(Command):
  201.     """
  202.    :fd_search [-d<depth>] <query>
  203.  
  204.    Executes "fd -d<depth> <query>" in the current directory and focuses the
  205.    first match. <depth> defaults to 1, i.e. only the contents of the current
  206.    directory.
  207.    """
  208.  
  209.     def execute(self):
  210.         import subprocess
  211.         from ranger.ext.get_executables import get_executables
  212.  
  213.         if not "fd" in get_executables():
  214.             self.fm.notify("Couldn't find fd on the PATH.", bad=True)
  215.             return
  216.         if self.arg(1):
  217.             if self.arg(1)[:2] == "-d":
  218.                 depth = self.arg(1)
  219.                 target = self.rest(2)
  220.             else:
  221.                 depth = "-d1"
  222.                 target = self.rest(1)
  223.         else:
  224.             self.fm.notify(":fd_search needs a query.", bad=True)
  225.             return
  226.  
  227.         # For convenience, change which dict is used as result_sep to change
  228.         # fd's behavior from splitting results by \0, which allows for newlines
  229.         # in your filenames to splitting results by \n, which allows for \0 in
  230.         # filenames.
  231.         null_sep = {"arg": "-0", "split": "\0"}
  232.         nl_sep = {"arg": "", "split": "\n"}
  233.         result_sep = null_sep
  234.  
  235.         process = subprocess.Popen(
  236.             ["fd", result_sep["arg"], depth, target],
  237.             universal_newlines=True,
  238.             stdout=subprocess.PIPE,
  239.         )
  240.         (search_results, _err) = process.communicate()
  241.         global fd_deq
  242.         fd_deq = deque(
  243.             (
  244.                 self.fm.thisdir.path + os.sep + rel
  245.                 for rel in sorted(
  246.                     search_results.split(result_sep["split"]), key=str.lower
  247.                 )
  248.                 if rel != ""
  249.             )
  250.         )
  251.         if len(fd_deq) > 0:
  252.             self.fm.select_file(fd_deq[0])
  253.  
  254.  
  255. class fd_next(Command):
  256.     """
  257.    :fd_next
  258.  
  259.    Selects the next match from the last :fd_search.
  260.    """
  261.  
  262.     def execute(self):
  263.         if len(fd_deq) > 1:
  264.             fd_deq.rotate(-1)  # rotate left
  265.             self.fm.select_file(fd_deq[0])
  266.         elif len(fd_deq) == 1:
  267.             self.fm.select_file(fd_deq[0])
  268.  
  269.  
  270. class fd_prev(Command):
  271.     """
  272.    :fd_prev
  273.  
  274.    Selects the next match from the last :fd_search.
  275.    """
  276.  
  277.     def execute(self):
  278.         if len(fd_deq) > 1:
  279.             fd_deq.rotate(1)  # rotate right
  280.             self.fm.select_file(fd_deq[0])
  281.         elif len(fd_deq) == 1:
  282.             self.fm.select_file(fd_deq[0])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement