diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 0d75df51..c2427383 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -384,8 +384,12 @@ Themes adjacent segment is to the *right* for segments on the *left* side, and vice versa. Hard dividers are used between segments with different background colors, soft ones are used between segments with same - background. These options may be overridden by return value of functions - segments. + background. Both options default to ``True``. + + ``draw_inner_divider`` + Determines whether inner soft dividers are to be drawn for function + segments. Only applicable for functions returning multiple segments. + Defaults to ``False``. ``exclude_modes`` A list of modes where this segment will be excluded: The segment is diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 67de84ce..6b2636af 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -507,7 +507,7 @@ vim_colorscheme_spec = (Spec( generic_keys = set(('exclude_modes', 'include_modes', 'width', 'align', 'name', 'draw_soft_divider', 'draw_hard_divider', 'priority', 'after', 'before')) type_keys = { - 'function': set(('args', 'module')), + 'function': set(('args', 'module', 'draw_inner_divider')), 'string': set(('contents', 'type', 'highlight_group', 'divider_highlight_group')), 'filler': set(('type', 'highlight_group', 'divider_highlight_group')), } @@ -799,6 +799,7 @@ segments_spec = Spec().optional().list( include_modes=Spec().list(vim_mode_spec()).optional(), draw_hard_divider=Spec().type(bool).optional(), draw_soft_divider=Spec().type(bool).optional(), + draw_inner_divider=Spec().type(bool).optional(), module=segment_module_spec(), priority=Spec().cmp('ge', -1).optional(), after=Spec().type(unicode).optional(), diff --git a/powerline/segment.py b/powerline/segment.py index 8d3c7623..8a2483ff 100644 --- a/powerline/segment.py +++ b/powerline/segment.py @@ -76,6 +76,7 @@ def gen_segment_getter(ext, path, theme_configs, default_module=None): 'priority': segment.get('priority', -1), 'draw_hard_divider': segment.get('draw_hard_divider', True), 'draw_soft_divider': segment.get('draw_soft_divider', True), + 'draw_inner_divider': segment.get('draw_inner_divider', False), 'side': side, 'exclude_modes': segment.get('exclude_modes', []), 'include_modes': segment.get('include_modes', []), diff --git a/powerline/segments/common.py b/powerline/segments/common.py index 7b7d79d9..c85f6019 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -438,7 +438,6 @@ class WeatherSegment(ThreadedSegment): { 'contents': temp_format.format(temp=converted_temp), 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], - 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': gradient_level, }, @@ -521,11 +520,9 @@ def system_load(pl, format='{avg:.1f}', threshold_good=1, threshold_bad=2): ret.append({ 'contents': format.format(avg=avg), 'highlight_group': ['system_load_gradient', 'system_load'], - 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': gradient_level, }) - ret[0]['draw_soft_divider'] = True ret[0]['contents'] += ' ' ret[1]['contents'] += ' ' return ret diff --git a/powerline/theme.py b/powerline/theme.py index ed5e5788..0b7cdd7a 100644 --- a/powerline/theme.py +++ b/powerline/theme.py @@ -1,7 +1,5 @@ # vim:fileencoding=utf-8:noet -from copy import copy - from .segment import gen_segment_getter @@ -91,19 +89,35 @@ class Theme(object): if contents is None: continue if isinstance(contents, list): - segment_base = copy(segment) + segment_base = segment.copy() if contents: - for key in ('before', 'after'): + 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[0][key] = segment_base.pop(key) - segment_base[key] = '' + contents[i][key] = segment_base.pop(key) + segment_base[key] = newval except KeyError: pass - for subsegment in contents: - segment_copy = copy(segment_base) + 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) - parsed_segments.append(segment_copy) + 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) @@ -124,4 +138,4 @@ class Theme(object): # 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(segment) + yield segment.copy() diff --git a/tests/test_segments.py b/tests/test_segments.py index 74e5e966..b4c52b31 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -175,35 +175,35 @@ class TestCommon(TestCase): with replace_attr(common, 'urllib_read', urllib_read): self.assertEqual(common.weather(pl=pl), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(pl=pl, temp_coldest=0, temp_hottest=100), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 0} ]) self.assertEqual(common.weather(pl=pl, temp_coldest=-100, temp_hottest=-50), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 100} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 100} ]) self.assertEqual(common.weather(pl=pl, icons={'cloudy': 'o'}), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'o '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(pl=pl, icons={'partly_cloudy_day': 'x'}), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'x '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(pl=pl, unit='F'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '16°F', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '16°F', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(pl=pl, unit='K'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '264K', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '264K', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(pl=pl, temp_format='{temp:.1e}C'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9.0e+00C', 'gradient_level': 30.0} + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9.0e+00C', 'gradient_level': 30.0} ]) def test_system_load(self): @@ -211,13 +211,13 @@ class TestCommon(TestCase): with replace_module_module(common, 'os', getloadavg=lambda: (7.5, 3.5, 1.5)): with replace_attr(common, 'cpu_count', lambda: 2): self.assertEqual(common.system_load(pl=pl), - [{'contents': '7.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': True, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '3.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}, - {'contents': '1.5', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 0}]) + [{'contents': '7.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '3.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}, + {'contents': '1.5', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 0}]) self.assertEqual(common.system_load(pl=pl, format='{avg:.0f}', threshold_good=0, threshold_bad=1), - [{'contents': '8 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': True, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '4 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, - {'contents': '2', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_soft_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}]) + [{'contents': '8 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '4 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '2', 'highlight_group': ['system_load_gradient', 'system_load'], 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}]) def test_cpu_load_percent(self): pl = Pl()