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.
61 lines
2.3 KiB
61 lines
2.3 KiB
from ranger.api.commands import Command |
|
import os |
|
|
|
class fzf_select(Command): |
|
""" |
|
:fzf_select |
|
Find a file using fzf. |
|
With a prefix argument to select only directories. |
|
|
|
See: https://github.com/junegunn/fzf |
|
""" |
|
|
|
def execute(self): |
|
import subprocess |
|
from ranger.ext.get_executables import get_executables |
|
|
|
if 'fzf' not in get_executables(): |
|
self.fm.notify('Could not find fzf in the PATH.', bad=True) |
|
return |
|
|
|
fd = None |
|
if 'fdfind' in get_executables(): |
|
fd = 'fdfind' |
|
elif 'fd' in get_executables(): |
|
fd = 'fd' |
|
|
|
if fd is not None: |
|
hidden = ('--hidden' if self.fm.settings.show_hidden else '') |
|
exclude = "--no-ignore-vcs --exclude '.git' --exclude '*.py[co]' --exclude '__pycache__'" |
|
only_directories = ('--type directory' if self.quantifier else '') |
|
fzf_default_command = '{} --follow {} {} {} --color=always'.format( |
|
fd, hidden, exclude, only_directories |
|
) |
|
else: |
|
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 {} -o {} -o {} -print | cut -b3-'.format( |
|
hidden, exclude, only_directories |
|
) |
|
|
|
env = os.environ.copy() |
|
env['FZF_DEFAULT_COMMAND'] = fzf_default_command |
|
env['FZF_DEFAULT_OPTS'] = '--height=40% --layout=reverse --ansi --preview="{}"'.format(''' |
|
( |
|
batcat --color=always {} || |
|
bat --color=always {} || |
|
cat {} || |
|
tree -ahpCL 3 -I '.git' -I '*.py[co]' -I '__pycache__' {} |
|
) 2>/dev/null | head -n 100 |
|
''') |
|
|
|
fzf = self.fm.execute_command('fzf --no-multi', env=env, |
|
universal_newlines=True, stdout=subprocess.PIPE) |
|
stdout, _ = fzf.communicate() |
|
if fzf.returncode == 0: |
|
selected = os.path.abspath(stdout.strip()) |
|
if os.path.isdir(selected): |
|
self.fm.cd(selected) |
|
else: |
|
self.fm.select_file(selected)
|
|
|