Clean up code
This commit is contained in:
parent
67cb6a9802
commit
0ed0a6db57
@ -118,10 +118,18 @@ class change_filter: # pylint: disable=invalid-name
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class NewKeyConfig:
|
class KeyConfig:
|
||||||
|
|
||||||
def __init__(self, manager):
|
"""Utilities related to keybindings.
|
||||||
self._manager = manager
|
|
||||||
|
Note that the actual values are saved in the config itself, not here.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
_config: The Config object to be used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self._config = config
|
||||||
|
|
||||||
def get_reverse_bindings_for(self, mode):
|
def get_reverse_bindings_for(self, mode):
|
||||||
"""Get a dict of commands to a list of bindings for the mode."""
|
"""Get a dict of commands to a list of bindings for the mode."""
|
||||||
@ -172,7 +180,7 @@ class NewKeyConfig:
|
|||||||
if key in bindings and not force:
|
if key in bindings and not force:
|
||||||
raise configexc.DuplicateKeyError(key)
|
raise configexc.DuplicateKeyError(key)
|
||||||
bindings[key] = command
|
bindings[key] = command
|
||||||
self._manager.update_mutables(save_yaml=save_yaml)
|
self._config.update_mutables(save_yaml=save_yaml)
|
||||||
|
|
||||||
def unbind(self, key, *, mode='normal', save_yaml=False):
|
def unbind(self, key, *, mode='normal', save_yaml=False):
|
||||||
"""Unbind the given key in the given mode."""
|
"""Unbind the given key in the given mode."""
|
||||||
@ -183,7 +191,7 @@ class NewKeyConfig:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise configexc.KeybindingError("Can't find binding '{}' in section '{}'!"
|
raise configexc.KeybindingError("Can't find binding '{}' in section '{}'!"
|
||||||
.format(key, mode))
|
.format(key, mode))
|
||||||
self._manager.update_mutables(save_yaml=save_yaml)
|
self._config.update_mutables(save_yaml=save_yaml)
|
||||||
|
|
||||||
def get_command(self, key, mode):
|
def get_command(self, key, mode):
|
||||||
"""Get the command for a given key (or None)."""
|
"""Get the command for a given key (or None)."""
|
||||||
@ -193,6 +201,8 @@ class NewKeyConfig:
|
|||||||
|
|
||||||
class ConfigCommands:
|
class ConfigCommands:
|
||||||
|
|
||||||
|
"""qutebrowser commands related to the configuration."""
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self._config = config
|
self._config = config
|
||||||
|
|
||||||
@ -330,7 +340,20 @@ class ConfigCommands:
|
|||||||
raise cmdexc.CommandError(str(e))
|
raise cmdexc.CommandError(str(e))
|
||||||
|
|
||||||
|
|
||||||
class NewConfigManager(QObject):
|
class Config(QObject):
|
||||||
|
|
||||||
|
"""Main config object.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
options: A dict mapping setting names to configdata.Option objects.
|
||||||
|
Those contain the type, default value, etc.
|
||||||
|
_values: A dict mapping setting names to their values.
|
||||||
|
_mutables: A list of mutable objects to be checked for changes.
|
||||||
|
_yaml: A YamlConfig object.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
changed: Emitted with the option name when an option changed.
|
||||||
|
"""
|
||||||
|
|
||||||
changed = pyqtSignal(str)
|
changed = pyqtSignal(str)
|
||||||
|
|
||||||
@ -342,14 +365,17 @@ class NewConfigManager(QObject):
|
|||||||
self._yaml = configfiles.YamlConfig()
|
self._yaml = configfiles.YamlConfig()
|
||||||
|
|
||||||
def _changed(self, name, value):
|
def _changed(self, name, value):
|
||||||
|
"""Emit changed signal and log change."""
|
||||||
self.changed.emit(name)
|
self.changed.emit(name)
|
||||||
log.config.debug("Config option changed: {} = {}".format(name, value))
|
log.config.debug("Config option changed: {} = {}".format(name, value))
|
||||||
|
|
||||||
def read_defaults(self):
|
def read_configdata(self):
|
||||||
|
"""Read the option objects from configdata."""
|
||||||
for name, option in configdata.DATA.items():
|
for name, option in configdata.DATA.items():
|
||||||
self.options[name] = option
|
self.options[name] = option
|
||||||
|
|
||||||
def read_yaml(self):
|
def read_yaml(self):
|
||||||
|
"""Read the YAML settings from self._yaml."""
|
||||||
self._yaml.load()
|
self._yaml.load()
|
||||||
for name, value in self._yaml.values.items():
|
for name, value in self._yaml.values.items():
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
@ -357,17 +383,23 @@ class NewConfigManager(QObject):
|
|||||||
self._values[name] = value
|
self._values[name] = value
|
||||||
|
|
||||||
def get_opt(self, name):
|
def get_opt(self, name):
|
||||||
|
"""Get a configdata.Option object for the given setting."""
|
||||||
try:
|
try:
|
||||||
return self.options[name]
|
return self.options[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise configexc.NoOptionError(name)
|
raise configexc.NoOptionError(name)
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
|
"""Get the given setting converted for Python code."""
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
obj = self.get_obj(name, mutable=False)
|
obj = self.get_obj(name, mutable=False)
|
||||||
return opt.typ.to_py(obj)
|
return opt.typ.to_py(obj)
|
||||||
|
|
||||||
def get_obj(self, name, *, mutable=True):
|
def get_obj(self, name, *, mutable=True):
|
||||||
|
"""Get the given setting as object (for YAML/config.py).
|
||||||
|
|
||||||
|
If mutable=True is set, watch the returned object for mutations.
|
||||||
|
"""
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
obj = self._values.get(name, opt.default)
|
obj = self._values.get(name, opt.default)
|
||||||
if isinstance(obj, (dict, list)):
|
if isinstance(obj, (dict, list)):
|
||||||
@ -379,11 +411,16 @@ class NewConfigManager(QObject):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
def get_str(self, name):
|
def get_str(self, name):
|
||||||
|
"""Get the given setting as string."""
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
value = self._values.get(name, opt.default)
|
value = self._values.get(name, opt.default)
|
||||||
return opt.typ.to_str(value)
|
return opt.typ.to_str(value)
|
||||||
|
|
||||||
def set_obj(self, name, value, *, save_yaml=False):
|
def set_obj(self, name, value, *, save_yaml=False):
|
||||||
|
"""Set the given setting from a YAML/config.py object.
|
||||||
|
|
||||||
|
If save_yaml=True is given, store the new value to YAML.
|
||||||
|
"""
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
opt.typ.to_py(value) # for validation
|
opt.typ.to_py(value) # for validation
|
||||||
self._values[name] = value
|
self._values[name] = value
|
||||||
@ -392,6 +429,10 @@ class NewConfigManager(QObject):
|
|||||||
self._yaml.values[name] = value
|
self._yaml.values[name] = value
|
||||||
|
|
||||||
def set_str(self, name, value, *, save_yaml=False):
|
def set_str(self, name, value, *, save_yaml=False):
|
||||||
|
"""Set the given setting from a string.
|
||||||
|
|
||||||
|
If save_yaml=True is given, store the new value to YAML.
|
||||||
|
"""
|
||||||
opt = self.get_opt(name)
|
opt = self.get_opt(name)
|
||||||
converted = opt.typ.from_str(value)
|
converted = opt.typ.from_str(value)
|
||||||
self._values[name] = converted
|
self._values[name] = converted
|
||||||
@ -400,6 +441,14 @@ class NewConfigManager(QObject):
|
|||||||
self._yaml.values[name] = converted
|
self._yaml.values[name] = converted
|
||||||
|
|
||||||
def update_mutables(self, *, save_yaml=False):
|
def update_mutables(self, *, save_yaml=False):
|
||||||
|
"""Update mutable settings if they changed.
|
||||||
|
|
||||||
|
Every time someone calls get_obj() on a mutable object, we save a
|
||||||
|
reference to the original object and a copy.
|
||||||
|
|
||||||
|
Here, we check all those saved copies for mutations, and if something
|
||||||
|
mutated, we call set_obj again so we save the new value.
|
||||||
|
"""
|
||||||
for name, old_value, new_value in self._mutables:
|
for name, old_value, new_value in self._mutables:
|
||||||
if old_value != new_value:
|
if old_value != new_value:
|
||||||
log.config.debug("{} was mutated, updating".format(name))
|
log.config.debug("{} was mutated, updating".format(name))
|
||||||
@ -424,16 +473,16 @@ class ConfigContainer:
|
|||||||
"""An object implementing config access via __getattr__.
|
"""An object implementing config access via __getattr__.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_manager: The ConfigManager object.
|
_config: The Config object.
|
||||||
_prefix: The __getattr__ chain leading up to this object.
|
_prefix: The __getattr__ chain leading up to this object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, manager, prefix=''):
|
def __init__(self, config, prefix=''):
|
||||||
self._manager = manager
|
self._config = config
|
||||||
self._prefix = prefix
|
self._prefix = prefix
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return utils.get_repr(self, constructor=True, manager=self._manager,
|
return utils.get_repr(self, constructor=True, config=self._config,
|
||||||
prefix=self._prefix)
|
prefix=self._prefix)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
@ -450,20 +499,22 @@ class ConfigContainer:
|
|||||||
|
|
||||||
name = self._join(attr)
|
name = self._join(attr)
|
||||||
if configdata.is_valid_prefix(name):
|
if configdata.is_valid_prefix(name):
|
||||||
return ConfigContainer(manager=self._manager, prefix=name)
|
return ConfigContainer(config=self._config, prefix=name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self._manager.get(name)
|
return self._config.get(name)
|
||||||
except configexc.NoOptionError as e:
|
except configexc.NoOptionError as e:
|
||||||
# If it's not a valid prefix - re-raise to improve error text.
|
# If it's not a valid prefix - re-raise to improve error text.
|
||||||
raise configexc.NoOptionError(name)
|
raise configexc.NoOptionError(name)
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
def __setattr__(self, attr, value):
|
||||||
|
"""Set the given option in the config."""
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_'):
|
||||||
return super().__setattr__(attr, value)
|
return super().__setattr__(attr, value)
|
||||||
self._manager.set_obj(self._join(attr), value)
|
self._config.set_obj(self._join(attr), value)
|
||||||
|
|
||||||
def _join(self, attr):
|
def _join(self, attr):
|
||||||
|
"""Get the prefix joined with the given attribute."""
|
||||||
if self._prefix:
|
if self._prefix:
|
||||||
return '{}.{}'.format(self._prefix, attr)
|
return '{}.{}'.format(self._prefix, attr)
|
||||||
else:
|
else:
|
||||||
@ -478,18 +529,18 @@ def init(parent=None):
|
|||||||
"""
|
"""
|
||||||
configdata.init()
|
configdata.init()
|
||||||
|
|
||||||
new_config = NewConfigManager(parent)
|
config = Config(parent)
|
||||||
new_config.read_defaults()
|
config.read_configdata()
|
||||||
new_config.read_yaml()
|
config.read_yaml()
|
||||||
objreg.register('config', new_config)
|
objreg.register('config', config)
|
||||||
|
|
||||||
config_commands = ConfigCommands(new_config)
|
config_commands = ConfigCommands(config)
|
||||||
objreg.register('config-commands', config_commands)
|
objreg.register('config-commands', config_commands)
|
||||||
|
|
||||||
global val, instance, key_instance
|
global val, instance, key_instance
|
||||||
val = ConfigContainer(new_config)
|
val = ConfigContainer(config)
|
||||||
instance = new_config
|
instance = config
|
||||||
key_instance = NewKeyConfig(new_config)
|
key_instance = KeyConfig(config)
|
||||||
|
|
||||||
for cf in _change_filters:
|
for cf in _change_filters:
|
||||||
cf.validate()
|
cf.validate()
|
||||||
|
Loading…
Reference in New Issue
Block a user