mirror of
https://github.com/powerline/powerline.git
synced 2025-07-24 22:36:01 +02:00
Merge pull request #1206 from ZyX-I/fbterm-support
Add support for fbterm
This commit is contained in:
commit
d2a1106c04
@ -26,6 +26,29 @@ Common configuration is a subdictionary that is a value of ``common`` key in
|
|||||||
to the terminal emulator. See the :ref:`term-feature-support-matrix` for
|
to the terminal emulator. See the :ref:`term-feature-support-matrix` for
|
||||||
information on whether your terminal emulator supports 24-bit colors.
|
information on whether your terminal emulator supports 24-bit colors.
|
||||||
|
|
||||||
|
This variable is forced to be ``false`` if :ref:`term_escape_style
|
||||||
|
<config-common-term_escape_style>` option is set to ``"fbterm"`` or if it is
|
||||||
|
set to ``"auto"`` and powerline detected fbterm.
|
||||||
|
|
||||||
|
.. _config-common-term_escape_style:
|
||||||
|
|
||||||
|
``term_escape_style``
|
||||||
|
Defines what escapes sequences should be used. Accepts three variants:
|
||||||
|
|
||||||
|
======= ===================================================================
|
||||||
|
Variant Description
|
||||||
|
======= ===================================================================
|
||||||
|
auto ``xterm`` or ``fbterm`` depending on ``$TERM`` variable value:
|
||||||
|
``TERM=fbterm`` implies ``fbterm`` escaping style, all other values
|
||||||
|
select ``xterm`` escaping.
|
||||||
|
xterm Uses ``\e[{fb};5;{color}m`` for colors (``{fb}`` is either ``38``
|
||||||
|
(foreground) or ``48`` (background)). Should be used for most
|
||||||
|
terminals.
|
||||||
|
fbterm Uses ``\e[{fb};{color}}`` for colors (``{fb}`` is either ``1``
|
||||||
|
(foreground) or ``2`` (background)). Should be used for fbterm:
|
||||||
|
framebuffer terminal.
|
||||||
|
======= ===================================================================
|
||||||
|
|
||||||
.. _config-common-ambiwidth:
|
.. _config-common-ambiwidth:
|
||||||
|
|
||||||
``ambiwidth``
|
``ambiwidth``
|
||||||
|
@ -52,6 +52,7 @@ if your terminal emulator supports it.
|
|||||||
Terminal.app OS X |i_yes| |i_no| |i_no|
|
Terminal.app OS X |i_yes| |i_no| |i_no|
|
||||||
libvte-based [#]_ Linux |i_yes| |i_yes| |i_yes| [#]_
|
libvte-based [#]_ Linux |i_yes| |i_yes| |i_yes| [#]_
|
||||||
xterm Linux |i_yes| |i_no| |i_partial| [#]_
|
xterm Linux |i_yes| |i_no| |i_partial| [#]_
|
||||||
|
fbterm Linux |i_yes| |i_yes| |i_no|
|
||||||
===================== ======= ===================== ===================== =====================
|
===================== ======= ===================== ===================== =====================
|
||||||
|
|
||||||
.. |i_yes| image:: _static/img/icons/tick.png
|
.. |i_yes| image:: _static/img/icons/tick.png
|
||||||
|
@ -258,6 +258,7 @@ def finish_common_config(encoding, common_config):
|
|||||||
common_config.setdefault('log_level', 'WARNING')
|
common_config.setdefault('log_level', 'WARNING')
|
||||||
common_config.setdefault('log_format', '%(asctime)s:%(levelname)s:%(message)s')
|
common_config.setdefault('log_format', '%(asctime)s:%(levelname)s:%(message)s')
|
||||||
common_config.setdefault('term_truecolor', False)
|
common_config.setdefault('term_truecolor', False)
|
||||||
|
common_config.setdefault('term_escape_style', 'auto')
|
||||||
common_config.setdefault('ambiwidth', 1)
|
common_config.setdefault('ambiwidth', 1)
|
||||||
common_config.setdefault('additional_escapes', None)
|
common_config.setdefault('additional_escapes', None)
|
||||||
common_config.setdefault('reload_config', True)
|
common_config.setdefault('reload_config', True)
|
||||||
@ -474,6 +475,7 @@ class Powerline(object):
|
|||||||
mergedicts(self.renderer_options, dict(
|
mergedicts(self.renderer_options, dict(
|
||||||
pl=self.pl,
|
pl=self.pl,
|
||||||
term_truecolor=self.common_config['term_truecolor'],
|
term_truecolor=self.common_config['term_truecolor'],
|
||||||
|
term_escape_style=self.common_config['term_escape_style'],
|
||||||
ambiwidth=self.common_config['ambiwidth'],
|
ambiwidth=self.common_config['ambiwidth'],
|
||||||
tmux_escape=self.common_config['additional_escapes'] == 'tmux',
|
tmux_escape=self.common_config['additional_escapes'] == 'tmux',
|
||||||
screen_escape=self.common_config['additional_escapes'] == 'screen',
|
screen_escape=self.common_config['additional_escapes'] == 'screen',
|
||||||
|
@ -57,6 +57,7 @@ main_spec = (Spec(
|
|||||||
common=Spec(
|
common=Spec(
|
||||||
default_top_theme=top_theme_spec().optional(),
|
default_top_theme=top_theme_spec().optional(),
|
||||||
term_truecolor=Spec().type(bool).optional(),
|
term_truecolor=Spec().type(bool).optional(),
|
||||||
|
term_escape_style=Spec().type(unicode).oneof(set(('auto', 'xterm', 'fbterm'))).optional(),
|
||||||
# Python is capable of loading from zip archives. Thus checking path
|
# Python is capable of loading from zip archives. Thus checking path
|
||||||
# only for existence of the path, not for it being a directory
|
# only for existence of the path, not for it being a directory
|
||||||
paths=Spec().list(
|
paths=Spec().list(
|
||||||
|
@ -291,7 +291,7 @@ class Renderer(object):
|
|||||||
line=line,
|
line=line,
|
||||||
output_raw=output_raw,
|
output_raw=output_raw,
|
||||||
output_width=output_width,
|
output_width=output_width,
|
||||||
segment_info=segment_info,
|
segment_info=self.get_segment_info(segment_info, mode),
|
||||||
theme=theme,
|
theme=theme,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ class Renderer(object):
|
|||||||
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme):
|
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme):
|
||||||
'''Like Renderer.render(), but accept theme in place of matcher_info
|
'''Like Renderer.render(), but accept theme in place of matcher_info
|
||||||
'''
|
'''
|
||||||
segments = list(theme.get_segments(side, line, self.get_segment_info(segment_info, mode), mode))
|
segments = list(theme.get_segments(side, line, segment_info, mode))
|
||||||
|
|
||||||
current_width = 0
|
current_width = 0
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ class ShellRenderer(Renderer):
|
|||||||
escape_hl_start = ''
|
escape_hl_start = ''
|
||||||
escape_hl_end = ''
|
escape_hl_end = ''
|
||||||
term_truecolor = False
|
term_truecolor = False
|
||||||
|
term_escape_style = 'auto'
|
||||||
tmux_escape = False
|
tmux_escape = False
|
||||||
screen_escape = False
|
screen_escape = False
|
||||||
|
|
||||||
@ -36,6 +37,13 @@ class ShellRenderer(Renderer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def do_render(self, output_width, segment_info, side, theme, width=None, **kwargs):
|
def do_render(self, output_width, segment_info, side, theme, width=None, **kwargs):
|
||||||
|
if self.term_escape_style == 'auto':
|
||||||
|
if segment_info['environ'].get('TERM') == 'fbterm':
|
||||||
|
self.used_term_escape_style = 'fbterm'
|
||||||
|
else:
|
||||||
|
self.used_term_escape_style = 'xterm'
|
||||||
|
else:
|
||||||
|
self.used_term_escape_style = self.term_escape_style
|
||||||
if isinstance(segment_info, dict):
|
if isinstance(segment_info, dict):
|
||||||
client_id = segment_info.get('client_id')
|
client_id = segment_info.get('client_id')
|
||||||
else:
|
else:
|
||||||
@ -85,11 +93,13 @@ class ShellRenderer(Renderer):
|
|||||||
is a valid color or attribute, it’s added to the ANSI escape code.
|
is a valid color or attribute, it’s added to the ANSI escape code.
|
||||||
'''
|
'''
|
||||||
ansi = [0]
|
ansi = [0]
|
||||||
|
is_fbterm = self.used_term_escape_style == 'fbterm'
|
||||||
|
term_truecolor = not is_fbterm and self.term_truecolor
|
||||||
if fg is not None:
|
if fg is not None:
|
||||||
if fg is False or fg[0] is False:
|
if fg is False or fg[0] is False:
|
||||||
ansi += [39]
|
ansi += [39]
|
||||||
else:
|
else:
|
||||||
if self.term_truecolor:
|
if term_truecolor:
|
||||||
ansi += [38, 2] + list(int_to_rgb(fg[1]))
|
ansi += [38, 2] + list(int_to_rgb(fg[1]))
|
||||||
else:
|
else:
|
||||||
ansi += [38, 5, fg[0]]
|
ansi += [38, 5, fg[0]]
|
||||||
@ -97,7 +107,7 @@ class ShellRenderer(Renderer):
|
|||||||
if bg is False or bg[0] is False:
|
if bg is False or bg[0] is False:
|
||||||
ansi += [49]
|
ansi += [49]
|
||||||
else:
|
else:
|
||||||
if self.term_truecolor:
|
if term_truecolor:
|
||||||
ansi += [48, 2] + list(int_to_rgb(bg[1]))
|
ansi += [48, 2] + list(int_to_rgb(bg[1]))
|
||||||
else:
|
else:
|
||||||
ansi += [48, 5, bg[0]]
|
ansi += [48, 5, bg[0]]
|
||||||
@ -113,7 +123,21 @@ class ShellRenderer(Renderer):
|
|||||||
ansi += [3]
|
ansi += [3]
|
||||||
elif attr & ATTR_UNDERLINE:
|
elif attr & ATTR_UNDERLINE:
|
||||||
ansi += [4]
|
ansi += [4]
|
||||||
r = '\033[{0}m'.format(';'.join(str(attr) for attr in ansi))
|
if is_fbterm:
|
||||||
|
r = []
|
||||||
|
while ansi:
|
||||||
|
cur_ansi = ansi.pop(0)
|
||||||
|
if cur_ansi == 38:
|
||||||
|
ansi.pop(0)
|
||||||
|
r.append('\033[1;{0}}}'.format(ansi.pop(0)))
|
||||||
|
elif cur_ansi == 48:
|
||||||
|
ansi.pop(0)
|
||||||
|
r.append('\033[2;{0}}}'.format(ansi.pop(0)))
|
||||||
|
else:
|
||||||
|
r.append('\033[{0}m'.format(cur_ansi))
|
||||||
|
r = ''.join(r)
|
||||||
|
else:
|
||||||
|
r = '\033[{0}m'.format(';'.join(str(attr) for attr in ansi))
|
||||||
if self.tmux_escape:
|
if self.tmux_escape:
|
||||||
r = '\033Ptmux;' + r.replace('\033', '\033\033') + '\033\\'
|
r = '\033Ptmux;' + r.replace('\033', '\033\033') + '\033\\'
|
||||||
elif self.screen_escape:
|
elif self.screen_escape:
|
||||||
|
@ -39,6 +39,10 @@ config = {
|
|||||||
'theme': 'default',
|
'theme': 'default',
|
||||||
'colorscheme': 'default',
|
'colorscheme': 'default',
|
||||||
},
|
},
|
||||||
|
'shell': {
|
||||||
|
'theme': 'default',
|
||||||
|
'colorscheme': 'default',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'colors': {
|
'colors': {
|
||||||
@ -131,6 +135,14 @@ config = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'themes/shell/default': {
|
||||||
|
'default_module': 'powerline.segments.common',
|
||||||
|
'segments': {
|
||||||
|
'left': [
|
||||||
|
highlighted_string('s', 'g1', width='auto'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -639,6 +651,102 @@ class TestSegmentData(TestRender):
|
|||||||
self.assertRenderEqual(p, '{56} 1S{56}>{56}3S{610}>>{910}3S{910}>{910}2S{10-}>>{--}')
|
self.assertRenderEqual(p, '{56} 1S{56}>{56}3S{610}>>{910}3S{910}>{910}2S{10-}>>{--}')
|
||||||
|
|
||||||
|
|
||||||
|
class TestShellEscapes(TestCase):
|
||||||
|
@with_new_config
|
||||||
|
def test_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0;38;5;5;48;5;6m\xa0s\x1b[0;38;5;6;49;22m>>\x1b[0m')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_tmux_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['additional_escapes'] = 'tmux'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0;38;5;5;48;5;6m\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0;38;5;6;49;22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_screen_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['additional_escapes'] = 'screen'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0;38;5;5;48;5;6m\x1b\\\xa0s\x1bP\x1b\x1b[0;38;5;6;49;22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_fbterm_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_escape_style'] = 'fbterm'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0m\x1b[1;5}\x1b[2;6}\xa0s\x1b[0m\x1b[1;6}\x1b[49m\x1b[22m>>\x1b[0m')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_fbterm_tmux_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_escape_style'] = 'fbterm'
|
||||||
|
config['config']['common']['additional_escapes'] = 'tmux'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0m\x1b\x1b[1;5}\x1b\x1b[2;6}\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0m\x1b\x1b[1;6}\x1b\x1b[49m\x1b\x1b[22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_fbterm_screen_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_escape_style'] = 'fbterm'
|
||||||
|
config['config']['common']['additional_escapes'] = 'screen'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0m\x1b\x1b[1;5}\x1b\x1b[2;6}\x1b\\\xa0s\x1bP\x1b\x1b[0m\x1b\x1b[1;6}\x1b\x1b[49m\x1b\x1b[22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_term_truecolor_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_truecolor'] = True
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0;38;2;192;0;192;48;2;0;128;128m\xa0s\x1b[0;38;2;0;128;128;49;22m>>\x1b[0m')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_term_truecolor_fbterm_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_escape_style'] = 'fbterm'
|
||||||
|
config['config']['common']['term_truecolor'] = True
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1b[0m\x1b[1;5}\x1b[2;6}\xa0s\x1b[0m\x1b[1;6}\x1b[49m\x1b[22m>>\x1b[0m')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_term_truecolor_tmux_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_truecolor'] = True
|
||||||
|
config['config']['common']['additional_escapes'] = 'tmux'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bPtmux;\x1b\x1b[0;38;2;192;0;192;48;2;0;128;128m\x1b\\\xa0s\x1bPtmux;\x1b\x1b[0;38;2;0;128;128;49;22m\x1b\\>>\x1bPtmux;\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
@with_new_config
|
||||||
|
def test_term_truecolor_screen_escapes(self, config):
|
||||||
|
from powerline.shell import ShellPowerline
|
||||||
|
import powerline as powerline_module
|
||||||
|
config['config']['common']['term_truecolor'] = True
|
||||||
|
config['config']['common']['additional_escapes'] = 'screen'
|
||||||
|
with swap_attributes(config, powerline_module):
|
||||||
|
with get_powerline_raw(config, ShellPowerline, args=Args(config_path=[''])) as powerline:
|
||||||
|
self.assertEqual(powerline.render(segment_info={}, side='left'), '\x1bP\x1b\x1b[0;38;2;192;0;192;48;2;0;128;128m\x1b\\\xa0s\x1bP\x1b\x1b[0;38;2;0;128;128;49;22m\x1b\\>>\x1bP\x1b\x1b[0m\x1b\\')
|
||||||
|
|
||||||
|
|
||||||
class TestVim(TestCase):
|
class TestVim(TestCase):
|
||||||
def test_environ_update(self):
|
def test_environ_update(self):
|
||||||
# Regression test: test that segment obtains environment from vim, not
|
# Regression test: test that segment obtains environment from vim, not
|
||||||
|
Loading…
x
Reference in New Issue
Block a user