Improve rendering performance
This commit almost doubles the segment rendering performance. This is accomplished by caching a lot of data like highlighting groups, moving some calculations out of loops, and by performing less function calls overall. When a width is specified the main speed improvement comes from avoiding rendering the raw segments over and over until the statusline is short enough. Instead, the raw rendering is stored as a segment property and the combined length of all these renderings is used when removing low-priority segments instead. This results in a maximum of two rendering passes. Some "less pythonic" solutions have been chosen some places for performance reasons, e.g. joining strings instead of appending and joining lists. Overall this commit appears to make the performance equal or better than the legacy vimscript implementation. Later optimizations (in particular finding another method than remove() for removing low-priority segments) may make this version of Powerline far superior both in terms of functionality and performance.
This commit is contained in:
parent
6c5316a058
commit
f4e3d01d07
|
@ -176,13 +176,13 @@ def statusline(winnr):
|
|||
stl = re.sub('(\w+)\%(?![-{()<=#*%])', '\\1%%', stl)
|
||||
|
||||
# Create highlighting groups
|
||||
for group, hl in renderer.hl_groups.items():
|
||||
if vim_funcs['hlexists'](group):
|
||||
for idx, hl in renderer.hl_groups.items():
|
||||
if vim_funcs['hlexists'](hl['name']):
|
||||
# Only create hl group if it doesn't already exist
|
||||
continue
|
||||
|
||||
vim.command('hi {group} ctermfg={ctermfg} guifg={guifg} guibg={guibg} ctermbg={ctermbg} cterm={attr} gui={attr}'.format(
|
||||
group=group,
|
||||
group=hl['name'],
|
||||
ctermfg=hl['ctermfg'],
|
||||
guifg='#{0:06x}'.format(hl['guifg']) if hl['guifg'] != 'NONE' else 'NONE',
|
||||
ctermbg=hl['ctermbg'],
|
||||
|
|
|
@ -1,54 +1,42 @@
|
|||
def cterm_to_hex(cterm_color):
|
||||
'''Translate a cterm color index into the corresponding hex/RGB color.
|
||||
'''
|
||||
color_dict = {
|
||||
16: 0x000000, 17: 0x00005f, 18: 0x000087, 19: 0x0000af, 20: 0x0000d7, 21: 0x0000ff,
|
||||
22: 0x005f00, 23: 0x005f5f, 24: 0x005f87, 25: 0x005faf, 26: 0x005fd7, 27: 0x005fff,
|
||||
28: 0x008700, 29: 0x00875f, 30: 0x008787, 31: 0x0087af, 32: 0x0087d7, 33: 0x0087ff,
|
||||
34: 0x00af00, 35: 0x00af5f, 36: 0x00af87, 37: 0x00afaf, 38: 0x00afd7, 39: 0x00afff,
|
||||
40: 0x00d700, 41: 0x00d75f, 42: 0x00d787, 43: 0x00d7af, 44: 0x00d7d7, 45: 0x00d7ff,
|
||||
46: 0x00ff00, 47: 0x00ff5f, 48: 0x00ff87, 49: 0x00ffaf, 50: 0x00ffd7, 51: 0x00ffff,
|
||||
52: 0x5f0000, 53: 0x5f005f, 54: 0x5f0087, 55: 0x5f00af, 56: 0x5f00d7, 57: 0x5f00ff,
|
||||
58: 0x5f5f00, 59: 0x5f5f5f, 60: 0x5f5f87, 61: 0x5f5faf, 62: 0x5f5fd7, 63: 0x5f5fff,
|
||||
64: 0x5f8700, 65: 0x5f875f, 66: 0x5f8787, 67: 0x5f87af, 68: 0x5f87d7, 69: 0x5f87ff,
|
||||
70: 0x5faf00, 71: 0x5faf5f, 72: 0x5faf87, 73: 0x5fafaf, 74: 0x5fafd7, 75: 0x5fafff,
|
||||
76: 0x5fd700, 77: 0x5fd75f, 78: 0x5fd787, 79: 0x5fd7af, 80: 0x5fd7d7, 81: 0x5fd7ff,
|
||||
82: 0x5fff00, 83: 0x5fff5f, 84: 0x5fff87, 85: 0x5fffaf, 86: 0x5fffd7, 87: 0x5fffff,
|
||||
88: 0x870000, 89: 0x87005f, 90: 0x870087, 91: 0x8700af, 92: 0x8700d7, 93: 0x8700ff,
|
||||
94: 0x875f00, 95: 0x875f5f, 96: 0x875f87, 97: 0x875faf, 98: 0x875fd7, 99: 0x875fff,
|
||||
100: 0x878700, 101: 0x87875f, 102: 0x878787, 103: 0x8787af, 104: 0x8787d7, 105: 0x8787ff,
|
||||
106: 0x87af00, 107: 0x87af5f, 108: 0x87af87, 109: 0x87afaf, 110: 0x87afd7, 111: 0x87afff,
|
||||
112: 0x87d700, 113: 0x87d75f, 114: 0x87d787, 115: 0x87d7af, 116: 0x87d7d7, 117: 0x87d7ff,
|
||||
118: 0x87ff00, 119: 0x87ff5f, 120: 0x87ff87, 121: 0x87ffaf, 122: 0x87ffd7, 123: 0x87ffff,
|
||||
124: 0xaf0000, 125: 0xaf005f, 126: 0xaf0087, 127: 0xaf00af, 128: 0xaf00d7, 129: 0xaf00ff,
|
||||
130: 0xaf5f00, 131: 0xaf5f5f, 132: 0xaf5f87, 133: 0xaf5faf, 134: 0xaf5fd7, 135: 0xaf5fff,
|
||||
136: 0xaf8700, 137: 0xaf875f, 138: 0xaf8787, 139: 0xaf87af, 140: 0xaf87d7, 141: 0xaf87ff,
|
||||
142: 0xafaf00, 143: 0xafaf5f, 144: 0xafaf87, 145: 0xafafaf, 146: 0xafafd7, 147: 0xafafff,
|
||||
148: 0xafd700, 149: 0xafd75f, 150: 0xafd787, 151: 0xafd7af, 152: 0xafd7d7, 153: 0xafd7ff,
|
||||
154: 0xafff00, 155: 0xafff5f, 156: 0xafff87, 157: 0xafffaf, 158: 0xafffd7, 159: 0xafffff,
|
||||
160: 0xd70000, 161: 0xd7005f, 162: 0xd70087, 163: 0xd700af, 164: 0xd700d7, 165: 0xd700ff,
|
||||
166: 0xd75f00, 167: 0xd75f5f, 168: 0xd75f87, 169: 0xd75faf, 170: 0xd75fd7, 171: 0xd75fff,
|
||||
172: 0xd78700, 173: 0xd7875f, 174: 0xd78787, 175: 0xd787af, 176: 0xd787d7, 177: 0xd787ff,
|
||||
178: 0xd7af00, 179: 0xd7af5f, 180: 0xd7af87, 181: 0xd7afaf, 182: 0xd7afd7, 183: 0xd7afff,
|
||||
184: 0xd7d700, 185: 0xd7d75f, 186: 0xd7d787, 187: 0xd7d7af, 188: 0xd7d7d7, 189: 0xd7d7ff,
|
||||
190: 0xd7ff00, 191: 0xd7ff5f, 192: 0xd7ff87, 193: 0xd7ffaf, 194: 0xd7ffd7, 195: 0xd7ffff,
|
||||
196: 0xff0000, 197: 0xff005f, 198: 0xff0087, 199: 0xff00af, 200: 0xff00d7, 201: 0xff00ff,
|
||||
202: 0xff5f00, 203: 0xff5f5f, 204: 0xff5f87, 205: 0xff5faf, 206: 0xff5fd7, 207: 0xff5fff,
|
||||
208: 0xff8700, 209: 0xff875f, 210: 0xff8787, 211: 0xff87af, 212: 0xff87d7, 213: 0xff87ff,
|
||||
214: 0xffaf00, 215: 0xffaf5f, 216: 0xffaf87, 217: 0xffafaf, 218: 0xffafd7, 219: 0xffafff,
|
||||
220: 0xffd700, 221: 0xffd75f, 222: 0xffd787, 223: 0xffd7af, 224: 0xffd7d7, 225: 0xffd7ff,
|
||||
226: 0xffff00, 227: 0xffff5f, 228: 0xffff87, 229: 0xffffaf, 230: 0xffffd7, 231: 0xffffff,
|
||||
232: 0x080808, 233: 0x121212, 234: 0x1c1c1c, 235: 0x262626, 236: 0x303030, 237: 0x3a3a3a,
|
||||
238: 0x444444, 239: 0x4e4e4e, 240: 0x585858, 241: 0x626262, 242: 0x6c6c6c, 243: 0x767676,
|
||||
244: 0x808080, 245: 0x8a8a8a, 246: 0x949494, 247: 0x9e9e9e, 248: 0xa8a8a8, 249: 0xb2b2b2,
|
||||
250: 0xbcbcbc, 251: 0xc6c6c6, 252: 0xd0d0d0, 253: 0xdadada, 254: 0xe4e4e4, 255: 0xeeeeee,
|
||||
}
|
||||
if not cterm_color:
|
||||
return None
|
||||
|
||||
try:
|
||||
return color_dict[cterm_color]
|
||||
except KeyError:
|
||||
import sys
|
||||
sys.stderr.write('Invalid cterm color index: {0}\n'.format(cterm_color))
|
||||
return None
|
||||
cterm_to_hex = {
|
||||
16: 0x000000, 17: 0x00005f, 18: 0x000087, 19: 0x0000af, 20: 0x0000d7, 21: 0x0000ff,
|
||||
22: 0x005f00, 23: 0x005f5f, 24: 0x005f87, 25: 0x005faf, 26: 0x005fd7, 27: 0x005fff,
|
||||
28: 0x008700, 29: 0x00875f, 30: 0x008787, 31: 0x0087af, 32: 0x0087d7, 33: 0x0087ff,
|
||||
34: 0x00af00, 35: 0x00af5f, 36: 0x00af87, 37: 0x00afaf, 38: 0x00afd7, 39: 0x00afff,
|
||||
40: 0x00d700, 41: 0x00d75f, 42: 0x00d787, 43: 0x00d7af, 44: 0x00d7d7, 45: 0x00d7ff,
|
||||
46: 0x00ff00, 47: 0x00ff5f, 48: 0x00ff87, 49: 0x00ffaf, 50: 0x00ffd7, 51: 0x00ffff,
|
||||
52: 0x5f0000, 53: 0x5f005f, 54: 0x5f0087, 55: 0x5f00af, 56: 0x5f00d7, 57: 0x5f00ff,
|
||||
58: 0x5f5f00, 59: 0x5f5f5f, 60: 0x5f5f87, 61: 0x5f5faf, 62: 0x5f5fd7, 63: 0x5f5fff,
|
||||
64: 0x5f8700, 65: 0x5f875f, 66: 0x5f8787, 67: 0x5f87af, 68: 0x5f87d7, 69: 0x5f87ff,
|
||||
70: 0x5faf00, 71: 0x5faf5f, 72: 0x5faf87, 73: 0x5fafaf, 74: 0x5fafd7, 75: 0x5fafff,
|
||||
76: 0x5fd700, 77: 0x5fd75f, 78: 0x5fd787, 79: 0x5fd7af, 80: 0x5fd7d7, 81: 0x5fd7ff,
|
||||
82: 0x5fff00, 83: 0x5fff5f, 84: 0x5fff87, 85: 0x5fffaf, 86: 0x5fffd7, 87: 0x5fffff,
|
||||
88: 0x870000, 89: 0x87005f, 90: 0x870087, 91: 0x8700af, 92: 0x8700d7, 93: 0x8700ff,
|
||||
94: 0x875f00, 95: 0x875f5f, 96: 0x875f87, 97: 0x875faf, 98: 0x875fd7, 99: 0x875fff,
|
||||
100: 0x878700, 101: 0x87875f, 102: 0x878787, 103: 0x8787af, 104: 0x8787d7, 105: 0x8787ff,
|
||||
106: 0x87af00, 107: 0x87af5f, 108: 0x87af87, 109: 0x87afaf, 110: 0x87afd7, 111: 0x87afff,
|
||||
112: 0x87d700, 113: 0x87d75f, 114: 0x87d787, 115: 0x87d7af, 116: 0x87d7d7, 117: 0x87d7ff,
|
||||
118: 0x87ff00, 119: 0x87ff5f, 120: 0x87ff87, 121: 0x87ffaf, 122: 0x87ffd7, 123: 0x87ffff,
|
||||
124: 0xaf0000, 125: 0xaf005f, 126: 0xaf0087, 127: 0xaf00af, 128: 0xaf00d7, 129: 0xaf00ff,
|
||||
130: 0xaf5f00, 131: 0xaf5f5f, 132: 0xaf5f87, 133: 0xaf5faf, 134: 0xaf5fd7, 135: 0xaf5fff,
|
||||
136: 0xaf8700, 137: 0xaf875f, 138: 0xaf8787, 139: 0xaf87af, 140: 0xaf87d7, 141: 0xaf87ff,
|
||||
142: 0xafaf00, 143: 0xafaf5f, 144: 0xafaf87, 145: 0xafafaf, 146: 0xafafd7, 147: 0xafafff,
|
||||
148: 0xafd700, 149: 0xafd75f, 150: 0xafd787, 151: 0xafd7af, 152: 0xafd7d7, 153: 0xafd7ff,
|
||||
154: 0xafff00, 155: 0xafff5f, 156: 0xafff87, 157: 0xafffaf, 158: 0xafffd7, 159: 0xafffff,
|
||||
160: 0xd70000, 161: 0xd7005f, 162: 0xd70087, 163: 0xd700af, 164: 0xd700d7, 165: 0xd700ff,
|
||||
166: 0xd75f00, 167: 0xd75f5f, 168: 0xd75f87, 169: 0xd75faf, 170: 0xd75fd7, 171: 0xd75fff,
|
||||
172: 0xd78700, 173: 0xd7875f, 174: 0xd78787, 175: 0xd787af, 176: 0xd787d7, 177: 0xd787ff,
|
||||
178: 0xd7af00, 179: 0xd7af5f, 180: 0xd7af87, 181: 0xd7afaf, 182: 0xd7afd7, 183: 0xd7afff,
|
||||
184: 0xd7d700, 185: 0xd7d75f, 186: 0xd7d787, 187: 0xd7d7af, 188: 0xd7d7d7, 189: 0xd7d7ff,
|
||||
190: 0xd7ff00, 191: 0xd7ff5f, 192: 0xd7ff87, 193: 0xd7ffaf, 194: 0xd7ffd7, 195: 0xd7ffff,
|
||||
196: 0xff0000, 197: 0xff005f, 198: 0xff0087, 199: 0xff00af, 200: 0xff00d7, 201: 0xff00ff,
|
||||
202: 0xff5f00, 203: 0xff5f5f, 204: 0xff5f87, 205: 0xff5faf, 206: 0xff5fd7, 207: 0xff5fff,
|
||||
208: 0xff8700, 209: 0xff875f, 210: 0xff8787, 211: 0xff87af, 212: 0xff87d7, 213: 0xff87ff,
|
||||
214: 0xffaf00, 215: 0xffaf5f, 216: 0xffaf87, 217: 0xffafaf, 218: 0xffafd7, 219: 0xffafff,
|
||||
220: 0xffd700, 221: 0xffd75f, 222: 0xffd787, 223: 0xffd7af, 224: 0xffd7d7, 225: 0xffd7ff,
|
||||
226: 0xffff00, 227: 0xffff5f, 228: 0xffff87, 229: 0xffffaf, 230: 0xffffd7, 231: 0xffffff,
|
||||
232: 0x080808, 233: 0x121212, 234: 0x1c1c1c, 235: 0x262626, 236: 0x303030, 237: 0x3a3a3a,
|
||||
238: 0x444444, 239: 0x4e4e4e, 240: 0x585858, 241: 0x626262, 242: 0x6c6c6c, 243: 0x767676,
|
||||
244: 0x808080, 245: 0x8a8a8a, 246: 0x949494, 247: 0x9e9e9e, 248: 0xa8a8a8, 249: 0xb2b2b2,
|
||||
250: 0xbcbcbc, 251: 0xc6c6c6, 252: 0xd0d0d0, 253: 0xdadada, 254: 0xe4e4e4, 255: 0xeeeeee,
|
||||
}
|
||||
|
|
110
lib/core.py
110
lib/core.py
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from lib.colors import cterm_to_hex
|
||||
|
||||
|
||||
class Powerline:
|
||||
dividers = {
|
||||
|
@ -20,6 +22,7 @@ class Powerline:
|
|||
dropped from the segment array.
|
||||
'''
|
||||
self.segments = [segment for segment in segments if segment.contents or segment.filler]
|
||||
self._hl = {}
|
||||
|
||||
def render(self, renderer, width=None):
|
||||
'''Render all the segments with the specified renderer.
|
||||
|
@ -34,7 +37,7 @@ class Powerline:
|
|||
provided they will fill the remaining space until the desired width is
|
||||
reached.
|
||||
'''
|
||||
def render_segments(segments, render_raw=True, render_highlighted=True):
|
||||
def render_segments(segments, render_highlighted=True):
|
||||
'''Render a segment array.
|
||||
|
||||
By default this function renders both raw (un-highlighted segments
|
||||
|
@ -42,90 +45,94 @@ class Powerline:
|
|||
rendering is used for calculating the total width for dropping
|
||||
low-priority segments.
|
||||
'''
|
||||
rendered_raw = ''
|
||||
rendered_highlighted = ''
|
||||
segments_len = len(segments)
|
||||
empty_segment = Segment()
|
||||
|
||||
for idx, segment in enumerate(segments):
|
||||
prev = segments[idx - 1] if idx > 0 else Segment()
|
||||
next = segments[idx + 1] if idx < len(segments) - 1 else Segment()
|
||||
prev = segments[idx - 1] if idx > 0 else empty_segment
|
||||
next = segments[idx + 1] if idx < segments_len - 1 else empty_segment
|
||||
|
||||
compare_segment = next if segment.side == 'l' else prev
|
||||
divider_type = 'soft' if compare_segment.bg == segment.bg else 'hard'
|
||||
compare = next if segment.side == 'l' else prev
|
||||
outer_padding = ' ' if idx == 0 or idx == segments_len - 1 else ''
|
||||
divider_type = 'soft' if compare.bg == segment.bg else 'hard'
|
||||
divider = self.dividers[segment.side][divider_type]
|
||||
divider_hl = ''
|
||||
segment_hl = ''
|
||||
|
||||
if render_highlighted:
|
||||
# Generate and cache renderer highlighting
|
||||
if divider_type == 'hard':
|
||||
hl_key = (segment.bg, compare.bg)
|
||||
if not hl_key in self._hl:
|
||||
self._hl[hl_key] = renderer.hl(*hl_key)
|
||||
divider_hl = self._hl[hl_key]
|
||||
|
||||
hl_key = (segment.fg, segment.bg, segment.attr)
|
||||
if not hl_key in self._hl:
|
||||
self._hl[hl_key] = renderer.hl(*hl_key)
|
||||
segment_hl = self._hl[hl_key]
|
||||
|
||||
if segment.filler:
|
||||
# Filler segments shouldn't be padded
|
||||
segment_format = '{contents}'
|
||||
elif segment.draw_divider and (divider_type == 'hard' or segment.side == compare_segment.side):
|
||||
rendered_highlighted += segment.contents
|
||||
elif segment.draw_divider and (divider_type == 'hard' or segment.side == compare.side):
|
||||
# Draw divider if specified, and if the next segment is on
|
||||
# the opposite side only draw the divider if it's a hard
|
||||
# divider
|
||||
if segment.side == 'l':
|
||||
segment_format = '{segment_hl}{outer_padding}{contents} {divider_hl}{divider} '
|
||||
segment.rendered_raw += outer_padding + segment.contents + ' ' + divider + ' '
|
||||
rendered_highlighted += segment_hl + outer_padding + segment.contents + ' ' + divider_hl + divider + ' '
|
||||
else:
|
||||
segment_format = ' {divider_hl}{divider}{segment_hl} {contents}{outer_padding}'
|
||||
segment.rendered_raw += ' ' + divider + ' ' + segment.contents + outer_padding
|
||||
rendered_highlighted += ' ' + divider_hl + divider + segment_hl + ' ' + segment.contents + outer_padding
|
||||
elif segment.contents:
|
||||
# Segments without divider
|
||||
segment_format = '{segment_hl}{contents}{outer_padding}'
|
||||
if segment.side == 'l':
|
||||
segment.rendered_raw += outer_padding + segment.contents
|
||||
rendered_highlighted += segment_hl + outer_padding + segment.contents
|
||||
else:
|
||||
segment.rendered_raw += segment.contents + outer_padding
|
||||
rendered_highlighted += segment_hl + segment.contents + outer_padding
|
||||
else:
|
||||
# Unknown segment type, skip it
|
||||
continue
|
||||
|
||||
if render_raw is True and segment.filler is False:
|
||||
# Filler segments must be empty when used e.g. in vim (the
|
||||
# %=%< segment which disappears), so they will be skipped
|
||||
# when calculating the width using the raw rendering
|
||||
rendered_raw += segment_format.format(
|
||||
divider=divider,
|
||||
contents=segment.contents,
|
||||
divider_hl='',
|
||||
segment_hl='',
|
||||
outer_padding=' ' if idx == 0 or idx == len(segments) - 1 else '',
|
||||
)
|
||||
return rendered_highlighted.decode('utf-8')
|
||||
|
||||
if render_highlighted is True:
|
||||
rendered_highlighted += segment_format.format(
|
||||
divider=divider,
|
||||
contents=segment.contents,
|
||||
divider_hl='' if divider_type == 'soft' else renderer.hl(segment.bg, compare_segment.bg),
|
||||
segment_hl=renderer.hl(segment.fg, segment.bg, segment.attr),
|
||||
outer_padding=' ' if idx == 0 or idx == len(segments) - 1 else '',
|
||||
)
|
||||
|
||||
return {
|
||||
'highlighted': rendered_highlighted.decode('utf-8'),
|
||||
'raw': rendered_raw.decode('utf-8'),
|
||||
}
|
||||
|
||||
rendered = render_segments(self.segments)
|
||||
rendered_highlighted = render_segments(self.segments)
|
||||
|
||||
if not width:
|
||||
# No width specified, so we don't need to crop or pad anything
|
||||
return rendered['highlighted']
|
||||
return rendered_highlighted
|
||||
|
||||
# Create an ordered list of segments that can be dropped
|
||||
segments_priority = [segment for segment in sorted(self.segments, key=lambda segment: segment.priority, reverse=True) if segment.priority > 0]
|
||||
|
||||
while len(rendered['raw']) > width and len(segments_priority):
|
||||
while self._total_len() > width and len(segments_priority):
|
||||
# FIXME The remove method is quite expensive and we should find another way of removing low-priority segments
|
||||
self.segments.remove(segments_priority[0])
|
||||
segments_priority.pop(0)
|
||||
|
||||
rendered = render_segments(self.segments, render_highlighted=False)
|
||||
|
||||
# Distribute the remaining space on the filler segments
|
||||
segments_fillers = [segment for segment in self.segments if segment.filler is True]
|
||||
if segments_fillers:
|
||||
segments_fillers_len, segments_fillers_remainder = divmod((width - len(rendered['raw'])), len(segments_fillers))
|
||||
segments_fillers_len, segments_fillers_remainder = divmod((width - self._total_len()), len(segments_fillers))
|
||||
segments_fillers_contents = ' ' * segments_fillers_len
|
||||
for segment in segments_fillers:
|
||||
segment.contents = segments_fillers_contents
|
||||
# Add remainder whitespace to the first filler segment
|
||||
segments_fillers[0].contents += ' ' * segments_fillers_remainder
|
||||
|
||||
# Do a final render now that we have handled the cropping and padding
|
||||
rendered = render_segments(self.segments, render_raw=False)
|
||||
return render_segments(self.segments)
|
||||
|
||||
return rendered['highlighted']
|
||||
def _total_len(self):
|
||||
'''Return total/rendered length of all segments.
|
||||
|
||||
This method uses the rendered_raw property of the segments and requires
|
||||
that the segments have been rendered using the render() method first.
|
||||
'''
|
||||
return len(''.join([segment.rendered_raw for segment in self.segments]).decode('utf-8'))
|
||||
|
||||
|
||||
class Segment:
|
||||
|
@ -144,23 +151,20 @@ class Segment:
|
|||
self.draw_divider = draw_divider
|
||||
self.priority = priority
|
||||
self.filler = filler
|
||||
self.rendered_raw = ''
|
||||
|
||||
if self.filler:
|
||||
# Filler segments should never have any dividers
|
||||
self.draw_divider = False
|
||||
|
||||
try:
|
||||
if len(self.fg) != 2:
|
||||
raise TypeError
|
||||
self.fg = (fg[0], fg[1])
|
||||
except TypeError:
|
||||
# Only the terminal color is defined, so we need to get the hex color
|
||||
from lib.colors import cterm_to_hex
|
||||
self.fg = [self.fg, cterm_to_hex(self.fg)]
|
||||
self.fg = (self.fg, cterm_to_hex.get(self.fg, 0xffffff))
|
||||
|
||||
try:
|
||||
if len(self.bg) != 2:
|
||||
raise TypeError
|
||||
self.bg = (bg[0], bg[1])
|
||||
except TypeError:
|
||||
# Only the terminal color is defined, so we need to get the hex color
|
||||
from lib.colors import cterm_to_hex
|
||||
self.bg = [self.bg, cterm_to_hex(self.bg)]
|
||||
self.bg = (self.bg, cterm_to_hex.get(self.bg, 0x000000))
|
||||
|
|
|
@ -17,43 +17,44 @@ class VimSegmentRenderer(SegmentRenderer):
|
|||
False, the argument is reset to the terminal defaults. If an argument
|
||||
is a valid color or attribute, it's added to the vim highlight group.
|
||||
'''
|
||||
hl_group = {
|
||||
'ctermfg': 'NONE',
|
||||
'guifg': 'NONE',
|
||||
'ctermbg': 'NONE',
|
||||
'guibg': 'NONE',
|
||||
'attr': ['NONE'],
|
||||
}
|
||||
|
||||
# We don't need to explicitly reset attributes in vim, so skip those calls
|
||||
if not attr and not bg and not fg:
|
||||
return ''
|
||||
|
||||
if fg is not None and fg is not False:
|
||||
hl_group['ctermfg'] = fg[0]
|
||||
hl_group['guifg'] = fg[1]
|
||||
if not (fg, bg, attr) in self.hl_groups:
|
||||
hl_group = {
|
||||
'ctermfg': 'NONE',
|
||||
'guifg': 'NONE',
|
||||
'ctermbg': 'NONE',
|
||||
'guibg': 'NONE',
|
||||
'attr': ['NONE'],
|
||||
'name': '',
|
||||
}
|
||||
|
||||
if bg is not None and bg is not False:
|
||||
hl_group['ctermbg'] = bg[0]
|
||||
hl_group['guibg'] = bg[1]
|
||||
if fg is not None and fg is not False:
|
||||
hl_group['ctermfg'] = fg[0]
|
||||
hl_group['guifg'] = fg[1]
|
||||
|
||||
if attr is not None and attr is not False and attr != 0:
|
||||
hl_group['attr'] = []
|
||||
if attr & Segment.ATTR_BOLD:
|
||||
hl_group['attr'].append('bold')
|
||||
if attr & Segment.ATTR_ITALIC:
|
||||
hl_group['attr'].append('italic')
|
||||
if attr & Segment.ATTR_UNDERLINE:
|
||||
hl_group['attr'].append('underline')
|
||||
if bg is not None and bg is not False:
|
||||
hl_group['ctermbg'] = bg[0]
|
||||
hl_group['guibg'] = bg[1]
|
||||
|
||||
hl_group_name = 'Pl_{ctermfg}_{guifg}_{ctermbg}_{guibg}_{attr}'.format(
|
||||
ctermfg=hl_group['ctermfg'],
|
||||
guifg=hl_group['guifg'],
|
||||
ctermbg=hl_group['ctermbg'],
|
||||
guibg=hl_group['guibg'],
|
||||
attr=''.join(attr[0] for attr in hl_group['attr']),
|
||||
)
|
||||
if attr:
|
||||
hl_group['attr'] = []
|
||||
if attr & Segment.ATTR_BOLD:
|
||||
hl_group['attr'].append('bold')
|
||||
if attr & Segment.ATTR_ITALIC:
|
||||
hl_group['attr'].append('italic')
|
||||
if attr & Segment.ATTR_UNDERLINE:
|
||||
hl_group['attr'].append('underline')
|
||||
|
||||
self.hl_groups[hl_group_name] = hl_group
|
||||
hl_group['name'] = 'Pl_' + \
|
||||
str(hl_group['ctermfg']) + '_' + \
|
||||
str(hl_group['guifg']) + '_' + \
|
||||
str(hl_group['ctermbg']) + '_' + \
|
||||
str(hl_group['guibg']) + '_' + \
|
||||
''.join(hl_group['attr'])
|
||||
|
||||
return '%#{0}#'.format(hl_group_name)
|
||||
self.hl_groups[(fg, bg, attr)] = hl_group
|
||||
|
||||
return '%#' + self.hl_groups[(fg, bg, attr)]['name'] + '#'
|
||||
|
|
Loading…
Reference in New Issue