-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.py
138 lines (115 loc) · 4.33 KB
/
commands.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# 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.
# A simple command for demonstration purposes follows.
# -----------------------------------------------------------------------------
from __future__ import (absolute_import, division, print_function)
# You can import any python module as needed.
import os
# You always need to import ranger.api.commands here to get the Command class:
from ranger.api.commands import Command
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
command="fd -L --max-depth 3"
if self.fm.settings.show_hidden:
command+=" --hidden"
if self.quantifier:
# match only directories
command+=" --type directory"
command+=" 2> /dev/null | 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)
from collections import deque
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
hidden=""
if self.fm.settings.show_hidden:
hidden="-H"
# 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
cmd=['fd', result_sep['arg'], depth, hidden, "'" + target + "'"]
process = subprocess.Popen(' '.join(cmd), shell=True,
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 toggle_flat(Command):
"""
:toggle_flat
Flattens or unflattens the directory view.
"""
def execute(self):
if self.fm.thisdir.flat == 0:
self.fm.thisdir.unload()
self.fm.thisdir.flat = -1
self.fm.thisdir.load_content()
else:
self.fm.thisdir.unload()
self.fm.thisdir.flat = 0
self.fm.thisdir.load_content()