Coding style.

More consistent leading underscores.
This commit is contained in:
Andrew Hamilton 2016-02-15 14:11:08 +00:00
parent 736dd3a701
commit 4919a1ed2a
10 changed files with 134 additions and 132 deletions

1
TODO
View file

@ -264,6 +264,7 @@ Ideas
- Have command line options for more things? timeout? worker's nice priority level? - Have command line options for more things? timeout? worker's nice priority level?
editor? pygment syntax theme? Compress the cache? Ignore which paths? Log to disk? editor? pygment syntax theme? Compress the cache? Ignore which paths? Log to disk?
The cache path? The cache path?
- Can mypy be a tool?
Shelved Shelved

View file

@ -341,25 +341,25 @@ class Table:
for y, row in enumerate(appearances)]) for y, row in enumerate(appearances)])
def parse_rgb(hex_rgb): def _parse_rgb(hex_rgb):
if hex_rgb.startswith("#"): if hex_rgb.startswith("#"):
hex_rgb = hex_rgb[1:] hex_rgb = hex_rgb[1:]
return tuple(eval("0x"+hex_rgb[index:index+2]) for index in [0, 2, 4]) return tuple(eval("0x"+hex_rgb[index:index+2]) for index in [0, 2, 4])
def char_style_for_token_type(token_type, pygment_style): def _char_style_for_token_type(token_type, pygment_style):
token_style = pygment_style.style_for_token(token_type) token_style = pygment_style.style_for_token(token_type)
fg_color = (None if token_style["color"] is None fg_color = (None if token_style["color"] is None
else parse_rgb(token_style["color"])) else _parse_rgb(token_style["color"]))
bg_color = (None if token_style["bgcolor"] is None bg_color = (None if token_style["bgcolor"] is None
else parse_rgb(token_style["bgcolor"])) else _parse_rgb(token_style["bgcolor"]))
return termstr.CharStyle(fg_color, bg_color, token_style["bold"], return termstr.CharStyle(fg_color, bg_color, token_style["bold"],
token_style["italic"], token_style["underline"]) token_style["italic"], token_style["underline"])
def pygments_to_termstr(tokens, pygment_style): def _pygments_to_termstr(tokens, pygment_style):
return termstr.TermStr("").join( return termstr.TermStr("").join(
termstr.TermStr(text, char_style_for_token_type( termstr.TermStr(text, _char_style_for_token_type(
token_type, pygment_style)) token_type, pygment_style))
for token_type, text in tokens) for token_type, text in tokens)
@ -367,10 +367,10 @@ def pygments_to_termstr(tokens, pygment_style):
class Code: class Code:
def __init__(self, tokens, style): def __init__(self, tokens, style):
code = pygments_to_termstr(tokens, style).split("\n") code = _pygments_to_termstr(tokens, style).split("\n")
max_width = max(len(line) for line in code) max_width = max(len(line) for line in code)
height = len(code) height = len(code)
# bg_color = parse_rgb(style.background_color) # bg_color = _parse_rgb(style.background_color)
# bg_style = termstr.CharStyle(1, bg_color) # bg_style = termstr.CharStyle(1, bg_color)
# pad_char = termstr.TermStr(" ", bg_style) # pad_char = termstr.TermStr(" ", bg_style)
pad_char = " " pad_char = " "

View file

@ -26,7 +26,7 @@ MISSING_KEY = "mi"
MULTI_HARDLINK_KEY = "mh" MULTI_HARDLINK_KEY = "mh"
def parse_ls_colors(ls_codes): def _parse_ls_colors(ls_codes):
color_codes = {} color_codes = {}
for entry in ls_codes.split(":"): for entry in ls_codes.split(":"):
if "=" not in entry: if "=" not in entry:
@ -39,7 +39,7 @@ def parse_ls_colors(ls_codes):
return color_codes return color_codes
DEFAULT_COLOR_CODES = \ _DEFAULT_COLOR_CODES = \
{BLOCK_DEVICE_KEY: '01;33', SYMLINK_KEY: '01;36', {BLOCK_DEVICE_KEY: '01;33', SYMLINK_KEY: '01;36',
STICKY_OTHER_WRITABLE_KEY: '30;42', DIRECTORY_KEY: '01;34', STICKY_OTHER_WRITABLE_KEY: '30;42', DIRECTORY_KEY: '01;34',
SETUID_KEY: '37;41', CHARACTER_DEVICE_KEY: '01;33', SOCKET_KEY: '01;35', SETUID_KEY: '37;41', CHARACTER_DEVICE_KEY: '01;33', SOCKET_KEY: '01;35',
@ -51,11 +51,11 @@ DEFAULT_COLOR_CODES = \
def get_color_codes(environment): def get_color_codes(environment):
if "LS_COLORS" in environment: if "LS_COLORS" in environment:
try: try:
return parse_ls_colors(environment["LS_COLORS"]) return _parse_ls_colors(environment["LS_COLORS"])
except: except:
syslog.syslog("Syntax error in LS_COLORS environment variable. " syslog.syslog("Syntax error in LS_COLORS environment variable. "
"Using default colors.") "Using default colors.")
return DEFAULT_COLOR_CODES return _DEFAULT_COLOR_CODES
def color_key_for_path(path, color_codes, is_link_target=True): def color_key_for_path(path, color_codes, is_link_target=True):

View file

@ -26,14 +26,14 @@ class TempDirTestCase(unittest.TestCase):
class ParseLsColorsTestCase(unittest.TestCase): class ParseLsColorsTestCase(unittest.TestCase):
def test_parse_ls_colors(self): def test_parse_ls_colors(self):
self.assertRaises(AssertionError, lscolors.parse_ls_colors, "") self.assertRaises(AssertionError, lscolors._parse_ls_colors, "")
self.assertRaises(AssertionError, lscolors.parse_ls_colors, "::") self.assertRaises(AssertionError, lscolors._parse_ls_colors, "::")
self.assertEqual(lscolors.parse_ls_colors("*.awk=38;5;148;1"), self.assertEqual(lscolors._parse_ls_colors("*.awk=38;5;148;1"),
{".awk": "38;5;148;1"}) {".awk": "38;5;148;1"})
self.assertEqual(lscolors.parse_ls_colors("*.tar.gz=38;5;148;1"), self.assertEqual(lscolors._parse_ls_colors("*.tar.gz=38;5;148;1"),
{".tar.gz": "38;5;148;1"}) {".tar.gz": "38;5;148;1"})
self.assertEqual( self.assertEqual(
lscolors.parse_ls_colors("*.awk=38;5;148;1:di=38;5;30"), lscolors._parse_ls_colors("*.awk=38;5;148;1:di=38;5;30"),
{".awk": "38;5;148;1", "di": "38;5;30"}) {".awk": "38;5;148;1", "di": "38;5;30"})
@ -216,7 +216,7 @@ class ColorCodeForFileTestCase(TempDirTestCase):
self.TAR_GZ_COLOR) self.TAR_GZ_COLOR)
def parse_ls_line(line): def _parse_ls_line(line):
parts = line.split("\x1b[") parts = line.split("\x1b[")
if len(parts) == 1: if len(parts) == 1:
return (None, line) return (None, line)
@ -229,7 +229,7 @@ def parse_ls_line(line):
class ParseLsLineTestCase(unittest.TestCase): class ParseLsLineTestCase(unittest.TestCase):
def test_parse_ls_line(self): def test_parse_ls_line(self):
self.assertEqual(parse_ls_line( self.assertEqual(_parse_ls_line(
"\x1b[0m\x1b[38;5;254m\x1b[m\x1b[38;5;30mhello\x1b[0m\n"), "\x1b[0m\x1b[38;5;254m\x1b[m\x1b[38;5;30mhello\x1b[0m\n"),
("38;5;30", "hello")) ("38;5;30", "hello"))
@ -247,7 +247,7 @@ def test_against_ls(root_path, environment):
if line.endswith(":"): if line.endswith(":"):
current_directory = line[:-1] current_directory = line[:-1]
continue continue
ls_color_code, filename = parse_ls_line(line) ls_color_code, filename = _parse_ls_line(line)
path = os.path.join(current_directory, filename) path = os.path.join(current_directory, filename)
if os.path.exists(path): # Some paths are already gone. e.g. in /proc if os.path.exists(path): # Some paths are already gone. e.g. in /proc
color_code = lscolors.color_code_for_path(path, color_codes) color_code = lscolors.color_code_for_path(path, color_codes)

View file

@ -8,7 +8,7 @@ import weakref
import terminal import terminal
def cache_first_result(user_function): def _cache_first_result(user_function):
def decorator(self, *args, **kwds): def decorator(self, *args, **kwds):
try: try:
return self._cache return self._cache
@ -66,7 +66,7 @@ class CharStyle:
return ("<CharStyle: fg:%s bg:%s attr:%s>" % return ("<CharStyle: fg:%s bg:%s attr:%s>" %
(self.fg_color, self.bg_color, ",".join(attributes))) (self.fg_color, self.bg_color, ",".join(attributes)))
@cache_first_result @_cache_first_result
def code_for_term(self): def code_for_term(self):
fg_func = (terminal.fg_color if isinstance(self.fg_color, int) fg_func = (terminal.fg_color if isinstance(self.fg_color, int)
else terminal.fg_rgb_color) else terminal.fg_rgb_color)
@ -80,7 +80,7 @@ class CharStyle:
underline_code]) underline_code])
def join_lists(lists): def _join_lists(lists):
result = [] result = []
for list_ in lists: for list_ in lists:
result.extend(list_) result.extend(list_)
@ -109,7 +109,7 @@ class TermStr(collections.UserString):
def __hash__(self): def __hash__(self):
return hash((self.data, self.style)) return hash((self.data, self.style))
@cache_first_result @_cache_first_result
def _partition_style(self): def _partition_style(self):
if self.data == "": if self.data == "":
return [] return []
@ -126,7 +126,7 @@ class TermStr(collections.UserString):
return result return result
def __str__(self): def __str__(self):
return "".join(join_lists( return "".join(_join_lists(
[style.code_for_term(), str_] [style.code_for_term(), str_]
for style, str_, position in self._partition_style()) + for style, str_, position in self._partition_style()) +
[terminal.normal]) [terminal.normal])
@ -154,7 +154,7 @@ class TermStr(collections.UserString):
def join(self, parts): def join(self, parts):
parts = [TermStr(part) if isinstance(part, str) else part parts = [TermStr(part) if isinstance(part, str) else part
for part in parts] for part in parts]
joined_style = join_lists(self.style + part.style for part in parts) joined_style = _join_lists(self.style + part.style for part in parts)
return self.__class__(self.data.join(part.data for part in parts), return self.__class__(self.data.join(part.data for part in parts),
tuple(joined_style[len(self.style):])) tuple(joined_style[len(self.style):]))
@ -207,7 +207,7 @@ class TermStr(collections.UserString):
# Below are extra methods useful for termstrs. # Below are extra methods useful for termstrs.
def transform_style(self, transform_func): def transform_style(self, transform_func):
new_style = tuple(join_lists([transform_func(style)] * len(str_) new_style = tuple(_join_lists([transform_func(style)] * len(str_)
for style, str_, position for style, str_, position
in self._partition_style())) in self._partition_style()))
return self.__class__(self.data, new_style) return self.__class__(self.data, new_style)

View file

@ -14,7 +14,7 @@ class CacheFirstResultTestCase(unittest.TestCase):
def test_cache_first_result_decorator(self): def test_cache_first_result_decorator(self):
class A: class A:
@termstr.cache_first_result @termstr._cache_first_result
def a(self, foo): def a(self, foo):
return foo return foo
a = A() a = A()
@ -22,7 +22,7 @@ class CacheFirstResultTestCase(unittest.TestCase):
self.assertEqual(a.a(4), 3) self.assertEqual(a.a(4), 3)
class B: class B:
@termstr.cache_first_result @termstr._cache_first_result
def b(self, foo): def b(self, foo):
return foo return foo
b = B() b = B()

View file

@ -87,11 +87,11 @@ def get_ls_color_codes():
return lscolors.get_color_codes(os.environ) return lscolors.get_color_codes(os.environ)
LS_COLOR_CODES = get_ls_color_codes() _LS_COLOR_CODES = get_ls_color_codes()
TIMEOUT = 60 TIMEOUT = 60
def fix_input(input_): def _fix_input(input_):
input_str = input_.decode("utf-8") if isinstance(input_, bytes) else input_ input_str = input_.decode("utf-8") if isinstance(input_, bytes) else input_
return input_str.replace("\t", " " * 4) return input_str.replace("\t", " " * 4)
@ -106,7 +106,7 @@ def _do_command(command, timeout=None, **kwargs):
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
process.kill() process.kill()
raise raise
return fix_input(stdout), fix_input(stderr), process.returncode return _fix_input(stdout), _fix_input(stderr), process.returncode
def _run_command(command, status_text=Status.ok): def _run_command(command, status_text=Status.ok):
@ -120,7 +120,7 @@ def _run_command(command, status_text=Status.ok):
status = Status.problem status = Status.problem
if process.returncode != 0: if process.returncode != 0:
status = Status.problem status = Status.problem
return status, fill3.Text(fix_input(output)) return status, fill3.Text(_fix_input(output))
def _syntax_highlight_code(text, path): def _syntax_highlight_code(text, path):
@ -138,7 +138,7 @@ def pygments_(path):
return Status.not_applicable, fill3.Text("Not unicode") return Status.not_applicable, fill3.Text("Not unicode")
else: else:
try: try:
source_widget = _syntax_highlight_code(fix_input(text), path) source_widget = _syntax_highlight_code(_fix_input(text), path)
except pygments.util.ClassNotFound: except pygments.util.ClassNotFound:
return Status.normal, fill3.Text(text) return Status.normal, fill3.Text(text)
return Status.normal, source_widget return Status.normal, source_widget
@ -170,14 +170,14 @@ def _pretty_bytes(bytes):
return "%s %s" % (conversion, units[unit_index]) return "%s %s" % (conversion, units[unit_index])
def md5(path): def _md5(path):
with open(path, "rb") as file: with open(path, "rb") as file:
return hashlib.md5(file.read()).hexdigest() return hashlib.md5(file.read()).hexdigest()
def metadata(path): def metadata(path):
def _detail(value, unit): def detail(value, unit):
result = (" (%s)" % value if unit is None else " (%s %s)" % result = (" (%s)" % value if unit is None else " (%s %s)" %
(value, unit)) (value, unit))
return termstr.TermStr(result).fg_color(termstr.Color.grey_100) return termstr.TermStr(result).fg_color(termstr.Color.grey_100)
@ -186,26 +186,26 @@ def metadata(path):
permissions = stat.filemode(stat_result.st_mode) permissions = stat.filemode(stat_result.st_mode)
hardlinks = str(stat_result.st_nlink) hardlinks = str(stat_result.st_nlink)
group = [pwd.getpwuid(stat_result.st_gid).pw_name, group = [pwd.getpwuid(stat_result.st_gid).pw_name,
_detail(stat_result.st_gid, "gid")] detail(stat_result.st_gid, "gid")]
owner = [pwd.getpwuid(stat_result.st_uid).pw_name, owner = [pwd.getpwuid(stat_result.st_uid).pw_name,
_detail(stat_result.st_uid, "uid")] detail(stat_result.st_uid, "uid")]
modified, created, access = [ modified, created, access = [
[time.asctime(time.gmtime(seconds)), _detail(int(seconds), "secs")] [time.asctime(time.gmtime(seconds)), detail(int(seconds), "secs")]
for seconds in (stat_result.st_mtime, stat_result.st_ctime, for seconds in (stat_result.st_mtime, stat_result.st_ctime,
stat_result.st_atime)] stat_result.st_atime)]
size = [_pretty_bytes(stat_result.st_size), size = [_pretty_bytes(stat_result.st_size),
_detail(stat_result.st_size, "bytes")] detail(stat_result.st_size, "bytes")]
stdout, *rest = _do_command( stdout, *rest = _do_command(
["file", "--dereference", "--brief", "--uncompress", "--mime", path]) ["file", "--dereference", "--brief", "--uncompress", "--mime", path])
mime_type = stdout mime_type = stdout
stdout, *rest = _do_command( stdout, *rest = _do_command(
["file", "--dereference", "--brief", "--uncompress", path]) ["file", "--dereference", "--brief", "--uncompress", path])
file_type = stdout file_type = stdout
md5sum = md5(path) md5sum = _md5(path)
stdout, *rest = _do_command(["sha1sum", path]) stdout, *rest = _do_command(["sha1sum", path])
sha1sum = stdout.split()[0] sha1sum = stdout.split()[0]
permissions_value = [permissions, permissions_value = [permissions,
_detail(_permissions_in_octal(permissions), None)] detail(_permissions_in_octal(permissions), None)]
text = [] text = []
for line in [ for line in [
("size", size), ("permissions", permissions_value), None, ("size", size), ("permissions", permissions_value), None,
@ -294,7 +294,7 @@ def pydoc(path):
status, output = Status.normal, "" status, output = Status.normal, ""
try: try:
output = subprocess.check_output([pydoc_exe, path], timeout=TIMEOUT) output = subprocess.check_output([pydoc_exe, path], timeout=TIMEOUT)
output = fix_input(output) output = _fix_input(output)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
status = Status.not_applicable status = Status.not_applicable
if not output.startswith("Help on module"): if not output.startswith("Help on module"):
@ -359,7 +359,7 @@ pylint.dependencies = {"pylint", "pylint3"}
def python_gut(path): def python_gut(path):
with open(path) as module_file: with open(path) as module_file:
output = gut.gut_module(module_file.read()) output = gut.gut_module(module_file.read())
source_widget = _syntax_highlight_code(fix_input(output), path) source_widget = _syntax_highlight_code(_fix_input(output), path)
return Status.normal, source_widget return Status.normal, source_widget
python_gut.dependencies = set() python_gut.dependencies = set()
@ -666,11 +666,11 @@ class Result:
self.entry.summary.is_status_simple)] self.entry.summary.is_status_simple)]
def generic_tools(): def _generic_tools():
return [contents, metadata] return [contents, metadata]
def tools_for_extension(): def _tools_for_extension():
return { return {
"py": [python_syntax, python_unittests, pydoc, python_coverage, "py": [python_syntax, python_unittests, pydoc, python_coverage,
python_profile, pep8, pyflakes, pylint, python_gut, python_profile, pep8, pyflakes, pylint, python_gut,
@ -702,8 +702,8 @@ def tools_for_extension():
def tools_all(): def tools_all():
tools_ = set(generic_tools()) tools_ = set(_generic_tools())
for tool_list in tools_for_extension().values(): for tool_list in _tools_for_extension().values():
tools_.update(set(tool_list)) tools_.update(set(tool_list))
return tools_ return tools_
@ -726,8 +726,8 @@ def splitext(path):
def tools_for_path(path): def tools_for_path(path):
root, ext = splitext(path) root, ext = splitext(path)
extra_tools = [] if ext == "" else tools_for_extension().get(ext[1:], []) extra_tools = [] if ext == "" else _tools_for_extension().get(ext[1:], [])
return generic_tools() + extra_tools return _generic_tools() + extra_tools
def _get_python_traceback_lexer(): def _get_python_traceback_lexer():
@ -767,7 +767,7 @@ def _convert_lscolor_code_to_charstyle(lscolor_code):
def _charstyle_of_path(path): def _charstyle_of_path(path):
color_code = lscolors.color_code_for_path(path, LS_COLOR_CODES) color_code = lscolors.color_code_for_path(path, _LS_COLOR_CODES)
return (termstr.CharStyle() if color_code is None else return (termstr.CharStyle() if color_code is None else
_convert_lscolor_code_to_charstyle(color_code)) _convert_lscolor_code_to_charstyle(color_code))
@ -787,6 +787,6 @@ def _path_colored(path):
@functools.lru_cache(maxsize=100) @functools.lru_cache(maxsize=100)
def _tool_name_colored(tool, path): def _tool_name_colored(tool, path):
char_style = (termstr.CharStyle(is_bold=True) if tool in generic_tools() char_style = (termstr.CharStyle(is_bold=True) if tool in _generic_tools()
else _charstyle_of_path(path)) else _charstyle_of_path(path))
return termstr.TermStr(tool.__name__, char_style) return termstr.TermStr(tool.__name__, char_style)

121
vigil
View file

@ -89,7 +89,7 @@ def _log_error(message=None):
log_file.write(message) log_file.write(message)
def reverse_style(style): def _reverse_style(style):
return termstr.CharStyle(style.bg_color, style.fg_color, style.is_bold, return termstr.CharStyle(style.bg_color, style.fg_color, style.is_bold,
style.is_underlined) style.is_underlined)
@ -122,7 +122,7 @@ class Entry(collections.UserList):
return fill3.Text(termstr.TermStr("●", termstr.CharStyle( return fill3.Text(termstr.TermStr("●", termstr.CharStyle(
fg_color=fg_color, bg_color=status_color))) fg_color=fg_color, bg_color=status_color)))
else: else:
return fill3.Style(result_selected, reverse_style) return fill3.Style(result_selected, _reverse_style)
def appearance_min(self): def appearance_min(self):
# 'appearance' local variable exists because appearance_cache can # 'appearance' local variable exists because appearance_cache can
@ -139,27 +139,27 @@ class Entry(collections.UserList):
return appearance return appearance
def is_filename_excluded(filename): def _is_filename_excluded(filename):
return filename.startswith(".") return filename.startswith(".")
def codebase_files(path, skip_hidden_directories=True): def _codebase_files(path, skip_hidden_directories=True):
for (dirpath, dirnames, filenames) in os.walk(path): for (dirpath, dirnames, filenames) in os.walk(path):
if skip_hidden_directories: if skip_hidden_directories:
filtered_dirnames = [dirname for dirname in dirnames filtered_dirnames = [dirname for dirname in dirnames
if not is_filename_excluded(dirname)] if not _is_filename_excluded(dirname)]
dirnames[:] = filtered_dirnames dirnames[:] = filtered_dirnames
for filename in filenames: for filename in filenames:
if not is_filename_excluded(filename): if not _is_filename_excluded(filename):
yield os.path.join(dirpath, filename) yield os.path.join(dirpath, filename)
def fix_paths(root_path, paths): def _fix_paths(root_path, paths):
return [os.path.join(".", os.path.relpath(path, root_path)) return [os.path.join(".", os.path.relpath(path, root_path))
for path in paths] for path in paths]
def change_background(str_, new_background): def _change_background(str_, new_background):
def change_background_style(style): def change_background_style(style):
new_bg = (new_background if style.bg_color == termstr.Color.black new_bg = (new_background if style.bg_color == termstr.Color.black
@ -169,19 +169,19 @@ def change_background(str_, new_background):
return termstr.TermStr(str_).transform_style(change_background_style) return termstr.TermStr(str_).transform_style(change_background_style)
def in_green(str_): def _in_green(str_):
return termstr.TermStr(str_, termstr.CharStyle(termstr.Color.green)) return termstr.TermStr(str_, termstr.CharStyle(termstr.Color.green))
UP, DOWN, LEFT, RIGHT = (0, -1), (0, 1), (-1, 0), (1, 0) _UP, _DOWN, _LEFT, _RIGHT = (0, -1), (0, 1), (-1, 0), (1, 0)
def directory_sort(path): def _directory_sort(path):
return (os.path.dirname(path), tools.splitext(path)[1], return (os.path.dirname(path), tools.splitext(path)[1],
os.path.basename(path)) os.path.basename(path))
def type_sort(path): def _type_sort(path):
return (tools.splitext(path)[1], os.path.dirname(path), return (tools.splitext(path)[1], os.path.dirname(path),
os.path.basename(path)) os.path.basename(path))
@ -196,7 +196,7 @@ def _log_filesystem_changed(log, added, removed, modified):
log.log_message("Filesystem changed: " + fill3.join(" ", parts)) log.log_message("Filesystem changed: " + fill3.join(" ", parts))
def get_diff_stats(old_files, new_files): def _get_diff_stats(old_files, new_files):
old_names = set(name for name, ctime in old_files) old_names = set(name for name, ctime in old_files)
new_names = set(name for name, ctime in new_files) new_names = set(name for name, ctime in new_files)
added_count = len(new_names - old_names) added_count = len(new_names - old_names)
@ -241,9 +241,10 @@ class Summary:
old_path = None old_path = None
new_column = fill3.Column([]) new_column = fill3.Column([])
new_cache = {} new_cache = {}
paths = fix_paths(self._root_path, paths = _fix_paths(self._root_path,
codebase_files(self._root_path)) _codebase_files(self._root_path))
paths.sort(key=directory_sort if self.is_directory_sort else type_sort) paths.sort(key=_directory_sort if self.is_directory_sort
else _type_sort)
jobs_added = False jobs_added = False
new_cursor_position = (0, 0) new_cursor_position = (0, 0)
row_index = 0 row_index = 0
@ -280,7 +281,7 @@ class Summary:
max_path_length = max(len(path) for path in paths) - len("./") max_path_length = max(len(path) for path in paths) - len("./")
deleted_results = self._all_results - all_results deleted_results = self._all_results - all_results
if log is not None: if log is not None:
stats = get_diff_stats( stats = _get_diff_stats(
set(self._cache.keys()), set(new_cache.keys())) set(self._cache.keys()), set(new_cache.keys()))
if sum(stats) != 0: if sum(stats) != 0:
_log_filesystem_changed(log, *stats) _log_filesystem_changed(log, *stats)
@ -295,7 +296,7 @@ class Summary:
with contextlib.suppress(FileNotFoundError): with contextlib.suppress(FileNotFoundError):
os.remove(result.pickle_path) os.remove(result.pickle_path)
def placeholder_spiral(self): def _placeholder_spiral(self):
x, y = self.cursor_position() x, y = self.cursor_position()
result = self._column[y][x] result = self._column[y][x]
if result.is_placeholder: if result.is_placeholder:
@ -318,7 +319,7 @@ class Summary:
try: try:
return self.closest_placeholder_generator.send(None) return self.closest_placeholder_generator.send(None)
except AttributeError: except AttributeError:
self.closest_placeholder_generator = self.placeholder_spiral() self.closest_placeholder_generator = self._placeholder_spiral()
return self.closest_placeholder_generator.send(None) return self.closest_placeholder_generator.send(None)
def appearance_dimensions(self): def appearance_dimensions(self):
@ -343,7 +344,7 @@ class Summary:
scroll_y = (screen_y // height) * height scroll_y = (screen_y // height) * height
self._view_widget.position = ((screen_x // width) * width, scroll_y) self._view_widget.position = ((screen_x // width) * width, scroll_y)
appearance = self._view_widget.appearance(dimensions) appearance = self._view_widget.appearance(dimensions)
appearance[screen_y - scroll_y] = change_background( appearance[screen_y - scroll_y] = _change_background(
appearance[screen_y - scroll_y], termstr.Color.grey_50) appearance[screen_y - scroll_y], termstr.Color.grey_50)
return appearance return appearance
@ -367,16 +368,16 @@ class Summary:
raise ValueError raise ValueError
def cursor_right(self): def cursor_right(self):
self._move_cursor(RIGHT) self._move_cursor(_RIGHT)
def cursor_left(self): def cursor_left(self):
self._move_cursor(LEFT) self._move_cursor(_LEFT)
def cursor_up(self): def cursor_up(self):
self._move_cursor(UP) self._move_cursor(_UP)
def cursor_down(self): def cursor_down(self):
self._move_cursor(DOWN) self._move_cursor(_DOWN)
def cursor_page_up(self): def cursor_page_up(self):
view_width, view_height = self._view_widget.portal.last_dimensions view_width, view_height = self._view_widget.portal.last_dimensions
@ -423,9 +424,9 @@ class Summary:
tool_name = tools._tool_name_colored( tool_name = tools._tool_name_colored(
selection.tool, selection.path) selection.tool, selection.path)
path_colored = tools._path_colored(selection.path) path_colored = tools._path_colored(selection.path)
log.log_message([in_green("Refreshing "), tool_name, log.log_message([_in_green("Refreshing "), tool_name,
in_green(" result of "), path_colored, _in_green(" result of "), path_colored,
in_green("...")]) _in_green("...")])
selection.reset() selection.reset()
self.closest_placeholder_generator = None self.closest_placeholder_generator = None
self._jobs_added_event.set() self._jobs_added_event.set()
@ -434,9 +435,9 @@ class Summary:
class Log: class Log:
GREY_BOLD_STYLE = termstr.CharStyle(termstr.Color.grey_100, is_bold=True) _GREY_BOLD_STYLE = termstr.CharStyle(termstr.Color.grey_100, is_bold=True)
GREEN_STYLE = termstr.CharStyle(termstr.Color.green) _GREEN_STYLE = termstr.CharStyle(termstr.Color.green)
LOG_PATH = os.path.join(tools._CACHE_PATH, "log") _LOG_PATH = os.path.join(tools._CACHE_PATH, "log")
def __init__(self, appearance_changed_event): def __init__(self, appearance_changed_event):
self._appearance_changed_event = appearance_changed_event self._appearance_changed_event = appearance_changed_event
@ -453,20 +454,20 @@ class Log:
message = termstr.TermStr(message, char_style) message = termstr.TermStr(message, char_style)
timestamp = (time.strftime("%H:%M:%S", time.localtime()) timestamp = (time.strftime("%H:%M:%S", time.localtime())
if timestamp is None else timestamp) if timestamp is None else timestamp)
line = termstr.TermStr(timestamp, Log.GREY_BOLD_STYLE) + " " + message line = termstr.TermStr(timestamp, Log._GREY_BOLD_STYLE) + " " + message
self.widget.append(fill3.Text(line)) self.widget.append(fill3.Text(line))
with open(Log.LOG_PATH, "a") as log_file: with open(Log._LOG_PATH, "a") as log_file:
print(line, file=log_file) print(line, file=log_file)
self.widget.widgets = self.widget[-200:] self.widget.widgets = self.widget[-200:]
self._appearance_cache = None self._appearance_cache = None
self._appearance_changed_event.set() self._appearance_changed_event.set()
def log_command(self, message, timestamp=None): def log_command(self, message, timestamp=None):
self.log_message(message, char_style=Log.GREEN_STYLE) self.log_message(message, char_style=Log._GREEN_STYLE)
def delete_log_file(self): def delete_log_file(self):
with contextlib.suppress(FileNotFoundError): with contextlib.suppress(FileNotFoundError):
os.remove(Log.LOG_PATH) os.remove(Log._LOG_PATH)
def appearance_min(self): def appearance_min(self):
appearance = self._appearance_cache appearance = self._appearance_cache
@ -490,7 +491,7 @@ def _highlight_chars(str_, style, marker="*"):
@functools.lru_cache() @functools.lru_cache()
def _get_help_text(is_status_simple=True): def _get_help_text(is_status_simple=True):
usage = _highlight_chars(__doc__, Log.GREEN_STYLE) usage = _highlight_chars(__doc__, Log._GREEN_STYLE)
return fill3.join( return fill3.join(
"\n", [usage, "Statuses:"] + "\n", [usage, "Statuses:"] +
[" " + tools.status_to_str(status, is_status_simple) + " " + meaning [" " + tools.status_to_str(status, is_status_simple) + " " + meaning
@ -515,15 +516,15 @@ class Help:
self.widget = fill3.Border(self.view, title="Help") self.widget = fill3.Border(self.view, title="Help")
portal = self.view.portal portal = self.view.portal
self.key_map = _make_key_map([ self.key_map = _make_key_map([
({"h"}, self.exit_help), ({"d", "up"}, portal.scroll_up), ({"h"}, self._exit_help), ({"d", "up"}, portal.scroll_up),
({"c", "down"}, portal.scroll_down), ({"c", "down"}, portal.scroll_down),
({"j", "left"}, portal.scroll_left), ({"j", "left"}, portal.scroll_left),
({"k", "right"}, portal.scroll_right), ({"q"}, self.exit_help)]) ({"k", "right"}, portal.scroll_right), ({"q"}, self._exit_help)])
def exit_help(self): def _exit_help(self):
self.screen._is_help_visible = False self.screen._is_help_visible = False
def on_mouse_event(self, event, appearance_changed_event): def _on_mouse_event(self, event, appearance_changed_event):
if event[1] == 4: # Mouse wheel up if event[1] == 4: # Mouse wheel up
self.view.portal.scroll_up() self.view.portal.scroll_up()
appearance_changed_event.set() appearance_changed_event.set()
@ -533,7 +534,7 @@ class Help:
def on_input_event(self, event, appearance_changed_event): def on_input_event(self, event, appearance_changed_event):
if type(event) == tuple: if type(event) == tuple:
self.on_mouse_event(event, appearance_changed_event) self._on_mouse_event(event, appearance_changed_event)
return return
try: try:
action = self.key_map[event] action = self.key_map[event]
@ -679,8 +680,8 @@ class Screen:
else: else:
path = self._summary.get_selection().path path = self._summary.get_selection().path
path_colored = tools._path_colored(path) path_colored = tools._path_colored(path)
self._log.log_message([in_green("Editing "), path_colored, self._log.log_message([_in_green("Editing "), path_colored,
in_green(' with command: "%s"...' _in_green(' with command: "%s"...'
% self.editor_command)]) % self.editor_command)])
subprocess.Popen("%s %s" % (self.editor_command, path), shell=True, subprocess.Popen("%s %s" % (self.editor_command, path), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -712,7 +713,7 @@ class Screen:
def refresh(self): def refresh(self):
self._summary.refresh(self._log) self._summary.refresh(self._log)
def on_mouse_event(self, event): def _on_mouse_event(self, event):
if event[0] not in ["mouse press", "mouse drag"]: if event[0] not in ["mouse press", "mouse drag"]:
return return
if event[1] == 4: # Mouse wheel up if event[1] == 4: # Mouse wheel up
@ -752,7 +753,7 @@ class Screen:
event, self._appearance_changed_event) event, self._appearance_changed_event)
return return
if type(event) == tuple: if type(event) == tuple:
self.on_mouse_event(event) self._on_mouse_event(event)
return return
try: try:
action = self._key_map[event] action = self._key_map[event]
@ -764,7 +765,7 @@ class Screen:
_STATUS_BAR = _highlight_chars( _STATUS_BAR = _highlight_chars(
" *help *quit *d,*c,*j,*k,*f,*v:navigate *turn *log *edit *next *pause" " *help *quit *d,*c,*j,*k,*f,*v:navigate *turn *log *edit *next *pause"
" *order *refresh *statuses", Log.GREEN_STYLE) " *order *refresh *statuses", Log._GREEN_STYLE)
@functools.lru_cache(maxsize=2) @functools.lru_cache(maxsize=2)
def _get_status_bar_appearance(self, width, is_directory_sort, is_paused, def _get_status_bar_appearance(self, width, is_directory_sort, is_paused,
@ -818,15 +819,15 @@ class Screen:
({"p"}, toggle_pause), ({"r"}, refresh)] ({"p"}, toggle_pause), ({"r"}, refresh)]
def get_cpu_temperature(): def _get_cpu_temperature():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as temp_file: with open("/sys/class/thermal/thermal_zone0/temp", "r") as temp_file:
return int(temp_file.read()[:-4]) return int(temp_file.read()[:-4])
def regulate_temperature(log): def _regulate_temperature(log):
if get_cpu_temperature() >= 72: if _get_cpu_temperature() >= 72:
log.log_message("The computer is too hot. Waiting to cool down...") log.log_message("The computer is too hot. Waiting to cool down...")
while get_cpu_temperature() > 66: while _get_cpu_temperature() > 66:
time.sleep(1) time.sleep(1)
log.log_message("The computer has cooled down. Continuing...") log.log_message("The computer has cooled down. Continuing...")
@ -844,7 +845,7 @@ class Runner:
while True: while True:
jobs_added_event.wait() jobs_added_event.wait()
while True: while True:
# regulate_temperature(log) # My fan is broken # _regulate_temperature(log) # My fan is broken
try: try:
self.result = summary.get_closest_placeholder() self.result = summary.get_closest_placeholder()
except StopIteration: except StopIteration:
@ -873,11 +874,11 @@ class Runner:
self.worker.continue_() self.worker.continue_()
def is_path_excluded(path): def _is_path_excluded(path):
return any(part.startswith(".") for part in path.split(os.path.sep)) return any(part.startswith(".") for part in path.split(os.path.sep))
def add_watch_manager_to_mainloop(root_path, mainloop, on_filesystem_change, def _add_watch_manager_to_mainloop(root_path, mainloop, on_filesystem_change,
exclude_filter): exclude_filter):
watch_manager = pyinotify.WatchManager() watch_manager = pyinotify.WatchManager()
event_mask = (pyinotify.IN_CREATE | pyinotify.IN_DELETE | event_mask = (pyinotify.IN_CREATE | pyinotify.IN_DELETE |
@ -901,7 +902,7 @@ def add_watch_manager_to_mainloop(root_path, mainloop, on_filesystem_change,
_UPDATE_THREAD_STOPPED = False _UPDATE_THREAD_STOPPED = False
def update_screen(main_widget, appearance_changed_event): def _update_screen(main_widget, appearance_changed_event):
while True: while True:
appearance_changed_event.wait() appearance_changed_event.wait()
appearance_changed_event.clear() appearance_changed_event.clear()
@ -945,8 +946,8 @@ def main(root_path, worker_count=multiprocessing.cpu_count()*2,
def on_filesystem_change(): def on_filesystem_change():
summary.sync_with_filesystem(log) summary.sync_with_filesystem(log)
appearance_changed_event.set() appearance_changed_event.set()
watch_manager_fd = add_watch_manager_to_mainloop( watch_manager_fd = _add_watch_manager_to_mainloop(
root_path, loop, on_filesystem_change, is_path_excluded) root_path, loop, on_filesystem_change, _is_path_excluded)
screen.runners = runners = [] screen.runners = runners = []
if is_sandboxed: if is_sandboxed:
sandbox_temp_dir = tempfile.mkdtemp() sandbox_temp_dir = tempfile.mkdtemp()
@ -980,7 +981,7 @@ def main(root_path, worker_count=multiprocessing.cpu_count()*2,
appearance_changed_event.set() appearance_changed_event.set()
appearance_changed_event.set() appearance_changed_event.set()
update_display_thread = threading.Thread( update_display_thread = threading.Thread(
target=update_screen, args=(screen, appearance_changed_event), target=_update_screen, args=(screen, appearance_changed_event),
daemon=True) daemon=True)
with terminal.hidden_cursor(): with terminal.hidden_cursor():
with terminal.urwid_screen() as urwid_screen: with terminal.urwid_screen() as urwid_screen:
@ -1014,7 +1015,7 @@ def main(root_path, worker_count=multiprocessing.cpu_count()*2,
@contextlib.contextmanager @contextlib.contextmanager
def chdir(path): def _chdir(path):
old_cwd = os.getcwd() old_cwd = os.getcwd()
os.chdir(path) os.chdir(path)
try: try:
@ -1023,7 +1024,7 @@ def chdir(path):
os.chdir(old_cwd) os.chdir(old_cwd)
def manage_cache(root_path): def _manage_cache(root_path):
cache_path = os.path.join(root_path, tools._CACHE_PATH) cache_path = os.path.join(root_path, tools._CACHE_PATH)
timestamp_path = os.path.join(cache_path, "creation_time") timestamp_path = os.path.join(cache_path, "creation_time")
if os.path.exists(cache_path) and \ if os.path.exists(cache_path) and \
@ -1068,6 +1069,6 @@ if __name__ == "__main__":
subprocess.call(["sudo", "-p", "Vigil uses sudo... " subprocess.call(["sudo", "-p", "Vigil uses sudo... "
"[sudo] password for %u: ", "true"]) "[sudo] password for %u: ", "true"])
with terminal.console_title("vigil: " + os.path.basename(root_path)): with terminal.console_title("vigil: " + os.path.basename(root_path)):
manage_cache(root_path) _manage_cache(root_path)
with chdir(root_path): # FIX: Don't change directory if possible. with _chdir(root_path): # FIX: Don't change directory if possible.
main(root_path, worker_count, is_sandboxed, editor_command) main(root_path, worker_count, is_sandboxed, editor_command)

View file

@ -27,17 +27,17 @@ def _widget_to_string(widget, dimensions=_DIMENSIONS):
return str(fill3.join("\n", appearance)) return str(fill3.join("\n", appearance))
def touch(path): def _touch(path):
open(path, "w").close() open(path, "w").close()
def assert_widget_appearance(widget, golden_path, dimensions=_DIMENSIONS): def _assert_widget_appearance(widget, golden_path, dimensions=_DIMENSIONS):
golden_path_absolute = os.path.join(os.path.dirname(__file__), golden_path) golden_path_absolute = os.path.join(os.path.dirname(__file__), golden_path)
golden.assertGolden(_widget_to_string(widget, dimensions), golden.assertGolden(_widget_to_string(widget, dimensions),
golden_path_absolute) golden_path_absolute)
class MockMainLoop: class _MockMainLoop:
def add_reader(self, foo, bar): def add_reader(self, foo, bar):
pass pass
@ -48,23 +48,23 @@ class ScreenWidgetTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.temp_dir = tempfile.mkdtemp() self.temp_dir = tempfile.mkdtemp()
foo_path = os.path.join(self.temp_dir, "foo.py") foo_path = os.path.join(self.temp_dir, "foo.py")
touch(foo_path) _touch(foo_path)
jobs_added_event = threading.Event() jobs_added_event = threading.Event()
appearance_changed_event = threading.Event() appearance_changed_event = threading.Event()
summary = vigil.Summary(self.temp_dir, jobs_added_event) summary = vigil.Summary(self.temp_dir, jobs_added_event)
log = vigil.Log(appearance_changed_event) log = vigil.Log(appearance_changed_event)
self.main_widget = vigil.Screen(summary, log, appearance_changed_event, self.main_widget = vigil.Screen(summary, log, appearance_changed_event,
MockMainLoop()) _MockMainLoop())
def tearDown(self): def tearDown(self):
shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir)
# def test_initial_appearance(self): # def test_initial_appearance(self):
# assert_widget_appearance(self.main_widget, "golden-files/initial") # _assert_widget_appearance(self.main_widget, "golden-files/initial")
def test_help_appearance(self): def test_help_appearance(self):
self.main_widget.toggle_help() self.main_widget.toggle_help()
assert_widget_appearance(self.main_widget, "golden-files/help") _assert_widget_appearance(self.main_widget, "golden-files/help")
# def test_log_appearance(self): # def test_log_appearance(self):
# log_shown = _widget_to_string(self.main_widget) # log_shown = _widget_to_string(self.main_widget)
@ -124,8 +124,8 @@ class SummarySyncWithFilesystem(unittest.TestCase):
self.foo_path = os.path.join(self.temp_dir, "foo") self.foo_path = os.path.join(self.temp_dir, "foo")
self.bar_path = os.path.join(self.temp_dir, "bar") self.bar_path = os.path.join(self.temp_dir, "bar")
self.zoo_path = os.path.join(self.temp_dir, "zoo") self.zoo_path = os.path.join(self.temp_dir, "zoo")
touch(self.foo_path) _touch(self.foo_path)
touch(self.bar_path) _touch(self.bar_path)
self.jobs_added_event = threading.Event() self.jobs_added_event = threading.Event()
self.appearance_changed_event = threading.Event() self.appearance_changed_event = threading.Event()
self.summary = vigil.Summary(self.temp_dir, self.jobs_added_event) self.summary = vigil.Summary(self.temp_dir, self.jobs_added_event)
@ -150,7 +150,7 @@ class SummarySyncWithFilesystem(unittest.TestCase):
self.assertFalse(self.jobs_added_event.isSet()) self.assertFalse(self.jobs_added_event.isSet())
def test_sync_added_file(self): def test_sync_added_file(self):
touch(self.zoo_path) _touch(self.zoo_path)
self.summary.sync_with_filesystem() self.summary.sync_with_filesystem()
self._assert_paths(["./bar", "./foo", "./zoo"]) self._assert_paths(["./bar", "./foo", "./zoo"])
self.assertTrue(self.jobs_added_event.isSet()) self.assertTrue(self.jobs_added_event.isSet())
@ -158,7 +158,7 @@ class SummarySyncWithFilesystem(unittest.TestCase):
# def test_sync_changed_file_metadata(self): # def test_sync_changed_file_metadata(self):
# ids_before = [id(entry) for entry in self.summary._column] # ids_before = [id(entry) for entry in self.summary._column]
# time.sleep(1) # time.sleep(1)
# touch(self.foo_path) # _touch(self.foo_path)
# self.summary.sync_with_filesystem() # self.summary.sync_with_filesystem()
# ids_after = [id(entry) for entry in self.summary._column] # ids_after = [id(entry) for entry in self.summary._column]
# self.assertTrue(ids_before[0] == ids_after[0]) # bar # self.assertTrue(ids_before[0] == ids_after[0]) # bar
@ -191,15 +191,15 @@ class SummarySyncWithFilesystem(unittest.TestCase):
# def test_log(self): # def test_log(self):
# appearance_changed_event = threading.Event() # appearance_changed_event = threading.Event()
# log = vigil.Log(appearance_changed_event) # log = vigil.Log(appearance_changed_event)
# assert_widget_appearance(log, "golden-files/log-initial", None) # _assert_widget_appearance(log, "golden-files/log-initial", None)
# timestamp = "11:11:11" # timestamp = "11:11:11"
# self.assertFalse(appearance_changed_event.isSet()) # self.assertFalse(appearance_changed_event.isSet())
# log.log_message("foo", timestamp=timestamp) # log.log_message("foo", timestamp=timestamp)
# self.assertTrue(appearance_changed_event.isSet()) # self.assertTrue(appearance_changed_event.isSet())
# assert_widget_appearance(log, "golden-files/log-one-message", None) # _assert_widget_appearance(log, "golden-files/log-one-message", None)
# log.log_message("bar", timestamp=timestamp) # log.log_message("bar", timestamp=timestamp)
# assert_widget_appearance(log, "golden-files/log-two-messages", None) # _assert_widget_appearance(log, "golden-files/log-two-messages", None)
# assert_widget_appearance(log, "golden-files/log-appearance") # _assert_widget_appearance(log, "golden-files/log-appearance")
def _mount_total(): def _mount_total():
@ -224,8 +224,8 @@ class MainTestCase(unittest.TestCase):
# processes = _all_processes() # processes = _all_processes()
foo_path = os.path.join(root_path, "foo") foo_path = os.path.join(root_path, "foo")
open(foo_path, "w").close() open(foo_path, "w").close()
vigil.manage_cache(root_path) vigil._manage_cache(root_path)
with vigil.chdir(root_path): with vigil._chdir(root_path):
with contextlib.redirect_stdout(io.StringIO()): with contextlib.redirect_stdout(io.StringIO()):
vigil.main(root_path, worker_count=2, is_sandboxed=True, vigil.main(root_path, worker_count=2, is_sandboxed=True,
is_being_tested=True) is_being_tested=True)

View file

@ -12,7 +12,7 @@ import psutil
import tools import tools
def make_process_nicest(pid): def _make_process_nicest(pid):
process = psutil.Process(pid) process = psutil.Process(pid)
process.nice(19) process.nice(19)
process.ionice(psutil.IOPRIO_CLASS_IDLE) process.ionice(psutil.IOPRIO_CLASS_IDLE)
@ -33,7 +33,7 @@ class Worker:
self.cache_mount]) self.cache_mount])
self.process = sandbox.Popen([__file__]) self.process = sandbox.Popen([__file__])
self.child_pid = int(self.process.stdout.readline()) self.child_pid = int(self.process.stdout.readline())
make_process_nicest(self.child_pid) _make_process_nicest(self.child_pid)
def run_tool(self, path, tool): def run_tool(self, path, tool):
self.process.stdin.write(("%s\n%s\n" % self.process.stdin.write(("%s\n%s\n" %