mirror of
https://github.com/powerline/powerline.git
synced 2025-07-23 13:55:45 +02:00
parent
e2168e2167
commit
f5d85b7294
@ -153,10 +153,25 @@ All keys in segments returned by the function override those obtained from
|
||||
|
||||
Detailed description of used dictionary keys:
|
||||
|
||||
.. _dev-segments-contents:
|
||||
|
||||
``contents``
|
||||
Text displayed by segment. Should be a ``unicode`` (Python2) or ``str``
|
||||
(Python3) instance.
|
||||
|
||||
``literal_contents``
|
||||
Text that needs to be output literally (i.e. without passing through
|
||||
:py:meth:`powerline.renderer.strwidth` to determine length, through
|
||||
:py:meth:`powerline.renderer.escape` to escape special characters and
|
||||
through :py:meth:`powerline.renderer.hl` to highlight it). Should be a tuple
|
||||
``(contents_length, contents)`` where ``contents_length`` is an integer and
|
||||
``contents`` is a ``unicode`` (Python2) or ``str`` (Python3) instance.
|
||||
|
||||
If this key is present and its second value is true then other contents keys
|
||||
(:ref:`contents <dev-segments-contents>`, :ref:`after
|
||||
<config-themes-seg-after>`, :ref:`before <config-themes-seg-before>`) will
|
||||
be ignored.
|
||||
|
||||
.. _dev-segments-draw_inner_divider:
|
||||
|
||||
``draw_hard_divider``, ``draw_soft_divider``, ``draw_inner_divider``
|
||||
|
@ -7,6 +7,9 @@
|
||||
"function": "powerline.listers.vim.tablister",
|
||||
"exclude_function": "single_tab",
|
||||
"segments": [
|
||||
{
|
||||
"function": "tab"
|
||||
},
|
||||
{
|
||||
"function": "tabnr",
|
||||
"after": " ",
|
||||
@ -29,6 +32,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "tab",
|
||||
"args": {
|
||||
"end": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "segment_list",
|
||||
"function": "powerline.listers.vim.bufferlister",
|
||||
|
@ -391,7 +391,10 @@ class Renderer(object):
|
||||
segment['contents'] = translate_np(segment['contents'])
|
||||
if calculate_contents_len:
|
||||
for segment in segments:
|
||||
segment['_contents_len'] = self.strwidth(segment['contents'])
|
||||
if segment['literal_contents'][1]:
|
||||
segment['_contents_len'] = segment['literal_contents'][0]
|
||||
else:
|
||||
segment['_contents_len'] = self.strwidth(segment['contents'])
|
||||
|
||||
def _render_length(self, theme, segments, divider_widths):
|
||||
'''Update segments lengths and return them
|
||||
@ -399,24 +402,52 @@ class Renderer(object):
|
||||
segments_len = len(segments)
|
||||
ret = 0
|
||||
divider_spaces = theme.get_spaces()
|
||||
prev_segment = theme.EMPTY_SEGMENT
|
||||
try:
|
||||
first_segment = next(iter((
|
||||
segment
|
||||
for segment in segments
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
first_segment = None
|
||||
try:
|
||||
last_segment = next(iter((
|
||||
segment
|
||||
for segment in reversed(segments)
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
last_segment = None
|
||||
for index, segment in enumerate(segments):
|
||||
side = segment['side']
|
||||
segment_len = segment['_contents_len']
|
||||
if not segment['literal_contents'][1]:
|
||||
if side == 'left':
|
||||
if segment is not last_segment:
|
||||
compare_segment = next(iter((
|
||||
segment
|
||||
for segment in segments[index + 1:]
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
else:
|
||||
compare_segment = theme.EMPTY_SEGMENT
|
||||
else:
|
||||
compare_segment = prev_segment
|
||||
|
||||
prev_segment = segments[index - 1] if index > 0 else theme.EMPTY_SEGMENT
|
||||
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
|
||||
compare_segment = next_segment if side == 'left' else prev_segment
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
outer_padding = int(bool(
|
||||
(index == 0 and side == 'left') or
|
||||
(index == segments_len - 1 and side == 'right')
|
||||
))
|
||||
outer_padding = int(bool(
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
))
|
||||
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += outer_padding
|
||||
if draw_divider:
|
||||
segment_len += divider_widths[side][divider_type] + divider_spaces
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += outer_padding
|
||||
if draw_divider:
|
||||
segment_len += divider_widths[side][divider_type] + divider_spaces
|
||||
prev_segment = segment
|
||||
|
||||
segment['_len'] = segment_len
|
||||
ret += segment_len
|
||||
@ -435,61 +466,92 @@ class Renderer(object):
|
||||
'''
|
||||
segments_len = len(segments)
|
||||
divider_spaces = theme.get_spaces()
|
||||
prev_segment = theme.EMPTY_SEGMENT
|
||||
try:
|
||||
first_segment = next(iter((
|
||||
segment
|
||||
for segment in segments
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
first_segment = None
|
||||
try:
|
||||
last_segment = next(iter((
|
||||
segment
|
||||
for segment in reversed(segments)
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
except StopIteration:
|
||||
last_segment = None
|
||||
|
||||
for index, segment in enumerate(segments):
|
||||
side = segment['side']
|
||||
prev_segment = segments[index - 1] if index > 0 else theme.EMPTY_SEGMENT
|
||||
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
|
||||
compare_segment = next_segment if side == 'left' else prev_segment
|
||||
outer_padding = int(bool(
|
||||
(index == 0 and side == 'left') or
|
||||
(index == segments_len - 1 and side == 'right')
|
||||
)) * ' '
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
divider_highlighted = ''
|
||||
contents_raw = segment['contents']
|
||||
contents_highlighted = ''
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
|
||||
# XXX Make sure self.hl() calls are called in the same order
|
||||
# segments are displayed. This is needed for Vim renderer to work.
|
||||
if draw_divider:
|
||||
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
||||
if not segment['literal_contents'][1]:
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw + (divider_spaces * ' ')
|
||||
if segment is not last_segment:
|
||||
compare_segment = next(iter((
|
||||
segment
|
||||
for segment in segments[index + 1:]
|
||||
if not segment['literal_contents'][1]
|
||||
)))
|
||||
else:
|
||||
compare_segment = theme.EMPTY_SEGMENT
|
||||
else:
|
||||
contents_raw = (divider_spaces * ' ') + contents_raw + outer_padding
|
||||
compare_segment = prev_segment
|
||||
outer_padding = int(bool(
|
||||
segment is first_segment
|
||||
if side == 'left' else
|
||||
segment is last_segment
|
||||
)) * ' '
|
||||
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
|
||||
|
||||
if divider_type == 'soft':
|
||||
divider_highlight_group_key = 'highlight' if segment['divider_highlight_group'] is None else 'divider_highlight'
|
||||
divider_fg = segment[divider_highlight_group_key]['fg']
|
||||
divider_bg = segment[divider_highlight_group_key]['bg']
|
||||
else:
|
||||
divider_fg = segment['highlight']['bg']
|
||||
divider_bg = compare_segment['highlight']['bg']
|
||||
divider_highlighted = ''
|
||||
contents_raw = segment['contents']
|
||||
contents_highlighted = ''
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
|
||||
if side == 'left':
|
||||
if render_highlighted:
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
segment['_rendered_raw'] = contents_raw + divider_raw
|
||||
segment['_rendered_hl'] = contents_highlighted + divider_highlighted
|
||||
# XXX Make sure self.hl() calls are called in the same order
|
||||
# segments are displayed. This is needed for Vim renderer to work.
|
||||
if draw_divider:
|
||||
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw + (divider_spaces * ' ')
|
||||
else:
|
||||
contents_raw = (divider_spaces * ' ') + contents_raw + outer_padding
|
||||
|
||||
if divider_type == 'soft':
|
||||
divider_highlight_group_key = 'highlight' if segment['divider_highlight_group'] is None else 'divider_highlight'
|
||||
divider_fg = segment[divider_highlight_group_key]['fg']
|
||||
divider_bg = segment[divider_highlight_group_key]['bg']
|
||||
else:
|
||||
divider_fg = segment['highlight']['bg']
|
||||
divider_bg = compare_segment['highlight']['bg']
|
||||
|
||||
if side == 'left':
|
||||
if render_highlighted:
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
segment['_rendered_raw'] = contents_raw + divider_raw
|
||||
segment['_rendered_hl'] = contents_highlighted + divider_highlighted
|
||||
else:
|
||||
if render_highlighted:
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = divider_raw + contents_raw
|
||||
segment['_rendered_hl'] = divider_highlighted + contents_highlighted
|
||||
else:
|
||||
if render_highlighted:
|
||||
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = divider_raw + contents_raw
|
||||
segment['_rendered_hl'] = divider_highlighted + contents_highlighted
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw
|
||||
else:
|
||||
contents_raw = contents_raw + outer_padding
|
||||
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = contents_raw
|
||||
segment['_rendered_hl'] = contents_highlighted
|
||||
prev_segment = segment
|
||||
else:
|
||||
if side == 'left':
|
||||
contents_raw = outer_padding + contents_raw
|
||||
else:
|
||||
contents_raw = contents_raw + outer_padding
|
||||
|
||||
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
|
||||
segment['_rendered_raw'] = contents_raw
|
||||
segment['_rendered_hl'] = contents_highlighted
|
||||
segment['_rendered_raw'] = ' ' * segment['literal_contents'][0]
|
||||
segment['_rendered_hl'] = segment['literal_contents'][1]
|
||||
yield segment
|
||||
|
||||
def escape(self, string):
|
||||
|
@ -127,6 +127,8 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, colors
|
||||
colorscheme,
|
||||
)
|
||||
new_pslen = len(parsed_segments)
|
||||
while parsed_segments[new_pslen - 1]['literal_contents'][1]:
|
||||
new_pslen -= 1
|
||||
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):
|
||||
parsed_segments[i]['draw_soft_divider'] = draw_inner_divider
|
||||
@ -134,6 +136,8 @@ def process_segment_lister(pl, segment_info, parsed_segments, side, mode, colors
|
||||
|
||||
|
||||
def set_segment_highlighting(pl, colorscheme, segment, mode):
|
||||
if segment['literal_contents'][1]:
|
||||
return True
|
||||
try:
|
||||
highlight_group_prefix = segment['highlight_group_prefix']
|
||||
except KeyError:
|
||||
@ -228,6 +232,7 @@ get_fallback_segment = {
|
||||
'before': None,
|
||||
'after': None,
|
||||
'contents': '',
|
||||
'literal_contents': (0, ''),
|
||||
'priority': None,
|
||||
'draw_soft_divider': True,
|
||||
'draw_hard_divider': True,
|
||||
@ -245,6 +250,7 @@ get_fallback_segment = {
|
||||
'_contents_len': None,
|
||||
}.copy
|
||||
|
||||
|
||||
def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, get_module_attr, top_theme):
|
||||
data = {
|
||||
'default_module': default_module or 'powerline.segments.' + ext,
|
||||
@ -373,6 +379,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
|
||||
)
|
||||
),
|
||||
'contents': None,
|
||||
'literal_contents': None,
|
||||
'priority': None,
|
||||
'draw_soft_divider': None,
|
||||
'draw_hard_divider': None,
|
||||
@ -421,6 +428,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
|
||||
'after': get_key(False, segment, module, function_name, name, 'after', ''),
|
||||
'contents_func': contents_func,
|
||||
'contents': contents,
|
||||
'literal_contents': (0, ''),
|
||||
'priority': segment.get('priority', None),
|
||||
'draw_hard_divider': segment.get('draw_hard_divider', True),
|
||||
'draw_soft_divider': segment.get('draw_soft_divider', True),
|
||||
|
@ -740,3 +740,19 @@ def csv_col_current(pl, segment_info, display_name='auto', name_format=' ({colum
|
||||
'contents': name_format.format(column_name=column_name),
|
||||
'highlight_groups': ['csv:column_name', 'csv'],
|
||||
}] if column_name else [])
|
||||
|
||||
|
||||
@requires_segment_info
|
||||
def tab(pl, segment_info, end=False):
|
||||
'''Mark start of the clickable region for tabpage
|
||||
|
||||
:param bool end:
|
||||
In place of starting region for the current tab end it.
|
||||
'''
|
||||
try:
|
||||
return [{
|
||||
'contents': None,
|
||||
'literal_contents': (0, '%{tabnr}T'.format(tabnr=('' if end else segment_info['tabnr']))),
|
||||
}]
|
||||
except KeyError:
|
||||
return None
|
||||
|
Loading…
x
Reference in New Issue
Block a user