mirror of
https://github.com/powerline/powerline.git
synced 2025-07-25 14:54:54 +02:00
Initial support for #770
What was done: - Implemented loading using configuration hierarhy as proposed in the issue - Implemented group aliasing What was not: - Some tests (config_reload) are failing - Other (test_configuration) are spamming console with unexpected messages - No support for powerline-lint - No tests for new functionality - Specifically I have not checked whether group aliasing actually works - Colorschemes were not ported Some other things: I have named this branch `config-ng` because I have other ideas about configuration and it would be good to include them making only one possibly backwards-incompatible merge commit instead of many. Specifically I am going to rebase `merge-config` branch here.
This commit is contained in:
parent
2d1a964e32
commit
97266b7ffc
@ -9,6 +9,7 @@ from powerline.colorscheme import Colorscheme
|
|||||||
from powerline.lib.config import ConfigLoader
|
from powerline.lib.config import ConfigLoader
|
||||||
from powerline.lib.unicode import safe_unicode, FailedUnicode
|
from powerline.lib.unicode import safe_unicode, FailedUnicode
|
||||||
from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR
|
from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR
|
||||||
|
from powerline.lib import mergedicts
|
||||||
|
|
||||||
from threading import Lock, Event
|
from threading import Lock, Event
|
||||||
|
|
||||||
@ -220,6 +221,22 @@ def finish_common_config(common_config):
|
|||||||
return common_config
|
return common_config
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info < (3,):
|
||||||
|
# `raise exception[0], None, exception[1]` is a SyntaxError in python-3*
|
||||||
|
# Not using ('''…''') because this syntax does not work in python-2.6
|
||||||
|
exec(('def reraise(exception):\n'
|
||||||
|
' if type(exception) is tuple:\n'
|
||||||
|
' raise exception[0], None, exception[1]\n'
|
||||||
|
' else:\n'
|
||||||
|
' raise exception\n'))
|
||||||
|
else:
|
||||||
|
def reraise(exception):
|
||||||
|
if type(exception) is tuple:
|
||||||
|
raise exception[0].with_traceback(exception[1])
|
||||||
|
else:
|
||||||
|
raise exception
|
||||||
|
|
||||||
|
|
||||||
class Powerline(object):
|
class Powerline(object):
|
||||||
'''Main powerline class, entrance point for all powerline uses. Sets
|
'''Main powerline class, entrance point for all powerline uses. Sets
|
||||||
powerline up and loads the configuration.
|
powerline up and loads the configuration.
|
||||||
@ -455,7 +472,38 @@ class Powerline(object):
|
|||||||
|
|
||||||
:return: dictionary with :ref:`colorscheme configuration <config-colorschemes>`.
|
:return: dictionary with :ref:`colorscheme configuration <config-colorschemes>`.
|
||||||
'''
|
'''
|
||||||
return self._load_config(os.path.join('colorschemes', self.ext, name), 'colorscheme')
|
# TODO Make sure no colorscheme name ends with __ (do it in
|
||||||
|
# powerline-lint)
|
||||||
|
levels = (
|
||||||
|
os.path.join('colorschemes', name),
|
||||||
|
os.path.join('colorschemes', self.ext, '__main__'),
|
||||||
|
os.path.join('colorschemes', self.ext, name),
|
||||||
|
)
|
||||||
|
config = {}
|
||||||
|
loaded = 0
|
||||||
|
exceptions = []
|
||||||
|
for cfg_path in levels:
|
||||||
|
try:
|
||||||
|
lvl_config = self._load_config(cfg_path, 'colorscheme')
|
||||||
|
except IOError as e:
|
||||||
|
if sys.version_info < (3,):
|
||||||
|
tb = sys.exc_info()[2]
|
||||||
|
exceptions.append((e, tb))
|
||||||
|
else:
|
||||||
|
exceptions.append(e)
|
||||||
|
else:
|
||||||
|
if not cfg_path.endswith('__'):
|
||||||
|
loaded += 1
|
||||||
|
mergedicts(config, lvl_config)
|
||||||
|
if not loaded:
|
||||||
|
for exception in exceptions:
|
||||||
|
if type(exception) is tuple:
|
||||||
|
e = exception[0]
|
||||||
|
else:
|
||||||
|
e = exception
|
||||||
|
self.exception('Failed to load colorscheme: {0}', e, exception=exception)
|
||||||
|
raise e
|
||||||
|
return config
|
||||||
|
|
||||||
def load_colors_config(self):
|
def load_colors_config(self):
|
||||||
'''Get colorscheme.
|
'''Get colorscheme.
|
||||||
@ -562,5 +610,11 @@ class Powerline(object):
|
|||||||
def exception(self, msg, *args, **kwargs):
|
def exception(self, msg, *args, **kwargs):
|
||||||
if 'prefix' not in kwargs:
|
if 'prefix' not in kwargs:
|
||||||
kwargs['prefix'] = 'powerline'
|
kwargs['prefix'] = 'powerline'
|
||||||
|
exception = kwargs.pop('exception', None)
|
||||||
pl = getattr(self, 'pl', None) or get_fallback_logger()
|
pl = getattr(self, 'pl', None) or get_fallback_logger()
|
||||||
|
if exception:
|
||||||
|
try:
|
||||||
|
reraise(exception)
|
||||||
|
except Exception:
|
||||||
|
return pl.exception(msg, *args, **kwargs)
|
||||||
return pl.exception(msg, *args, **kwargs)
|
return pl.exception(msg, *args, **kwargs)
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# vim:fileencoding=utf-8:noet
|
# vim:fileencoding=utf-8:noet
|
||||||
|
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
try:
|
||||||
|
from __builtin__ import unicode
|
||||||
|
except ImportError:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_MODE_KEY = None
|
DEFAULT_MODE_KEY = None
|
||||||
@ -70,32 +74,41 @@ class Colorscheme(object):
|
|||||||
else:
|
else:
|
||||||
return self.colors[gradient]
|
return self.colors[gradient]
|
||||||
|
|
||||||
def get_highlighting(self, groups, mode, gradient_level=None):
|
def get_group_props(self, mode, trans, group, translate_colors=True):
|
||||||
trans = self.translations.get(mode, {})
|
if isinstance(group, (str, unicode)):
|
||||||
for group in hl_iter(groups):
|
try:
|
||||||
if 'groups' in trans and group in trans['groups']:
|
group_props = trans['groups'][group]
|
||||||
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
group_props = trans['groups'][group]
|
group_props = self.groups[group]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
continue
|
return None
|
||||||
break
|
else:
|
||||||
|
return self.get_group_props(mode, trans, group_props, True)
|
||||||
else:
|
else:
|
||||||
try:
|
return self.get_group_props(mode, trans, group_props, False)
|
||||||
group_props = copy(self.groups[group])
|
else:
|
||||||
except KeyError:
|
if translate_colors:
|
||||||
continue
|
group_props = copy(group)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ctrans = trans['colors']
|
ctrans = trans['colors']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
for key in ('fg', 'bg'):
|
for key in ('fg', 'bg'):
|
||||||
try:
|
try:
|
||||||
group_props[key] = ctrans[group_props[key]]
|
group_props[key] = ctrans[group_props[key]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
except KeyError:
|
return group_props
|
||||||
pass
|
else:
|
||||||
|
return group
|
||||||
|
|
||||||
|
def get_highlighting(self, groups, mode, gradient_level=None):
|
||||||
|
trans = self.translations.get(mode, {})
|
||||||
|
for group in hl_iter(groups):
|
||||||
|
group_props = self.get_group_props(mode, trans, group)
|
||||||
|
if group_props:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise KeyError('Highlighting groups not found in colorscheme: ' + ', '.join(hl_iter(groups)))
|
raise KeyError('Highlighting groups not found in colorscheme: ' + ', '.join(hl_iter(groups)))
|
||||||
|
@ -101,7 +101,7 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=True) as p:
|
with get_powerline(run_once=True) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
config['config']['common']['spaces'] = 1
|
config['config']['common']['spaces'] = 1
|
||||||
add_watcher_events(p, 'config', wait=False, interval=0.05)
|
add_watcher_events(p, 'config', wait=False, interval=0.05)
|
||||||
# When running once thread should not start
|
# When running once thread should not start
|
||||||
@ -117,7 +117,7 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['config']['common']['spaces'] = 1
|
config['config']['common']['spaces'] = 1
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
@ -141,14 +141,19 @@ class TestConfigReload(TestCase):
|
|||||||
config['config']['ext']['test']['colorscheme'] = 'nonexistent'
|
config['config']['ext']['test']['colorscheme'] = 'nonexistent'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colorschemes/test/nonexistent')
|
self.assertAccessEvents('config', 'colorschemes/nonexistent', 'colorschemes/test/__main__', 'colorschemes/test/nonexistent')
|
||||||
# It should normally handle file missing error
|
# It should normally handle file missing error
|
||||||
self.assertEqual(p.logger._pop_msgs(), ['exception:test:powerline:Failed to create renderer: colorschemes/test/nonexistent'])
|
self.assertEqual(p.logger._pop_msgs(), [
|
||||||
|
'exception:test:powerline:Failed to load colorscheme: colorschemes/nonexistent',
|
||||||
|
'exception:test:powerline:Failed to load colorscheme: colorschemes/test/__main__',
|
||||||
|
'exception:test:powerline:Failed to load colorscheme: colorschemes/test/nonexistent',
|
||||||
|
'exception:test:powerline:Failed to create renderer: colorschemes/test/nonexistent'
|
||||||
|
])
|
||||||
|
|
||||||
config['config']['ext']['test']['colorscheme'] = '2'
|
config['config']['ext']['test']['colorscheme'] = '2'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colorschemes/test/2')
|
self.assertAccessEvents('config', 'colorschemes/2', 'colorschemes/test/__main__', 'colorschemes/test/2')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
|
|
||||||
config['config']['ext']['test']['theme'] = '2'
|
config['config']['ext']['test']['theme'] = '2'
|
||||||
@ -170,7 +175,7 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['config']['ext']['test']['colorscheme'] = 'nonexistentraise'
|
config['config']['ext']['test']['colorscheme'] = 'nonexistentraise'
|
||||||
add_watcher_events(p, 'config')
|
add_watcher_events(p, 'config')
|
||||||
@ -192,7 +197,7 @@ class TestConfigReload(TestCase):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
while not p._will_create_renderer():
|
while not p._will_create_renderer():
|
||||||
sleep(0.000001)
|
sleep(0.1)
|
||||||
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('colorschemes/test/nonexistentraise')
|
self.assertAccessEvents('colorschemes/test/nonexistentraise')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
@ -202,7 +207,7 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['colors']['colors']['col1'] = 5
|
config['colors']['colors']['col1'] = 5
|
||||||
add_watcher_events(p, 'colors')
|
add_watcher_events(p, 'colors')
|
||||||
@ -215,12 +220,12 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3'
|
config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3'
|
||||||
add_watcher_events(p, 'colorschemes/test/default')
|
add_watcher_events(p, 'colorschemes/test/default')
|
||||||
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('colorschemes/test/default')
|
self.assertAccessEvents('colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default')
|
||||||
self.assertEqual(p.logger._pop_msgs(), [])
|
self.assertEqual(p.logger._pop_msgs(), [])
|
||||||
pop_events()
|
pop_events()
|
||||||
|
|
||||||
@ -228,7 +233,7 @@ class TestConfigReload(TestCase):
|
|||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
with replace_item(globals(), 'config', deepcopy(config)):
|
with replace_item(globals(), 'config', deepcopy(config)):
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
||||||
add_watcher_events(p, 'themes/test/default')
|
add_watcher_events(p, 'themes/test/default')
|
||||||
@ -242,7 +247,7 @@ class TestConfigReload(TestCase):
|
|||||||
config['config']['common']['interval'] = None
|
config['config']['common']['interval'] = None
|
||||||
with get_powerline(run_once=False) as p:
|
with get_powerline(run_once=False) as p:
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
||||||
add_watcher_events(p, 'themes/test/default', wait=False)
|
add_watcher_events(p, 'themes/test/default', wait=False)
|
||||||
@ -257,7 +262,7 @@ class TestConfigReload(TestCase):
|
|||||||
config['config']['common']['interval'] = None
|
config['config']['common']['interval'] = None
|
||||||
with get_powerline(run_once=True) as p:
|
with get_powerline(run_once=True) as p:
|
||||||
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
|
||||||
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default')
|
self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
|
||||||
|
|
||||||
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
|
||||||
add_watcher_events(p, 'themes/test/default', wait=False)
|
add_watcher_events(p, 'themes/test/default', wait=False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user