ambevar-dotfiles/.config/ranger/commands.py

168 lines
5.7 KiB
Python

# -*- coding: utf-8 -*-
from ranger.api.commands import *
class bulkrename(Command):
""":bulkrename
This command opens a list of selected files in an external editor.
After you edit and save the file, it will generate a shell script
which does bulk renaming according to the changes you did in the file.
This shell script is opened in an editor for you to review.
After you close it, it will be executed.
"""
def execute(self):
import sys
import tempfile
from ranger.container.file import File
from ranger.ext.shell_escape import shell_escape as esc
py3 = sys.version_info[0] >= 3
## CUSTOM: change editor here.
local_ed='emc'
# Create and edit the file list
filenames = [f.relative_path for f in self.fm.thistab.get_selection()]
listfile = tempfile.NamedTemporaryFile(delete=False)
listpath = listfile.name
if py3:
listfile.write("\n".join(filenames).encode("utf-8"))
else:
listfile.write("\n".join(filenames))
listfile.close()
self.fm.execute_file([File(listpath)], app=local_ed)
listfile = open(listpath, 'r')
new_filenames = listfile.read().split("\n")
listfile.close()
os.unlink(listpath)
if all(a == b for a, b in zip(filenames, new_filenames)):
self.fm.notify("No renaming to be done!")
return
# Generate script
cmdfile = tempfile.NamedTemporaryFile()
script_lines = []
script_lines.append("# This file will be executed when you close the editor.\n")
script_lines.append("# Please double-check everything, clear the file to abort.\n")
script_lines.extend("mv -vi -- %s %s\n" % (esc(old), esc(new)) \
for old, new in zip(filenames, new_filenames) if old != new)
script_content = "".join(script_lines)
if py3:
cmdfile.write(script_content.encode("utf-8"))
else:
cmdfile.write(script_content)
cmdfile.flush()
# Open the script and let the user review it, then check if the script
# was modified by the user
self.fm.execute_file([File(cmdfile.name)], app=local_ed)
cmdfile.seek(0)
script_was_edited = (script_content != cmdfile.read())
# Do the renaming
self.fm.run(['/bin/sh', cmdfile.name], flags='w')
cmdfile.close()
# Retag the files, but only if the script wasn't changed during review,
# because only then we know which are the source and destination files.
if not script_was_edited:
tags_changed = False
for old, new in zip(filenames, new_filenames):
if old != new:
oldpath = self.fm.thisdir.path + '/' + old
newpath = self.fm.thisdir.path + '/' + new
if oldpath in self.fm.tags:
old_tag = self.fm.tags.tags[oldpath]
self.fm.tags.remove(oldpath)
self.fm.tags.tags[newpath] = old_tag
tags_changed = True
if tags_changed:
self.fm.tags.dump()
else:
fm.notify("files have not been retagged")
import os
from ranger.core.loader import CommandLoader
class extracthere(Command):
def execute(self):
""" Extract copied files to current directory """
copied_files = tuple(self.fm.env.copy)
if not copied_files:
return
def refresh(_):
cwd = self.fm.env.get_directory(original_path)
cwd.load_content()
one_file = copied_files[0]
cwd = self.fm.env.cwd
original_path = cwd.path
au_flags = ['-X', cwd.path]
au_flags += self.line.split()[1:]
au_flags += ['-e']
self.fm.env.copy.clear()
self.fm.env.cut = False
if len(copied_files) == 1:
descr = "extracting: " + os.path.basename(one_file.path)
else:
descr = "extracting files from: " + os.path.basename(one_file.dirname)
obj = CommandLoader(args=['aunpack'] + au_flags \
+ [f.path for f in copied_files], descr=descr)
obj.signal_bind('after', refresh)
self.fm.loader.add(obj)
class mkcd(Command):
"""
:mkcd <dirname>
Creates a directory with the name <dirname> and enters it.
"""
def execute(self):
from os.path import join, expanduser, lexists
from os import makedirs
import re
dirname = join(self.fm.thisdir.path, expanduser(self.rest(1)))
if not lexists(dirname):
makedirs(dirname)
match = re.search('^/|^~[^/]*/', dirname)
if match:
self.fm.cd(match.group(0))
dirname = dirname[match.end(0):]
for m in re.finditer('[^/]+', dirname):
s = m.group(0)
if s == '..' or (s.startswith('.') and not self.fm.settings['show_hidden']):
self.fm.cd(s)
else:
## We force ranger to load content before calling `scout`.
self.fm.thisdir.load_content(schedule=False)
self.fm.execute_console('scout -ae ^{}$'.format(s))
else:
self.fm.notify("file/directory exists!", bad=True)
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()