Restructure segment rendering methods
Theme.get_segments() is now a generator which returns segment copies, and it no longer handles segment content replacement. Renderer.render() accepts a theme and a segments parameter in order to override the default actions (calling self.get_theme() and self.get_segments()). This is necessary to be able to cache themes and segment contents somewhere else and provide the cached data to the render method. The render method now also handles removing excluded segments, which was previously handled in Theme.get_segments(). Finally, VimRenderer.render() caches all theme and segment data and provides this data to the renderer for non-current windows. Closes #12.
This commit is contained in:
parent
3a8e64b767
commit
ccd6b4c28a
|
@ -33,17 +33,16 @@ class VimRenderer(Renderer):
|
|||
|
||||
if current:
|
||||
mode = vim_mode()
|
||||
contents_override = None
|
||||
theme = self.get_theme()
|
||||
segments = [segment for segment in theme.get_segments()]
|
||||
self.window_cache[window_id] = (theme, segments)
|
||||
else:
|
||||
mode = 'nc'
|
||||
contents_override = self.window_cache.get(window_id)
|
||||
theme, segments = self.window_cache.get(window_id, (None, None))
|
||||
|
||||
statusline = super(VimRenderer, self).render(mode, width=winwidth, contents_override=contents_override)
|
||||
statusline = super(VimRenderer, self).render(mode, winwidth, theme, segments)
|
||||
statusline = statusline.replace(self.PERCENT_PLACEHOLDER, '%%')
|
||||
|
||||
if current:
|
||||
self.window_cache[window_id] = {segment['key']: segment['contents'] for segment in self.segments if segment['type'] == 'function'}
|
||||
|
||||
return statusline
|
||||
|
||||
def hl(self, fg=None, bg=None, attr=None):
|
||||
|
|
|
@ -13,7 +13,6 @@ class Renderer(object):
|
|||
self.theme = Theme(theme_config=theme_config, **theme_kwargs)
|
||||
self.local_themes = local_themes
|
||||
self.theme_kwargs = theme_kwargs
|
||||
self.segments = []
|
||||
|
||||
def get_theme(self):
|
||||
for matcher in self.local_themes.iterkeys():
|
||||
|
@ -25,7 +24,7 @@ class Renderer(object):
|
|||
else:
|
||||
return self.theme
|
||||
|
||||
def render(self, mode, width=None, contents_override=None):
|
||||
def render(self, mode, width=None, theme=None, segments=None):
|
||||
'''Render all segments.
|
||||
|
||||
When a width is provided, low-priority segments are dropped one at
|
||||
|
@ -34,10 +33,13 @@ class Renderer(object):
|
|||
provided they will fill the remaining space until the desired width is
|
||||
reached.
|
||||
'''
|
||||
theme = self.get_theme()
|
||||
theme = theme or self.get_theme()
|
||||
segments = segments or theme.get_segments()
|
||||
|
||||
# Handle excluded/included segments for the current mode
|
||||
segments = [segment for segment in segments\
|
||||
if mode not in segment['exclude_modes'] or (segment['include_modes'] and segment in segment['include_modes'])]
|
||||
|
||||
segments = theme.get_segments(mode, contents_override)
|
||||
self.segments = segments
|
||||
rendered_highlighted = self._render_segments(mode, theme, segments)
|
||||
|
||||
if not width:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
class Theme(object):
|
||||
def __init__(self, ext, colorscheme, theme_config, common_config, get_segment):
|
||||
|
@ -20,24 +22,15 @@ class Theme(object):
|
|||
'''
|
||||
return self.dividers[side][type]
|
||||
|
||||
def get_segments(self, mode, contents_override=None):
|
||||
def get_segments(self):
|
||||
'''Return all segments.
|
||||
|
||||
Function segments are called, and all segments get their before/after
|
||||
and ljust/rjust properties applied.
|
||||
'''
|
||||
contents_override = contents_override or {}
|
||||
return_segments = []
|
||||
for segment in self.segments:
|
||||
if mode in segment['exclude_modes'] or (segment['include_modes'] and segment not in segment['include_modes']):
|
||||
continue
|
||||
|
||||
if segment['type'] == 'function':
|
||||
contents = contents_override.get(segment['key'])
|
||||
if contents is None:
|
||||
if contents_override:
|
||||
continue
|
||||
contents = segment['contents_func'](**segment['args'])
|
||||
contents = segment['contents_func'](**segment['args'])
|
||||
|
||||
if contents is None:
|
||||
continue
|
||||
|
@ -52,12 +45,11 @@ class Theme(object):
|
|||
else:
|
||||
continue
|
||||
|
||||
if segment['key'] not in contents_override:
|
||||
# Only apply before/after/just to non-overridden segments
|
||||
segment['contents'] = unicode(segment['before'] + unicode(segment['contents']) + segment['after'])\
|
||||
.ljust(segment['ljust'])\
|
||||
.rjust(segment['rjust'])
|
||||
segment['contents'] = unicode(segment['before'] + unicode(segment['contents']) + segment['after'])\
|
||||
.ljust(segment['ljust'])\
|
||||
.rjust(segment['rjust'])
|
||||
|
||||
return_segments.append(segment)
|
||||
|
||||
return return_segments
|
||||
# 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 copy.copy(segment)
|
||||
|
|
Loading…
Reference in New Issue