Coverage for qutebrowser/config/config.py : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org> # # This file is part of qutebrowser. # # qutebrowser is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # qutebrowser is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# An easy way to access the config from other code via config.val.foo
# Keeping track of all change filters to validate them later.
"""Decorator to filter calls based on a config section/option matching.
This could also be a function, but as a class (with a "wrong" name) it's much cleaner to implement.
Attributes: _option: An option or prefix to be filtered _function: Whether a function rather than a method is decorated. """
"""Save decorator arguments.
Gets called on parse-time with the decorator arguments.
Args: option: The option to be filtered. function: Whether a function rather than a method is decorated. """
"""Make sure the configured option or prefix exists.
We can't do this in __init__ as configdata isn't ready yet. """ not configdata.is_valid_prefix(self._option)):
"""Check if the given option matches the filter.""" # Called directly, not from a config change event. # prefix match else:
"""Filter calls to the decorated function.
Gets called when a function should be decorated.
Adds a filter which returns if we're not interested in the change-event and calls the wrapped function if we are.
We assume the function passed doesn't take any parameters.
Args: func: The function to be decorated.
Return: The decorated function. """ """Call the underlying function.""" else: """Call the underlying function."""
"""Utilities related to keybindings.
Note that the actual values are saved in the config itself, not here.
Attributes: _config: The Config object to be used. """
"""Make sure the given mode exists and normalize the key.""" # <Ctrl-t>, <ctrl-T>, and <ctrl-t> should be considered equivalent
"""Get the combined bindings for the given mode.""" else:
"""Get a dict of commands to a list of bindings for the mode.""" # put special bindings last else:
"""Get the command for a given key (or None).""" else:
"""Add a new binding from key to command.""" "Can't add binding '{}' with empty command in {} " 'mode'.format(key, mode))
key, command, mode))
"""Restore a default keybinding."""
"Can't find binding '{}' in {} mode".format(key, mode))
"""Unbind the given key in the given mode."""
# In custom bindings -> remove it # In default bindings -> shadow it with None else: "Can't find binding '{}' in {} mode".format(key, mode))
"""Main config object.
Attributes: _values: A dict mapping setting names to their values. _mutables: A dictionary of mutable objects to be checked for changes. _yaml: A YamlConfig object or None.
Signals: changed: Emitted with the option name when an option changed. """
"""Iterate over Option, value tuples."""
"""Make sure the config gets saved properly.
We do this outside of __init__ because the config gets created before the save_manager exists. """
"""Set the given option to the given value."""
opt.name, value))
"""Read the YAML settings from self._yaml."""
"""Get a configdata.Option object for the given setting.""" name, deleted=deleted, renamed=renamed)
"""Get the given setting converted for Python code."""
"""Get the given setting as object (for YAML/config.py).
If mutable=True is set, watch the returned object for mutations. """ # If we allow mutation, there is a chance that prior mutations already # entered the mutable dictionary and thus further copies are unneeded # until update_mutables() is called # Otherwise, we return a copy of the value stored internally, so the # internal value can never be changed by mutating the object returned. else: # Then we watch the returned object for changes. else: # Shouldn't be mutable (and thus hashable)
"""Get the given setting as string."""
"""Set the given setting from a YAML/config.py object.
If save_yaml=True is given, store the new value to YAML. """
"""Set the given setting from a string.
If save_yaml=True is given, store the new value to YAML. """ .format(name, opt.typ.__class__.__name__, converted, value))
"""Set the given setting back to its default."""
"""Clear all settings in the config.
If save_yaml=True is given, also remove all customization from the YAML file. """
"""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. """
"""Get the part of the config which was changed by the user.
Return: The changed config part as string. """
"""An object implementing config access via __getattr__.
Attributes: _config: The Config object. _prefix: The __getattr__ chain leading up to this object. _configapi: If given, get values suitable for config.py and add errors to the given ConfigAPI object. """
def __repr__(self): return utils.get_repr(self, constructor=True, config=self._config, configapi=self._configapi, prefix=self._prefix)
def _handle_error(self, action, name):
"""Get an option or a new ConfigContainer with the added prefix.
If we get an option which exists, we return the value for it. If we get a part of an option name, we return a new ConfigContainer.
Those two never overlap as configdata.py ensures there are no shadowing options. """
configapi=self._configapi, prefix=name)
# access from Python code else: # access from config.py
"""Set the given option in the config."""
"""Get the prefix joined with the given attribute.""" else:
"""Set the stylesheet for an object based on it's STYLESHEET attribute.
Also, register an update when the config is changed.
Args: obj: The object to set the stylesheet for and register. Must have a STYLESHEET attribute if stylesheet is not given. stylesheet: The stylesheet to use. update: Whether to update the stylesheet on config changes. """
def _render_stylesheet(stylesheet): """Render the given stylesheet jinja template."""
"""Set the stylesheet on the given object and update it on changes.
Attributes: _obj: The object to observe. _stylesheet: The stylesheet template to use. """
# We only need to hang around if we are asked to update. else:
"""Format a stylesheet based on a template.
Return: The formatted template as string. """
def _update_stylesheet(self): """Update the stylesheet for obj."""
"""Do a first update and listen for more.
Args: update: if False, don't listen for future updates. """ self._obj.__class__.__name__, qss)) |