Add an "include" directive for the config files to read multiple config files.
This commit is contained in:
parent
530fd61125
commit
1c78633d1a
@ -2,11 +2,12 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from .utils import log_error
|
|
||||||
from .rgb import to_color as as_color
|
from .rgb import to_color as as_color
|
||||||
|
from .utils import log_error
|
||||||
|
|
||||||
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
||||||
|
|
||||||
@ -31,33 +32,57 @@ def to_bool(x):
|
|||||||
return x.lower() in 'y yes true'.split()
|
return x.lower() in 'y yes true'.split()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_line(line, type_map, special_handling, ans, all_keys, base_path_for_includes):
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith('#'):
|
||||||
|
return
|
||||||
|
m = key_pat.match(line)
|
||||||
|
if m is not None:
|
||||||
|
key, val = m.groups()
|
||||||
|
if special_handling(key, val, ans):
|
||||||
|
return
|
||||||
|
if key == 'include':
|
||||||
|
val = val.strip()
|
||||||
|
if not os.path.isabs(val):
|
||||||
|
val = os.path.join(base_path_for_includes, val)
|
||||||
|
try:
|
||||||
|
with open(val, encoding='utf-8', errors='replace') as include:
|
||||||
|
_parse(include, type_map, special_handling, ans, all_keys)
|
||||||
|
except FileNotFoundError:
|
||||||
|
log_error('Could not find included config file: {}, ignoring'.format(val))
|
||||||
|
except EnvironmentError:
|
||||||
|
log_error('Could not read from included config file: {}, ignoring'.format(val))
|
||||||
|
return
|
||||||
|
if all_keys is not None and key not in all_keys:
|
||||||
|
log_error('Ignoring unknown config key: {}'.format(key))
|
||||||
|
return
|
||||||
|
tm = type_map.get(key)
|
||||||
|
if tm is not None:
|
||||||
|
val = tm(val)
|
||||||
|
ans[key] = val
|
||||||
|
|
||||||
|
|
||||||
|
def _parse(lines, type_map, special_handling, ans, all_keys):
|
||||||
|
name = getattr(lines, 'name', None)
|
||||||
|
if name:
|
||||||
|
base_path_for_includes = os.path.dirname(os.path.abspath(name))
|
||||||
|
else:
|
||||||
|
from .constants import config_dir
|
||||||
|
base_path_for_includes = config_dir
|
||||||
|
for line in lines:
|
||||||
|
parse_line(line, type_map, special_handling, ans, all_keys, base_path_for_includes)
|
||||||
|
|
||||||
|
|
||||||
def parse_config_base(
|
def parse_config_base(
|
||||||
lines, defaults, type_map, special_handling, ans, check_keys=True
|
lines, defaults, type_map, special_handling, ans, check_keys=True
|
||||||
):
|
):
|
||||||
if check_keys:
|
all_keys = defaults._asdict() if check_keys else None
|
||||||
all_keys = defaults._asdict()
|
_parse(lines, type_map, special_handling, ans, all_keys)
|
||||||
for line in lines:
|
|
||||||
line = line.strip()
|
|
||||||
if not line or line.startswith('#'):
|
|
||||||
continue
|
|
||||||
m = key_pat.match(line)
|
|
||||||
if m is not None:
|
|
||||||
key, val = m.groups()
|
|
||||||
if special_handling(key, val, ans):
|
|
||||||
continue
|
|
||||||
if check_keys:
|
|
||||||
if key not in all_keys:
|
|
||||||
log_error('Ignoring unknown config key: {}'.format(key))
|
|
||||||
continue
|
|
||||||
tm = type_map.get(key)
|
|
||||||
if tm is not None:
|
|
||||||
val = tm(val)
|
|
||||||
ans[key] = val
|
|
||||||
|
|
||||||
|
|
||||||
def init_config(defaults_path, parse_config):
|
def init_config(defaults_path, parse_config):
|
||||||
with open(defaults_path, encoding='utf-8', errors='replace') as f:
|
with open(defaults_path, encoding='utf-8', errors='replace') as f:
|
||||||
defaults = parse_config(f.read().splitlines(), check_keys=False)
|
defaults = parse_config(f, check_keys=False)
|
||||||
Options = namedtuple('Defaults', ','.join(defaults.keys()))
|
Options = namedtuple('Defaults', ','.join(defaults.keys()))
|
||||||
defaults = Options(**defaults)
|
defaults = Options(**defaults)
|
||||||
return Options, defaults
|
return Options, defaults
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
# vim:fileencoding=utf-8:ft=conf
|
# vim:fileencoding=utf-8:ft=conf
|
||||||
|
|
||||||
|
# You can include secondary config files via the "include" directive.
|
||||||
|
# If you use a relative path for include, it is resolved with respect to the
|
||||||
|
# location od the current config file. For example:
|
||||||
|
# include other.conf
|
||||||
|
|
||||||
# Fonts {{{
|
# Fonts {{{
|
||||||
# Font family. You can also specify different fonts for the
|
# Font family. You can also specify different fonts for the
|
||||||
# bold/italic/bold-italic variants. By default they are derived automatically,
|
# bold/italic/bold-italic variants. By default they are derived automatically,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user