parent
3d77306c35
commit
27db44ac7a
|
@ -14,13 +14,25 @@ from powerline.lib import mergedicts
|
|||
from threading import Lock, Event
|
||||
|
||||
|
||||
def _find_config_file(search_paths, config_file):
|
||||
def _config_loader_condition(path):
|
||||
return path and os.path.isfile(path)
|
||||
|
||||
|
||||
def _find_config_files(search_paths, config_file, config_loader=None, loader_callback=None):
|
||||
config_file += '.json'
|
||||
found = False
|
||||
for path in search_paths:
|
||||
config_file_path = os.path.join(path, config_file)
|
||||
if os.path.isfile(config_file_path):
|
||||
return config_file_path
|
||||
raise IOError('Config file not found in search path: {0}'.format(config_file))
|
||||
yield config_file_path
|
||||
found = True
|
||||
elif config_loader:
|
||||
config_loader.register_missing(_config_loader_condition, loader_callback, config_file_path)
|
||||
if not found:
|
||||
raise IOError('Config file not found in search paths ({0}): {1}'.format(
|
||||
', '.join(search_paths),
|
||||
config_file
|
||||
))
|
||||
|
||||
|
||||
class PowerlineLogger(object):
|
||||
|
@ -103,14 +115,14 @@ def get_config_paths():
|
|||
config_paths = [config_path]
|
||||
config_dirs = os.environ.get('XDG_CONFIG_DIRS', DEFAULT_SYSTEM_CONFIG_DIR)
|
||||
if config_dirs is not None:
|
||||
config_paths.extend([os.path.join(d, 'powerline') for d in config_dirs.split(':')])
|
||||
config_paths[:0] = reversed([os.path.join(d, 'powerline') for d in config_dirs.split(':')])
|
||||
plugin_path = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'config_files')
|
||||
config_paths.append(plugin_path)
|
||||
config_paths.insert(0, plugin_path)
|
||||
return config_paths
|
||||
|
||||
|
||||
def generate_config_finder(get_config_paths=get_config_paths):
|
||||
'''Generate find_config_file function
|
||||
'''Generate find_config_files function
|
||||
|
||||
This function will find .json file given its path.
|
||||
|
||||
|
@ -123,17 +135,17 @@ def generate_config_finder(get_config_paths=get_config_paths):
|
|||
to it or raise IOError if it failed to find the file.
|
||||
'''
|
||||
config_paths = get_config_paths()
|
||||
return lambda cfg_path: _find_config_file(config_paths, cfg_path)
|
||||
return lambda *args: _find_config_files(config_paths, *args)
|
||||
|
||||
|
||||
def load_config(cfg_path, find_config_file, config_loader, loader_callback=None):
|
||||
def load_config(cfg_path, find_config_files, config_loader, loader_callback=None):
|
||||
'''Load configuration file and setup watches
|
||||
|
||||
Watches are only set up if loader_callback is not None.
|
||||
|
||||
:param str cfg_path:
|
||||
Path for configuration file that should be loaded.
|
||||
:param function find_config_file:
|
||||
:param function find_config_files:
|
||||
Function that finds configuration file. Check out the description of
|
||||
the return value of ``generate_config_finder`` function.
|
||||
:param ConfigLoader config_loader:
|
||||
|
@ -144,16 +156,16 @@ def load_config(cfg_path, find_config_file, config_loader, loader_callback=None)
|
|||
|
||||
:return: Configuration file contents.
|
||||
'''
|
||||
try:
|
||||
path = find_config_file(cfg_path)
|
||||
except IOError:
|
||||
if loader_callback:
|
||||
config_loader.register_missing(find_config_file, loader_callback, cfg_path)
|
||||
raise
|
||||
else:
|
||||
found_files = find_config_files(cfg_path, config_loader, loader_callback)
|
||||
ret = None
|
||||
for path in found_files:
|
||||
if loader_callback:
|
||||
config_loader.register(loader_callback, path)
|
||||
return config_loader.load(path)
|
||||
if ret is None:
|
||||
ret = config_loader.load(path)
|
||||
else:
|
||||
mergedicts(ret, config_loader.load(path))
|
||||
return ret
|
||||
|
||||
|
||||
def _get_log_handler(common_config):
|
||||
|
@ -286,7 +298,7 @@ class Powerline(object):
|
|||
elif self.renderer_module[-1] == '.':
|
||||
self.renderer_module = self.renderer_module[:-1]
|
||||
|
||||
self.find_config_file = generate_config_finder(self.get_config_paths)
|
||||
self.find_config_files = generate_config_finder(self.get_config_paths)
|
||||
|
||||
self.cr_kwargs_lock = Lock()
|
||||
self.cr_kwargs = {}
|
||||
|
@ -437,7 +449,7 @@ class Powerline(object):
|
|||
'''Load configuration and setup watches.'''
|
||||
return load_config(
|
||||
cfg_path,
|
||||
self.find_config_file,
|
||||
self.find_config_files,
|
||||
self.config_loader,
|
||||
self.cr_callbacks[type]
|
||||
)
|
||||
|
@ -445,7 +457,7 @@ class Powerline(object):
|
|||
def _purge_configs(self, type):
|
||||
function = self.cr_callbacks[type]
|
||||
self.config_loader.unregister_functions(set((function,)))
|
||||
self.config_loader.unregister_missing(set(((self.find_config_file, function),)))
|
||||
self.config_loader.unregister_missing(set(((self.find_config_files, function),)))
|
||||
|
||||
def load_theme_config(self, name):
|
||||
'''Get theme configuration.
|
||||
|
@ -601,7 +613,7 @@ class Powerline(object):
|
|||
pass
|
||||
functions = tuple(self.cr_callbacks.values())
|
||||
self.config_loader.unregister_functions(set(functions))
|
||||
self.config_loader.unregister_missing(set(((self.find_config_file, function) for function in functions)))
|
||||
self.config_loader.unregister_missing(set(((self.find_config_files, function) for function in functions)))
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
|
|
@ -119,9 +119,9 @@ def source_tmux_files(pl, args):
|
|||
|
||||
|
||||
def create_powerline_logger(args):
|
||||
find_config_file = generate_config_finder()
|
||||
find_config_files = generate_config_finder()
|
||||
config_loader = ConfigLoader(run_once=True)
|
||||
config = load_config('config', find_config_file, config_loader)
|
||||
config = load_config('config', find_config_files, config_loader)
|
||||
common_config = finish_common_config(config['common'])
|
||||
logger = create_logger(common_config)
|
||||
return PowerlineLogger(use_daemon_threads=True, logger=logger, ext='config')
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
|
||||
from powerline.lint.markedjson import load
|
||||
from powerline import generate_config_finder, get_config_paths
|
||||
from powerline.lib.config import load_json_config
|
||||
from powerline import generate_config_finder, get_config_paths, load_config
|
||||
from powerline.lib.config import ConfigLoader
|
||||
from powerline.lint.markedjson.error import echoerr, MarkedError
|
||||
from powerline.segments.vim import vim_modes
|
||||
from powerline.lint.inspect import getconfigargspec
|
||||
|
@ -1261,9 +1261,19 @@ theme_spec = (Spec(
|
|||
).context_message('Error while loading theme'))
|
||||
|
||||
|
||||
def generate_json_config_loader(lhadproblem):
|
||||
def load_json_config(config_file_path, load=load, open_file=open_file):
|
||||
with open_file(config_file_path) as config_file_fp:
|
||||
r, hadproblem = load(config_file_fp)
|
||||
if hadproblem:
|
||||
lhadproblem[0] = True
|
||||
return r
|
||||
return load_json_config
|
||||
|
||||
|
||||
def check(paths=None, debug=False):
|
||||
search_paths = paths or get_config_paths()
|
||||
find_config_file = generate_config_finder(lambda: search_paths)
|
||||
find_config_files = generate_config_finder(lambda: search_paths)
|
||||
|
||||
logger = logging.getLogger('powerline-lint')
|
||||
logger.setLevel(logging.DEBUG if debug else logging.ERROR)
|
||||
|
@ -1271,6 +1281,11 @@ def check(paths=None, debug=False):
|
|||
|
||||
ee = EchoErr(echoerr, logger)
|
||||
|
||||
lhadproblem = [False]
|
||||
load_json_config = generate_json_config_loader(lhadproblem)
|
||||
|
||||
config_loader = ConfigLoader(run_once=True, load=load_json_config)
|
||||
|
||||
paths = {
|
||||
'themes': defaultdict(lambda: []),
|
||||
'colorschemes': defaultdict(lambda: []),
|
||||
|
@ -1326,17 +1341,9 @@ def check(paths=None, debug=False):
|
|||
typ,
|
||||
))
|
||||
|
||||
lhadproblem = [False]
|
||||
|
||||
def load_config(stream):
|
||||
r, hadproblem = load(stream)
|
||||
if hadproblem:
|
||||
lhadproblem[0] = True
|
||||
return r
|
||||
|
||||
hadproblem = False
|
||||
try:
|
||||
main_config = load_json_config(find_config_file('config'), load=load_config, open_file=open_file)
|
||||
main_config = load_config('config', find_config_files, config_loader)
|
||||
except IOError:
|
||||
main_config = {}
|
||||
sys.stderr.write('\nConfiguration file not found: config.json\n')
|
||||
|
@ -1357,7 +1364,7 @@ def check(paths=None, debug=False):
|
|||
import_paths = [os.path.expanduser(path) for path in main_config.get('common', {}).get('paths', [])]
|
||||
|
||||
try:
|
||||
colors_config = load_json_config(find_config_file('colors'), load=load_config, open_file=open_file)
|
||||
colors_config = load_config('colors', find_config_files, config_loader)
|
||||
except IOError:
|
||||
colors_config = {}
|
||||
sys.stderr.write('\nConfiguration file not found: colors.json\n')
|
||||
|
|
|
@ -117,7 +117,7 @@ class TestPowerline(Powerline):
|
|||
return self.cr_kwargs
|
||||
|
||||
|
||||
renderer = SimpleRenderer
|
||||
renderer = EvenSimplerRenderer
|
||||
|
||||
|
||||
def get_powerline(**kwargs):
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
# vim:fileencoding=utf-8:noet
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from powerline import Powerline
|
||||
from tests import TestCase
|
||||
from shutil import rmtree
|
||||
import os
|
||||
import json
|
||||
from powerline.lib import mergedicts_copy as mdc
|
||||
|
||||
|
||||
CONFIG_DIR = 'tests/config'
|
||||
|
||||
|
||||
root_config = lambda: {
|
||||
'common': {
|
||||
'dividers': {
|
||||
'left': {
|
||||
'hard': '#>',
|
||||
'soft': '|>',
|
||||
},
|
||||
'right': {
|
||||
'hard': '<#',
|
||||
'soft': '<|',
|
||||
},
|
||||
},
|
||||
'spaces': 0,
|
||||
'interval': 0,
|
||||
'watcher': 'test',
|
||||
},
|
||||
'ext': {
|
||||
'test': {
|
||||
'theme': 'default',
|
||||
'colorscheme': 'default',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
colors_config = lambda: {
|
||||
'colors': {
|
||||
'c1': 1,
|
||||
'c2': 2,
|
||||
},
|
||||
'gradients': {
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
colorscheme_config = lambda: {
|
||||
'groups': {
|
||||
'g': {'fg': 'c1', 'bg': 'c2', 'attr': []},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
theme_config = lambda: {
|
||||
'segment_data': {
|
||||
's': {
|
||||
'before': 'b',
|
||||
},
|
||||
},
|
||||
'segments': {
|
||||
'left': [
|
||||
{
|
||||
'type': 'string',
|
||||
'name': 's',
|
||||
'contents': 't',
|
||||
'highlight_group': ['g'],
|
||||
},
|
||||
],
|
||||
'right': [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
main_tree = lambda: {
|
||||
'1/config': root_config(),
|
||||
'1/colors': colors_config(),
|
||||
'1/colorschemes/default': colorscheme_config(),
|
||||
'1/themes/test/default': theme_config(),
|
||||
}
|
||||
|
||||
|
||||
def mkdir_recursive(directory):
|
||||
if os.path.isdir(directory):
|
||||
return
|
||||
mkdir_recursive(os.path.dirname(directory))
|
||||
os.mkdir(directory)
|
||||
|
||||
|
||||
class TestPowerline(Powerline):
|
||||
def get_config_paths(self):
|
||||
return tuple(sorted([
|
||||
os.path.join(CONFIG_DIR, d)
|
||||
for d in os.listdir(CONFIG_DIR)
|
||||
]))
|
||||
|
||||
|
||||
class WithConfigTree(object):
|
||||
__slots__ = ('tree', 'p', 'p_kwargs')
|
||||
|
||||
def __init__(self, tree, p_kwargs={'run_once': True}):
|
||||
self.tree = tree
|
||||
self.p = None
|
||||
self.p_kwargs = p_kwargs
|
||||
|
||||
def __enter__(self, *args):
|
||||
os.mkdir(CONFIG_DIR)
|
||||
for k, v in self.tree.items():
|
||||
fname = os.path.join(CONFIG_DIR, k) + '.json'
|
||||
mkdir_recursive(os.path.dirname(fname))
|
||||
with open(fname, 'w') as F:
|
||||
json.dump(v, F)
|
||||
self.p = TestPowerline(
|
||||
ext='test',
|
||||
renderer_module='tests.lib.config_mock',
|
||||
**self.p_kwargs
|
||||
)
|
||||
return self.p.__enter__(*args)
|
||||
|
||||
def __exit__(self, *args):
|
||||
try:
|
||||
rmtree(CONFIG_DIR)
|
||||
finally:
|
||||
if self.p:
|
||||
self.p.__exit__(*args)
|
||||
|
||||
|
||||
class TestMerging(TestCase):
|
||||
def assertRenderEqual(self, p, output, **kwargs):
|
||||
self.assertEqual(p.render(**kwargs).replace(' ', ' '), output)
|
||||
|
||||
def test_not_merged_config(self):
|
||||
with WithConfigTree(main_tree()) as p:
|
||||
self.assertRenderEqual(p, '{12} bt{2-}#>{--}')
|
||||
|
||||
def test_root_config_merging(self):
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/config': {
|
||||
'common': {
|
||||
'dividers': {
|
||||
'left': {
|
||||
'hard': '!>',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{12} bt{2-}!>{--}')
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/config': {
|
||||
'common': {
|
||||
'dividers': {
|
||||
'left': {
|
||||
'hard': '!>',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'3/config': {
|
||||
'common': {
|
||||
'dividers': {
|
||||
'left': {
|
||||
'hard': '>>',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{12} bt{2-}>>{--}')
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/config': {
|
||||
'common': {
|
||||
'spaces': 3,
|
||||
}
|
||||
},
|
||||
'3/config': {
|
||||
'common': {
|
||||
'dividers': {
|
||||
'left': {
|
||||
'hard': '>>',
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{12} bt {2-}>>{--}')
|
||||
|
||||
def test_colors_config_merging(self):
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/colors': {
|
||||
'colors': {
|
||||
'c1': 3,
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{32} bt{2-}#>{--}')
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/colors': {
|
||||
'colors': {
|
||||
'c1': 3,
|
||||
}
|
||||
},
|
||||
'3/colors': {
|
||||
'colors': {
|
||||
'c1': 4,
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{42} bt{2-}#>{--}')
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/colors': {
|
||||
'colors': {
|
||||
'c1': 3,
|
||||
}
|
||||
},
|
||||
'3/colors': {
|
||||
'colors': {
|
||||
'c2': 4,
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{34} bt{4-}#>{--}')
|
||||
|
||||
def test_colorschemes_merging(self):
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/colorschemes/default': {
|
||||
'groups': {
|
||||
'g': {'fg': 'c2', 'bg': 'c1', 'attr': []},
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{21} bt{1-}#>{--}')
|
||||
|
||||
def test_theme_merging(self):
|
||||
with WithConfigTree(mdc(main_tree(), {
|
||||
'2/themes/test/default': {
|
||||
'segment_data': {
|
||||
's': {
|
||||
'after': 'a',
|
||||
}
|
||||
}
|
||||
},
|
||||
})) as p:
|
||||
self.assertRenderEqual(p, '{12} bta{2-}#>{--}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from tests import main
|
||||
main()
|
Loading…
Reference in New Issue