From 46d0fee11bb32c2aad27eef0886c01752ee11a8f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 16 Jun 2017 14:31:56 +0200 Subject: [PATCH] Bring back :set --- qutebrowser/config/config.py | 131 -------------------------------- qutebrowser/config/newconfig.py | 112 ++++++++++++++++++++++++--- 2 files changed, 103 insertions(+), 140 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 277cca55d..f7a8c9f7b 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -669,137 +669,6 @@ class ConfigManager(QObject): self.get.cache_clear() return existed - @functools.lru_cache() - def get(self, sectname, optname, raw=False, transformed=True, - fallback=UNSET): - """Get the value from a section/option. - - We don't support the vars argument from configparser.get as it's not - hashable. - - Args: - sectname: The section to get the option from. - optname: The option name - raw: Whether to get the uninterpolated, untransformed value. - transformed: Whether the value should be transformed. - - Return: - The value of the option. - """ - if not self._initialized: - raise Exception("get got called before initialization was " - "complete!") - - try: - sect = self.sections[sectname] - except KeyError: - if fallback is not UNSET: - return fallback - raise configexc.NoSectionError(sectname) - try: - val = sect[optname] - except KeyError: - if fallback is not UNSET: - return fallback - raise configexc.NoOptionError(optname, sectname) - if raw: - return val.value() - mapping = {key: val.value() for key, val in sect.values.items()} - newval = self._interpolation.before_get(self, sectname, optname, - val.value(), mapping) - if transformed: - newval = val.typ.transform(newval) - return newval - - @contextlib.contextmanager - def _handle_config_error(self): - """Catch errors in set_command and raise CommandError.""" - try: - yield - except (configexc.NoOptionError, configexc.NoSectionError, - configexc.ValidationError) as e: - raise cmdexc.CommandError("set: {}".format(e)) - except (configexc.Error, configparser.Error) as e: - raise cmdexc.CommandError("set: {} - {}".format( - e.__class__.__name__, e)) - - @cmdutils.register(name='set', instance='config', star_args_optional=True) - @cmdutils.argument('win_id', win_id=True) - def set_command(self, win_id, section_=None, option=None, *values, - temp=False, print_=False): - """Set an option. - - If the option name ends with '?', the value of the option is shown - instead. - - If the option name ends with '!' and it is a boolean value, toggle it. - - // - - Wrapper for self.set() to output exceptions in the status bar. - - Args: - section_: The section where the option is in. - option: The name of the option. - values: The value to set, or the values to cycle through. - temp: Set value temporarily. - print_: Print the value after setting. - """ - if section_ is not None and option is None: - raise cmdexc.CommandError( - "set: Either both section and option have to be given, or " - "neither!") - if section_ is None and option is None: - tabbed_browser = objreg.get('tabbed-browser', scope='window', - window=win_id) - tabbed_browser.openurl(QUrl('qute://settings'), newtab=False) - return - - if option.endswith('?') and option != '?': - option = option[:-1] - print_ = True - else: - with self._handle_config_error(): - if option.endswith('!') and option != '!' and not values: - # Handle inversion as special cases of the cycle code path - option = option[:-1] - val = self.get(section_, option) - if isinstance(val, bool): - values = ['false', 'true'] - else: - raise cmdexc.CommandError( - "set: Attempted inversion of non-boolean value.") - elif not values: - raise cmdexc.CommandError("set: The following arguments " - "are required: value") - - layer = 'temp' if temp else 'conf' - self._set_next(layer, section_, option, values) - - if print_: - with self._handle_config_error(): - val = self.get(section_, option, transformed=False) - message.info("{} {} = {}".format(section_, option, val)) - - def _set_next(self, layer, section_, option, values): - """Set the next value out of a list of values.""" - if len(values) == 1: - # If we have only one value, just set it directly (avoid - # breaking stuff like aliases or other pseudo-settings) - self.set(layer, section_, option, values[0]) - else: - # Otherwise, use the next valid value from values, or the - # first if the current value does not appear in the list - assert len(values) > 1 - val = self.get(section_, option, transformed=False) - try: - idx = values.index(str(val)) - idx = (idx + 1) % len(values) - value = values[idx] - except ValueError: - value = values[0] - self.set(layer, section_, option, value) - def set(self, layer, sectname, optname, value, validate=True): """Set an option. diff --git a/qutebrowser/config/newconfig.py b/qutebrowser/config/newconfig.py index 31f78ad67..97c1c98a4 100644 --- a/qutebrowser/config/newconfig.py +++ b/qutebrowser/config/newconfig.py @@ -19,12 +19,14 @@ """New qutebrowser configuration code.""" +import contextlib import functools -from PyQt5.QtCore import pyqtSignal, QObject +from PyQt5.QtCore import pyqtSignal, QObject, QUrl -from qutebrowser.config import configdata, configexc -from qutebrowser.utils import utils, objreg +from qutebrowser.config import configdata, configexc, configtypes +from qutebrowser.utils import utils, objreg, message +from qutebrowser.commands import cmdexc, cmdutils # An easy way to access the config from other code via config.val.foo val = None @@ -130,6 +132,95 @@ class NewKeyConfig: return cmd_to_keys +class ConfigCommands: + + def __init__(self, config): + self._config = config + + @cmdutils.register(instance='config-commands', star_args_optional=True) + @cmdutils.argument('win_id', win_id=True) + def set(self, win_id, option=None, *values, temp=False, print_=False): + """Set an option. + + If the option name ends with '?', the value of the option is shown + instead. + + If the option name ends with '!' and it is a boolean value, toggle it. + + // + + Args: + option: The name of the option. + values: The value to set, or the values to cycle through. + temp: Set value temporarily. + print_: Print the value after setting. + """ + # FIXME:conf write to YAML if temp isn't used! + if option is None: + tabbed_browser = objreg.get('tabbed-browser', scope='window', + window=win_id) + tabbed_browser.openurl(QUrl('qute://settings'), newtab=False) + return + + if option.endswith('?') and option != '?': + self._print_value(option[:-1]) + return + + with self._handle_config_error(): + if option.endswith('!') and option != '!' and not values: + # Handle inversion as special cases of the cycle code path + option = option[:-1] + opt = self._config.get_opt(option) + if opt.typ is configtypes.Bool: + values = ['false', 'true'] + else: + raise cmdexc.CommandError( + "set: Attempted inversion of non-boolean value.") + elif not values: + raise cmdexc.CommandError("set: The following arguments " + "are required: value") + self._set_next(option, values) + + if print_: + self._print_value(option) + + def _print_value(self, option): + """Print the value of the given option.""" + with self._handle_config_error(): + val = self._config.get_str(option) + message.info("{} = {}".format(option, val)) + + def _set_next(self, option, values): + """Set the next value out of a list of values.""" + if len(values) == 1: + # If we have only one value, just set it directly (avoid + # breaking stuff like aliases or other pseudo-settings) + self._config.set(option, values[0]) + return + + # Use the next valid value from values, or the first if the current + # value does not appear in the list + val = self._config.get_str(option) + try: + idx = values.index(str(val)) + idx = (idx + 1) % len(values) + value = values[idx] + except ValueError: + value = values[0] + self._config.set(option, value) + + @contextlib.contextmanager + def _handle_config_error(self): + """Catch errors in set_command and raise CommandError.""" + try: + yield + except (configexc.NoOptionError, configexc.ValidationError) as e: + raise cmdexc.CommandError("set: {}".format(e)) + except configexc.Error as e: + raise cmdexc.CommandError("set: {} - {}".format( + e.__class__.__name__, e)) + + class NewConfigManager(QObject): changed = pyqtSignal(str) # FIXME:conf stub... @@ -143,19 +234,19 @@ class NewConfigManager(QObject): for name, option in configdata.DATA.items(): self.options[name] = option - def get(self, name): + def get_opt(self, name): try: - opt = self.options[name] + return self.options[name] except KeyError: raise configexc.NoOptionError(name) + + def get(self, name): + opt = self.get_opt(name) value = self._values.get(name, opt.default) return opt.typ.to_py(value) def get_str(self, name): - try: - opt = self.options[name] - except KeyError: - raise configexc.NoOptionError(name) + opt = self.get_opt(name) return opt.typ.to_str(opt.default) def set(self, name, value): @@ -220,6 +311,9 @@ def init(parent): new_config.read_defaults() objreg.register('config', new_config) + config_commands = ConfigCommands(new_config) + objreg.register('config-commands', config_commands) + global val, instance, key_instance val = ConfigContainer(new_config) instance = new_config