from ranger.api.commands import Command from ranger.container.file import File from ranger.ext.get_executables import get_executables from collections import deque import os import subprocess # fd search class fd_search(Command): """ :fd_search [-d] Executes "fd -d " in the current directory and focuses the first match. defaults to 1, i.e. only the contents of the current directory. See https://github.com/sharkdp/fd """ SEARCH_RESULTS = deque() def execute(self): import re import subprocess from ranger.ext.get_executables import get_executables self.SEARCH_RESULTS.clear() if "fdfind" in get_executables(): fd = "fdfind" elif "fd" in get_executables(): fd = "fd" else: self.fm.notify("Couldn't find fd in the PATH.", bad=True) return if self.arg(1): if self.arg(1)[:2] == "-d": depth = self.arg(1) target = self.rest(2) else: depth = "-d1" target = self.rest(1) else: self.fm.notify(":fd_search needs a query.", bad=True) return hidden = "--hidden" if self.fm.settings.show_hidden else "" exclude = "--no-ignore-vcs --exclude '.git' --exclude '*.py[co]' --exclude '__pycache__'" command = "{} --follow {} {} {} --print0 {}".format( fd, depth, hidden, exclude, target ) fd = self.fm.execute_command( command, universal_newlines=True, stdout=subprocess.PIPE ) stdout, _ = fd.communicate() if fd.returncode == 0: results = filter(None, stdout.split("\0")) if not self.fm.settings.show_hidden and self.fm.settings.hidden_filter: hidden_filter = re.compile(self.fm.settings.hidden_filter) results = filter( lambda res: not hidden_filter.search(os.path.basename(res)), results ) results = map( lambda res: os.path.abspath(os.path.join(self.fm.thisdir.path, res)), results, ) self.SEARCH_RESULTS.extend(sorted(results, key=str.lower)) if len(self.SEARCH_RESULTS) > 0: self.fm.notify( "Found {} result{}.".format( len(self.SEARCH_RESULTS), ("s" if len(self.SEARCH_RESULTS) > 1 else ""), ) ) self.fm.select_file(self.SEARCH_RESULTS[0]) else: self.fm.notify("No results found.") class fd_next(Command): """ :fd_next Selects the next match from the last :fd_search. """ def execute(self): if len(fd_search.SEARCH_RESULTS) > 1: fd_search.SEARCH_RESULTS.rotate(-1) # rotate left self.fm.select_file(fd_search.SEARCH_RESULTS[0]) elif len(fd_search.SEARCH_RESULTS) == 1: self.fm.select_file(fd_search.SEARCH_RESULTS[0]) class fd_prev(Command): """ :fd_prev Selects the next match from the last :fd_search. """ def execute(self): if len(fd_search.SEARCH_RESULTS) > 1: fd_search.SEARCH_RESULTS.rotate(1) # rotate right self.fm.select_file(fd_search.SEARCH_RESULTS[0]) elif len(fd_search.SEARCH_RESULTS) == 1: self.fm.select_file(fd_search.SEARCH_RESULTS[0]) # yank content class YankContentWl(Command): def execute(self): if "wl-copy" not in get_executables(): self.fm.notify("wl-clipboard is not found.", bad=True) return arg = self.rest(1) if arg: if not os.path.isfile(arg): self.fm.notify("{} is not a file".format(arg)) return file = File(arg) else: file = self.fm.thisfile if not file.is_file: self.fm.notify("{} is not a file".format(file.relative_path)) return if file.is_binary or file.image: subprocess.check_call("wl-copy" + " < " + file.path, shell=True) else: self.fm.notify( "{} is not an image file or a text file".format(file.relative_path) ) import os import subprocess from ranger.api.commands import Command from ranger.container.file import File from ranger.ext.get_executables import get_executables class YankContent(Command): """ Copy the content of image file and text file with xclip """ def execute(self): if "xclip" not in get_executables(): self.fm.notify("xclip is not found.", bad=True) return arg = self.rest(1) if arg: if not os.path.isfile(arg): self.fm.notify("{} is not a file.".format(arg)) return file = File(arg) else: file = self.fm.thisfile if not file.is_file: self.fm.notify("{} is not a file.".format(file.relative_path)) return relative_path = file.relative_path cmd = ["xclip", "-selection", "clipboard"] if not file.is_binary(): with open(file.path, "rb") as fd: subprocess.check_call(cmd, stdin=fd) elif file.image: cmd += ["-t", file.mimetype, file.path] subprocess.check_call(cmd) self.fm.notify( "Content of {} is copied to x clipboard".format(relative_path) ) else: self.fm.notify( "{} is not an image file or a text file.".format(relative_path) ) def tab(self, tabnum): return self._tab_directory_content()