Make it possible to return several segment in segment functions

This requires a couple of minor changes to custom segments. The segment
`highlight` key has been renamed to `highlight_group`, and segment
functions must return a list of segments dicts instead of just a dict.

Closes #88.
This commit is contained in:
Kim Silkebækken 2013-01-22 10:58:41 +01:00
parent 973ea572d4
commit 424f979136
8 changed files with 70 additions and 54 deletions

View File

@ -61,7 +61,7 @@ Common configuration is a subdictionary that is a value of ``common`` key in
segments with the same background color.
``paths``
.. _config-common-paths
.. _config-common-paths:
Defines additional paths which will be searched for modules when using
:ref:`module segment option <config-themes-seg-module>`. Paths defined here
@ -166,14 +166,14 @@ Themes
``string``
A static string segment where the contents is defined in the
:ref:`contents option <config-themes-seg-contents>`, and the
highlighting group is defined in the :ref:`highlight option
<config-themes-seg-highlight>`.
highlighting group is defined in the :ref:`highlight_group
option <config-themes-seg-highlight_group>`.
``filler``
If the statusline is rendered with a specific width, remaining
whitespace is distributed among filler segments. The
highlighting group is defined in the :ref:`highlight option
<config-themes-seg-highlight>`.
highlighting group is defined in the :ref:`highlight_group
option <config-themes-seg-highlight_group>`.
``module``
.. _config-themes-seg-module:
@ -187,8 +187,8 @@ Themes
Function name, only required for function segments.
``highlight``
.. _config-themes-seg-highlight:
``highlight_group``
.. _config-themes-seg-highlight_group:
Highlighting group for this segment. Consists of a prioritized list
of highlighting groups, where the first highlighting group that is
@ -259,6 +259,6 @@ A segment function must return one of the following values:
* ``None``, which will remove the segment from the prompt/statusline.
* A string, which will be the segment contents.
* A dict consisting of a ``contents`` string, and a ``highlight`` list. This
is useful for providing a particular highlighting group depending on the
segment contents.
* A list of dicts consisting of a ``contents`` string, and
a ``highlight_group`` list. This is useful for providing a particular
highlighting group depending on the segment contents.

View File

@ -32,8 +32,7 @@
},
{
"name": "file_vcs_status",
"draw_divider": false,
"before": " "
"draw_divider": false
},
{
"name": "modified_indicator",
@ -42,7 +41,7 @@
},
{
"type": "filler",
"highlight": ["background"]
"highlight_group": ["background"]
}
],
"right": [
@ -72,7 +71,7 @@
{
"type": "string",
"contents": " ",
"highlight": ["line_current_symbol", "line_current"]
"highlight_group": ["line_current_symbol", "line_current"]
},
{
"name": "line_current",

View File

@ -7,7 +7,7 @@
},
{
"type": "filler",
"highlight": ["background"]
"highlight_group": ["background"]
}
],
"right": [
@ -21,7 +21,7 @@
{
"type": "string",
"contents": "⭡ ",
"highlight": ["line_current_symbol", "line_current"]
"highlight_group": ["line_current_symbol", "line_current"]
},
{
"name": "line_current",

View File

@ -89,7 +89,7 @@ class Renderer(object):
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
compare_segment = next_segment if segment['side'] == 'left' else prev_segment
segment['rendered_raw'] = u''
outer_padding = ' ' if index == 0 or (index == segments_len - 1 and segment['side'] == 'right') else ''
outer_padding = ' ' if (index == 0 and segment['side'] == 'left') or (index == segments_len - 1 and segment['side'] == 'right') else ''
divider_type = 'soft' if compare_segment['highlight'][mode]['bg'] == segment['highlight'][mode]['bg'] else 'hard'
divider = theme.get_divider(segment['side'], divider_type)
divider_hl = ''

View File

@ -34,11 +34,12 @@ class Segment(object):
except AttributeError:
raise TypeError('Unknown segment type: {0}'.format(segment_type))
contents, contents_func, key = get_segment_info(segment)
highlighting_group = segment.get('highlight', segment.get('name'))
highlight_group = segment.get('highlight_group', segment.get('name'))
return {
'key': key,
'type': segment_type,
'highlight': self.colorscheme.get_group_highlighting(highlighting_group),
'highlight_group': highlight_group,
'highlight': self.colorscheme.get_group_highlighting(highlight_group),
'before': segment.get('before', ''),
'after': segment.get('after', ''),
'contents_func': contents_func,

View File

@ -53,10 +53,10 @@ def hostname():
def user():
user = os.environ.get('USER')
euid = os.geteuid()
return {
'contents': user,
'highlight': 'user' if euid != 0 else ['superuser', 'user'],
}
return [{
'contents': user,
'highlight_group': 'user' if euid != 0 else ['superuser', 'user'],
}]
def branch():
@ -140,20 +140,26 @@ def weather(unit='c', location_query=None):
return u'{0} {1}°{2}'.format(icon, condition['temp'], unit.upper())
def system_load(format='{avg[0]:.1f}, {avg[1]:.1f}, {avg[2]:.1f}', threshold_good=1, threshold_bad=2):
from multiprocessing import cpu_count
averages = os.getloadavg()
normalized = averages[1] / cpu_count()
if normalized < threshold_good:
gradient = 'system_load_good'
elif normalized < threshold_bad:
gradient = 'system_load_bad'
else:
gradient = 'system_load_ugly'
return {
'contents': format.format(avg=averages),
'highlight': [gradient, 'system_load']
}
def system_load(format='{avg:.1f}', threshold_good=1, threshold_bad=2):
import multiprocessing
cpu_count = multiprocessing.cpu_count()
ret = []
for avg in os.getloadavg():
normalized = avg / cpu_count
if normalized < threshold_good:
hl = 'system_load_good'
elif normalized < threshold_bad:
hl = 'system_load_bad'
else:
hl = 'system_load_ugly'
ret.append({
'contents': format.format(avg=avg),
'highlight_group': [hl, 'system_load'],
'draw_divider': False,
})
ret[0]['contents'] += ' '
ret[1]['contents'] += ' '
return ret
def cpu_load_percent(measure_interval=.5):

View File

@ -90,10 +90,10 @@ def file_name(display_no_file=False, no_file_text='[No file]'):
if not file_name and not display_no_file:
return None
if not file_name:
return {
return [{
'contents': no_file_text,
'highlight': ['file_name_no_file', 'file_name'],
}
'highlight_group': ['file_name_no_file', 'file_name'],
}]
return file_name.decode('utf-8')
@ -128,10 +128,10 @@ def line_percent(gradient=False):
percentage = int(line_current * 100 // line_last)
if not gradient:
return percentage
return {
return [{
'contents': percentage,
'highlight': ['line_percent_gradient' + str(int(5 * percentage // 100) + 1), 'line_percent'],
}
'highlight_group': ['line_percent_gradient' + str(int(5 * percentage // 100) + 1), 'line_percent'],
}]
def line_current():
@ -166,8 +166,12 @@ def file_vcs_status():
if not status:
return None
status = status.strip()
return {
'contents': status,
'highlight': ['file_vcs_status_' + status, 'file_vcs_status'],
}
ret = []
for status in status:
ret.append({
'contents': status,
'highlight_group': ['file_vcs_status_' + status, 'file_vcs_status'],
})
ret[0]['before'] = ' '
return ret
return None

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from collections import defaultdict
import copy
from copy import copy
from .segment import Segment
@ -38,24 +38,30 @@ class Theme(object):
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':
contents = segment['contents_func'](**segment['args'])
if contents is None:
continue
try:
segment['highlight'] = self.colorscheme.get_group_highlighting(contents['highlight'])
segment['contents'] = contents['contents']
except TypeError:
if isinstance(contents, list):
for subsegment in contents:
segment_copy = copy(segment)
segment_copy.update(subsegment)
parsed_segments.append(segment_copy)
else:
segment['contents'] = contents
parsed_segments.append(segment)
elif segment['type'] == 'filler' or (segment['type'] == 'string' and segment['contents'] is not None):
pass
parsed_segments.append(segment)
else:
continue
for segment in parsed_segments:
segment['highlight'] = self.colorscheme.get_group_highlighting(segment['highlight_group'])
segment['contents'] = (segment['before'] + unicode(segment['contents']) + segment['after'])\
.ljust(segment['ljust'])\
.rjust(segment['rjust'])
# 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)
yield copy(segment)