b-ryan.powerline-shell/powerline_shell/utils.py
2018-04-25 09:55:50 -04:00

153 lines
4.4 KiB
Python

import sys
import os
import threading
py3 = sys.version_info[0] == 3
if py3:
def unicode_(x):
return str(x)
def decode(x):
return x.decode("utf-8")
else:
unicode_ = unicode
decode = unicode
class RepoStats(object):
symbols = {
'detached': u'\u2693',
'ahead': u'\u2B06',
'behind': u'\u2B07',
'staged': u'\u2714',
'changed': u'\u270E',
'new': u'?',
'conflicted': u'\u273C',
'stash': u'\u2398',
'git': u'\uE0A0',
'hg': u'\u263F',
'bzr': u'\u2B61\u20DF',
'fossil': u'\u2332',
'svn': u'\u2446'
}
def __init__(self, ahead=0, behind=0, new=0, changed=0, staged=0, conflicted=0):
self.ahead = ahead
self.behind = behind
self.new = new
self.changed = changed
self.staged = staged
self.conflicted = conflicted
def __eq__(self, other):
return (
self.ahead == other.ahead and
self.behind == other.behind and
self.new == other.new and
self.changed == other.changed and
self.staged == other.staged and
self.conflicted == other.conflicted
)
@property
def dirty(self):
qualifiers = [
self.new,
self.changed,
self.staged,
self.conflicted,
]
return sum(qualifiers) > 0
def __getitem__(self, _key):
return getattr(self, _key)
def n_or_empty(self, _key):
"""Given a string name of one of the properties of this class, returns
the value of the property as a string when the value is greater than
1. When it is not greater than one, returns an empty string.
As an example, if you want to show an icon for new files, but you only
want a number to appear next to the icon when there are more than one
new file, you can do:
segment = repo_stats.n_or_empty("new") + icon_string
"""
return unicode_(self[_key]) if int(self[_key]) > 1 else u''
def add_to_powerline(self, powerline):
def add(_key, fg, bg):
if self[_key]:
s = u" {}{} ".format(self.n_or_empty(_key), self.symbols[_key])
powerline.append(s, fg, bg)
color = powerline.theme
add('ahead', color.GIT_AHEAD_FG, color.GIT_AHEAD_BG)
add('behind', color.GIT_BEHIND_FG, color.GIT_BEHIND_BG)
add('staged', color.GIT_STAGED_FG, color.GIT_STAGED_BG)
add('changed', color.GIT_NOTSTAGED_FG, color.GIT_NOTSTAGED_BG)
add('new', color.GIT_UNTRACKED_FG, color.GIT_UNTRACKED_BG)
add('conflicted', color.GIT_CONFLICTED_FG, color.GIT_CONFLICTED_BG)
def warn(msg):
print('[powerline-bash] ', msg)
class BasicSegment(object):
def __init__(self, powerline, segment_def):
self.powerline = powerline
self.segment_def = segment_def # type: dict
def start(self):
pass
class ThreadedSegment(threading.Thread):
def __init__(self, powerline, segment_def):
super(ThreadedSegment, self).__init__()
self.powerline = powerline
self.segment_def = segment_def # type: dict
def import_file(module_name, path):
# An implementation of https://stackoverflow.com/a/67692/683436
if py3 and sys.version_info[1] >= 5:
import importlib.util
spec = importlib.util.spec_from_file_location(module_name, path)
if not spec:
raise ImportError()
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
elif py3:
from importlib.machinery import SourceFileLoader
return SourceFileLoader(module_name, path).load_module()
else:
import imp
return imp.load_source(module_name, path)
def get_PATH():
"""Normally gets the PATH from the OS. This function exists to enable
easily mocking the PATH in tests.
"""
return os.getenv("PATH")
def get_subprocess_env(**envs):
defaults = {
# https://github.com/milkbikis/powerline-shell/pull/153
"PATH": get_PATH(),
}
defaults.update(envs)
env = dict(os.environ)
env.update(defaults)
return env
def get_git_subprocess_env():
# LANG is specified to ensure git always uses a language we are expecting.
# Otherwise we may be unable to parse the output.
return get_subprocess_env(LANG="C")