This repository has been archived on 2022-08-21. You can view files and clone it, but cannot push or open issues or pull requests.
dotfiles/home/.config/ranger/commands.py

108 lines
3.5 KiB
Python

from __future__ import (absolute_import, division, print_function)
# You can import any python module as needed.
import os
from collections import deque
from ranger.api.commands import Command
fd_deq = deque()
class fd_search(Command):
""":fd_search [-d<depth>] <query>
Executes "fd -d<depth> <query>" in the current directory and focuses the
first match. <depth> defaults to 1, i.e. only the contents of the current
directory.
"""
def execute(self):
import subprocess
from ranger.ext.get_executables import get_executables
if not 'fd' in get_executables():
self.fm.notify("Couldn't find fd on 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
# For convenience, change which dict is used as result_sep to change
# fd's behavior from splitting results by \0, which allows for newlines
# in your filenames to splitting results by \n, which allows for \0 in
# filenames.
null_sep = {'arg': '-0', 'split': '\0'}
nl_sep = {'arg': '', 'split': '\n'}
result_sep = null_sep
process = subprocess.Popen(['fd', result_sep['arg'], depth, target],
universal_newlines=True, stdout=subprocess.PIPE)
(search_results, _err) = process.communicate()
global fd_deq
fd_deq = deque((self.fm.thisdir.path + os.sep + rel for rel in
sorted(search_results.split(result_sep['split']), key=str.lower)
if rel != ''))
if len(fd_deq) > 0:
self.fm.select_file(fd_deq[0])
class fd_next(Command):
""":fd_next
Selects the next match from the last :fd_search.
"""
def execute(self):
if len(fd_deq) > 1:
fd_deq.rotate(-1) # rotate left
self.fm.select_file(fd_deq[0])
elif len(fd_deq) == 1:
self.fm.select_file(fd_deq[0])
class fd_prev(Command):
""":fd_prev
Selects the next match from the last :fd_search.
"""
def execute(self):
if len(fd_deq) > 1:
fd_deq.rotate(1) # rotate right
self.fm.select_file(fd_deq[0])
elif len(fd_deq) == 1:
self.fm.select_file(fd_deq[0])
class fzf_select(Command):
"""
:fzf_select
Find a file using fzf.
With a prefix argument select only directories.
See: https://github.com/junegunn/fzf
"""
def execute(self):
import subprocess
import os.path
if self.quantifier:
# match only directories
command="find -L . \( -path '*/\.*' -o -fstype 'dev' -o -fstype 'proc' \) -prune \
-o -type d -print 2> /dev/null | sed 1d | cut -b3- | fzf +m"
else:
# match files and directories
command="find -L . \( -path '*/\.*' -o -fstype 'dev' -o -fstype 'proc' \) -prune \
-o -print 2> /dev/null | sed 1d | cut -b3- | fzf +m"
fzf = self.fm.execute_command(command, universal_newlines=True, stdout=subprocess.PIPE)
stdout, stderr = fzf.communicate()
if fzf.returncode == 0:
fzf_file = os.path.abspath(stdout.rstrip('\n'))
if os.path.isdir(fzf_file):
self.fm.cd(fzf_file)
else:
self.fm.select_file(fzf_file)