homes/common/.local/lib/python2.7/site-packages/powerline/theme.py
2013-05-02 18:11:33 +02:00

148 lines
4.7 KiB
Python

# vim:fileencoding=utf-8:noet
from .segment import gen_segment_getter
try:
from __builtin__ import unicode
except ImportError:
unicode = str # NOQA
def u(s):
if type(s) is unicode:
return s
else:
return unicode(s, 'utf-8')
def requires_segment_info(func):
func.powerline_requires_segment_info = True
return func
class Theme(object):
def __init__(self,
ext,
theme_config,
common_config,
pl,
top_theme_config=None,
run_once=False,
shutdown_event=None):
self.dividers = theme_config.get('dividers', common_config['dividers'])
self.spaces = theme_config.get('spaces', common_config['spaces'])
self.segments = {
'left': [],
'right': [],
}
self.EMPTY_SEGMENT = {
'contents': None,
'highlight': {'fg': False, 'bg': False, 'attr': 0}
}
self.pl = pl
theme_configs = [theme_config]
if top_theme_config:
theme_configs.append(top_theme_config)
get_segment = gen_segment_getter(pl, ext, common_config['paths'], theme_configs, theme_config.get('default_module'))
for side in ['left', 'right']:
for segment in theme_config['segments'].get(side, []):
segment = get_segment(segment, side)
if not run_once:
if segment['startup']:
try:
segment['startup'](pl=pl, shutdown_event=shutdown_event, **segment['args'])
except Exception as e:
pl.error('Exception during {0} startup: {1}', segment['name'], str(e))
continue
self.segments[side].append(segment)
def shutdown(self):
for segments in self.segments.values():
for segment in segments:
try:
segment['shutdown']()
except TypeError:
pass
def get_divider(self, side='left', type='soft'):
'''Return segment divider.'''
return self.dividers[side][type]
def get_spaces(self):
return self.spaces
def get_segments(self, side=None, segment_info=None):
'''Return all segments.
Function segments are called, and all segments get their before/after
and ljust/rjust properties applied.
'''
for side in [side] if side else ['left', 'right']:
parsed_segments = []
for segment in self.segments[side]:
if segment['type'] == 'function':
self.pl.prefix = segment['name']
try:
if (hasattr(segment['contents_func'], 'powerline_requires_segment_info')
and segment['contents_func'].powerline_requires_segment_info):
contents = segment['contents_func'](pl=self.pl, segment_info=segment_info, **segment['args'])
else:
contents = segment['contents_func'](pl=self.pl, **segment['args'])
except Exception as e:
self.pl.exception('Exception while computing segment: {0}', str(e))
continue
if contents is None:
continue
if isinstance(contents, list):
segment_base = segment.copy()
if contents:
draw_divider_position = -1 if side == 'left' else 0
for key, i, newval in (
('before', 0, ''),
('after', -1, ''),
('draw_soft_divider', draw_divider_position, True),
('draw_hard_divider', draw_divider_position, True),
):
try:
contents[i][key] = segment_base.pop(key)
segment_base[key] = newval
except KeyError:
pass
draw_inner_divider = None
if side == 'right':
append = parsed_segments.append
else:
pslen = len(parsed_segments)
append = lambda item: parsed_segments.insert(pslen, item)
for subsegment in (contents if side == 'right' else reversed(contents)):
segment_copy = segment_base.copy()
segment_copy.update(subsegment)
if draw_inner_divider is not None:
segment_copy['draw_soft_divider'] = draw_inner_divider
draw_inner_divider = segment_copy.pop('draw_inner_divider', None)
append(segment_copy)
else:
segment['contents'] = contents
parsed_segments.append(segment)
elif segment['width'] == 'auto' or (segment['type'] == 'string' and segment['contents'] is not None):
parsed_segments.append(segment)
else:
continue
for segment in parsed_segments:
segment['contents'] = segment['before'] + u(segment['contents'] if segment['contents'] is not None else '') + segment['after']
# Align segment contents
if segment['width'] and segment['width'] != 'auto':
if segment['align'] == 'l':
segment['contents'] = segment['contents'].ljust(segment['width'])
elif segment['align'] == 'r':
segment['contents'] = segment['contents'].rjust(segment['width'])
elif segment['align'] == 'c':
segment['contents'] = segment['contents'].center(segment['width'])
# We need to yield a copy of the segment, or else mode-dependent
# segment contents can't be cached correctly e.g. when caching
# non-current window contents for vim statuslines
yield segment.copy()