Handle errors from Renderer._set_highlighting

It is done by moving appropriate get_highlighting calls into segment.py: here
errors from contents_func are handled as well.

This is a “fix” for #480 that will make such failures cause segment to disappear
with better header which should show segment which caused the error.

Closes #480
This commit is contained in:
ZyX 2014-08-26 19:25:32 +04:00
parent c488b2da7b
commit acd55bbd87
4 changed files with 64 additions and 42 deletions

View File

@ -467,7 +467,7 @@ class Powerline(object):
self.get_module_attr = gen_module_attr_getter(self.pl, self.import_paths, self.imported_modules)
self.renderer_options.update(
mergedicts(self.renderer_options, dict(
pl=self.pl,
term_truecolor=self.common_config['term_truecolor'],
ambiwidth=self.common_config['ambiwidth'],
@ -480,7 +480,7 @@ class Powerline(object):
'shutdown_event': self.shutdown_event,
'get_module_attr': self.get_module_attr,
},
)
))
if not self.run_once and self.common_config['reload_config']:
interval = self.common_config['interval']
@ -535,7 +535,8 @@ class Powerline(object):
self._purge_configs('colorscheme')
if load_colorscheme:
self.colorscheme_config = self.load_colorscheme_config(self.ext_config['colorscheme'])
self.renderer_options['colorscheme'] = Colorscheme(self.colorscheme_config, self.colors_config)
self.renderer_options['theme_kwargs']['colorscheme'] = (
Colorscheme(self.colorscheme_config, self.colors_config))
if load_theme:
self._purge_configs('theme')

View File

@ -36,8 +36,6 @@ class Renderer(object):
base class only records this parameter to a ``.local_themes`` attribute.
:param dict theme_kwargs:
Keyword arguments for ``Theme`` class constructor.
:param Colorscheme colorscheme:
Colorscheme object that holds colors configuration.
:param PowerlineLogger pl:
Object used for logging.
:param int ambiwidth:
@ -93,7 +91,6 @@ class Renderer(object):
theme_config,
local_themes,
theme_kwargs,
colorscheme,
pl,
ambiwidth=1,
**options):
@ -107,7 +104,6 @@ class Renderer(object):
self.theme = Theme(theme_config=theme_config, **theme_kwargs)
self.local_themes = local_themes
self.theme_kwargs = theme_kwargs
self.colorscheme = colorscheme
self.width_data = {
'N': 1, # Neutral
'Na': 1, # Narrow
@ -150,21 +146,6 @@ class Renderer(object):
'''
self.theme.shutdown()
def _set_highlighting(self, segment):
segment['highlight'] = self.colorscheme.get_highlighting(
segment['highlight_group'],
segment['mode'],
segment.get('gradient_level')
)
if segment['divider_highlight_group']:
segment['divider_highlight'] = self.colorscheme.get_highlighting(
segment['divider_highlight_group'],
segment['mode']
)
else:
segment['divider_highlight'] = None
return segment
def get_segment_info(self, segment_info, mode):
'''Get segment information.
@ -264,12 +245,7 @@ class Renderer(object):
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme):
'''Like Renderer.render(), but accept theme in place of matcher_info
'''
segments = [
self._set_highlighting(segment)
for segment in (
theme.get_segments(side, line, self.get_segment_info(segment_info, mode), mode)
)
]
segments = list(theme.get_segments(side, line, self.get_segment_info(segment_info, mode), mode))
current_width = 0

View File

@ -99,7 +99,8 @@ def get_attr_func(contents_func, key, args):
return lambda pl, shutdown_event: func(pl=pl, shutdown_event=shutdown_event, **args)
def process_segment_lister(pl, segment_info, parsed_segments, side, mode, lister, subsegments, patcher_args):
def process_segment_lister(pl, segment_info, parsed_segments, side, mode, colorscheme,
lister, subsegments, patcher_args):
for subsegment_info, subsegment_update in lister(pl=pl, segment_info=segment_info, **patcher_args):
draw_inner_divider = subsegment_update.pop('draw_inner_divider', False)
old_pslen = len(parsed_segments)
@ -120,7 +121,15 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, lister
):
continue
process_segment(pl, side, subsegment_info, parsed_segments, subsegment, subsegment_mode or mode)
process_segment(
pl,
side,
subsegment_info,
parsed_segments,
subsegment,
subsegment_mode or mode,
colorscheme,
)
new_pslen = len(parsed_segments)
if new_pslen > old_pslen + 1 and draw_inner_divider is not None:
for i in range(old_pslen, new_pslen - 1) if side == 'left' else range(old_pslen + 1, new_pslen):
@ -128,16 +137,37 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, lister
return None
def process_segment(pl, side, segment_info, parsed_segments, segment, mode):
def set_segment_highlighting(pl, colorscheme, segment):
try:
segment['highlight'] = colorscheme.get_highlighting(
segment['highlight_group'],
segment['mode'],
segment.get('gradient_level')
)
if segment['divider_highlight_group']:
segment['divider_highlight'] = colorscheme.get_highlighting(
segment['divider_highlight_group'],
segment['mode']
)
else:
segment['divider_highlight'] = None
except Exception as e:
pl.exception('Failed to set highlight group: {0}', str(e))
return False
else:
return True
def process_segment(pl, side, segment_info, parsed_segments, segment, mode, colorscheme):
segment = segment.copy()
segment['mode'] = mode
pl.prefix = segment['name']
if segment['type'] in ('function', 'segment_list'):
pl.prefix = segment['name']
try:
if segment['type'] == 'function':
contents = segment['contents_func'](pl, segment_info)
else:
contents = segment['contents_func'](pl, segment_info, parsed_segments, side, mode)
contents = segment['contents_func'](pl, segment_info, parsed_segments, side, mode, colorscheme)
except Exception as e:
pl.exception('Exception while computing segment: {0}', str(e))
return
@ -176,12 +206,15 @@ def process_segment(pl, side, segment_info, parsed_segments, segment, mode):
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)
if set_segment_highlighting(pl, colorscheme, segment_copy):
append(segment_copy)
else:
segment['contents'] = contents
parsed_segments.append(segment)
if set_segment_highlighting(pl, colorscheme, segment):
parsed_segments.append(segment)
elif segment['width'] == 'auto' or (segment['type'] == 'string' and segment['contents'] is not None):
parsed_segments.append(segment)
if set_segment_highlighting(pl, colorscheme, segment):
parsed_segments.append(segment)
def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, get_module_attr, top_theme):
@ -239,11 +272,13 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
'divider_highlight_group': None,
'before': None,
'after': None,
'contents_func': lambda pl, segment_info, parsed_segments, side, mode: process_segment_lister(
pl, segment_info, parsed_segments, side, mode,
patcher_args=args,
subsegments=subsegments,
lister=_contents_func,
'contents_func': lambda pl, segment_info, parsed_segments, side, mode, colorscheme: (
process_segment_lister(
pl, segment_info, parsed_segments, side, mode, colorscheme,
patcher_args=args,
subsegments=subsegments,
lister=_contents_func,
)
),
'contents': None,
'priority': None,

View File

@ -31,9 +31,11 @@ class Theme(object):
pl,
get_module_attr,
top_theme,
colorscheme,
main_theme_config=None,
run_once=False,
shutdown_event=None):
self.colorscheme = colorscheme
self.dividers = theme_config['dividers']
self.dividers = dict((
(key, dict((k, u(v))
@ -116,7 +118,15 @@ class Theme(object):
if mode not in segment['exclude_modes'] and (
not segment['include_modes'] or mode in segment['include_modes']
):
process_segment(self.pl, side, segment_info, parsed_segments, segment, mode)
process_segment(
self.pl,
side,
segment_info,
parsed_segments,
segment,
mode,
self.colorscheme,
)
for segment in parsed_segments:
segment['contents'] = segment['before'] + u(segment['contents'] if segment['contents'] is not None else '') + segment['after']
# Align segment contents