From 9c0aa71cc106f6aac7d356bf5858e50a7c53df58 Mon Sep 17 00:00:00 2001 From: DarkWiiPlayer Date: Mon, 27 Feb 2023 10:15:29 +0100 Subject: [PATCH] Add ranger commands file --- ranger/commands.py | 145 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 ranger/commands.py diff --git a/ranger/commands.py b/ranger/commands.py new file mode 100644 index 0000000..9b78841 --- /dev/null +++ b/ranger/commands.py @@ -0,0 +1,145 @@ +# This is a sample commands.py. You can add your own commands here. +# +# Please refer to commands_full.py for all the default commands and a complete +# documentation. Do NOT add them all here, or you may end up with defunct +# commands when upgrading ranger. + +# You always need to import ranger.api.commands here to get the Command class: +from ranger.api.commands import * + +# A simple command for demonstration purposes follows. +# ----------------------------------------------------------------------------- + +# You can import any python module as needed. +import os + +# Any class that is a subclass of "Command" will be integrated into ranger as a +# command. Try typing ":my_edit" in ranger! + + +class my_edit(Command): + # The so-called doc-string of the class will be visible in the built-in + # help that is accessible by typing "?c" inside ranger. + """:my_edit + + A sample command for demonstration purposes that opens a file in an editor. + """ + + # The execute method is called when you run this command in ranger. + def execute(self): + # self.arg(1) is the first (space-separated) argument to the function. + # This way you can write ":my_edit somefilename". + if self.arg(1): + # self.rest(1) contains self.arg(1) and everything that follows + target_filename = self.rest(1) + else: + # self.fm is a ranger.core.filemanager.FileManager object and gives + # you access to internals of ranger. + # self.fm.thisfile is a ranger.container.file.File object and is a + # reference to the currently selected file. + target_filename = self.fm.thisfile.path + + # This is a generic function to print text in ranger. + self.fm.notify("Let's edit the file " + target_filename + "!") + + # Using bad=True in fm.notify allows you to print error messages: + if not os.path.exists(target_filename): + self.fm.notify("The given file does not exist!", bad=True) + return + + # This executes a function from ranger.core.acitons, a module with a + # variety of subroutines that can help you construct commands. + # Check out the source, or run "pydoc ranger.core.actions" for a list. + self.fm.edit_file(target_filename) + + # The tab method is called when you press tab, and should return a list of + # suggestions that the user will tab through. + # tabnum is 1 for and -1 for by default + def tab(self, tabnum): + # This is a generic tab-completion function that iterates through the + # content of the current directory. + return self._tab_directory_content() + +class mark_fzf(Command): + """ + `:fzf_mark` refer from `:fzf_select` (But Just in `Current directory and Not Recursion`) + so just `find` is enough instead of `fdfind`) + + `:fzf_mark` can One/Multi/All Selected & Marked files of current dir that filterd by `fzf extended-search mode` + fzf extended-search mode: https://github.com/junegunn/fzf#search-syntax + eg: py 'py .py ^he py$ !py !^py + In addition: + there is a delay in using `get_executables` (So I didn't use it) + so there is no compatible alias. + but find is builtin command, so you just consider your `fzf` name + Usage + :fzf_mark + + shortcut in fzf_mark: + : select all + : deselect all + : multiple select + : reverse multiple select + ... : and some remap for movement + """ + + def execute(self): + # from pathlib import Path # Py3.4+ + import os + import subprocess + + fzf_name = "fzf" + + hidden = ('-false' if self.fm.settings.show_hidden else r"-path '*/\.*' -prune") + exclude = r"\( -name '\.git' -o -iname '\.*py[co]' -o -fstype 'dev' -o -fstype 'proc' \) -prune" + only_directories = ('-type d' if self.quantifier else '') + fzf_default_command = 'find -L . -mindepth 1 -type d -prune {} -o {} -o {} -print | cut -b3-'.format( + hidden, exclude, only_directories + ) + + env = os.environ.copy() + env['FZF_DEFAULT_COMMAND'] = fzf_default_command + + # you can remap and config your fzf (and your can still use ctrl+n / ctrl+p ...) + preview + env['FZF_DEFAULT_OPTS'] = '\ + --multi \ + --reverse \ + --bind ctrl-a:select-all,ctrl-e:deselect-all,alt-n:down,alt-p:up,alt-o:backward-delete-char,alt-h:beginning-of-line,alt-l:end-of-line,alt-j:backward-char,alt-k:forward-char,alt-b:backward-word,alt-f:forward-word \ + --height 95% \ + --layout reverse \ + --border \ + --preview "cat {} | head -n 100"' + # if use bat instead of cat, you need install it + # --preview "bat --style=numbers --color=always --line-range :500 {}"' + + fzf = self.fm.execute_command(fzf_name, env=env, universal_newlines=True, stdout=subprocess.PIPE) + stdout, _ = fzf.communicate() + + if fzf.returncode == 0: + filename_list = stdout.strip().split() + for filename in filename_list: + # Python3.4+ + # self.fm.select_file( str(Path(filename).resolve()) ) + self.fm.select_file( os.path.abspath(filename) ) + self.fm.mark_files(all=False,toggle=True) + +class mark_grep(Command): + """ + TODO: Write + """ + + def execute(self): + import os + import subprocess + + env = os.environ.copy() + + command = 'grep {} {} | cut -f 1 -d :'.format(self.rest(1), "*") + fzf = self.fm.execute_command(command, env=env, universal_newlines=True, stdout=subprocess.PIPE) + stdout, _ = fzf.communicate() + + if fzf.returncode == 0: + filename_list = stdout.strip().split() + for filename in filename_list: + self.fm.select_file(os.path.abspath(filename)) + self.fm.mark_files(all=False,toggle=True)