-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.py
115 lines (98 loc) · 3.46 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
import os
import shutil
import subprocess
from typing import List, Optional, Union
from ranger.api.commands import Command
class mkcd(Command):
"""
Create a directory and 'cd' into it
Based on the 'cd' command:
https://github.com/ranger/ranger/blob/42cb5a521bf9b24eaaf47daed2b45763e704c347/ranger/config/commands.py#L903-L917
"""
def execute(self):
dirname = os.path.join(self.fm.thisdir.path, os.path.expanduser(self.rest(1)))
if not os.path.lexists(dirname):
os.makedirs(dirname)
self.fm.cd(dirname)
else:
self.fm.notify("file/directory exists!", bad=True)
class fzf_select(Command):
"""
Find a file using fzf. Use fd instead of find.
"""
fd_command = "fd -L"
multi_select = False
preview = True
@property
def command(self):
"""Command to run to run the find/fzf command"""
return "{} | fzf {} {}".format(
os.environ.get("RANGER_FZF_COMMAND", self.__class__.fd_command),
"-m" if self.__class__.multi_select else "+m",
(
"--preview='${HOME}/.config/fzf_preview {}'"
if self.__class__.preview
else ""
),
)
# helper function to run fzf in with self.command
# returns file if selected else none
def run_fzf(self) -> Optional[Union[List[str], str]]:
fzf = self.fm.execute_command(self.command, stdout=subprocess.PIPE)
stdout, _ = fzf.communicate()
if fzf.returncode == 0:
stdout_decoded = stdout.decode("utf-8").strip()
if self.__class__.multi_select:
return list(
map(
lambda s: os.path.abspath(s).strip(),
stdout_decoded.splitlines(),
)
)
else:
return os.path.abspath(stdout_decoded)
else:
return None
def execute(self):
fzf_file = self.run_fzf()
if fzf_file is None:
return
assert isinstance(fzf_file, str)
if os.path.isdir(fzf_file):
self.fm.cd(fzf_file)
else:
self.fm.select_file(fzf_file)
class fzf_select_hidden(fzf_select):
"""
same as fzf_select but shows hidden files
"""
fd_command = "fd -L -H"
class fzf_copy_from(fzf_select):
"""
Accepts a directory as the first argument
Prompts a multi-select fzf interface to pick
files from the passed directory and copies
them to the current directory.
"""
# search 2 levels down
fd_command = "fd -d 2 -L"
multi_select = True
def execute(self):
directory = os.path.join(os.environ["HOME"], "Downloads")
# get directory from first argument
if self.arg(1):
# normalize, convert to directory if user passed file
filepath = os.path.abspath(os.path.expanduser(self.arg(1)))
if not os.path.isdir(filepath):
filepath = os.path.dirname(filepath)
directory = filepath
os.chdir(directory)
fzf_files = self.run_fzf()
assert isinstance(fzf_files, list)
if fzf_files is not None:
for f in fzf_files:
to_path = os.path.join(self.fm.thisdir.path, os.path.basename(f))
# avoid overwriting a file
while os.path.exists(to_path):
to_path = f"{to_path}_"
shutil.copyfile(f, to_path)