From 788f469cc3e319d9722245d1e6b73130b432cf02 Mon Sep 17 00:00:00 2001 From: lufte Date: Tue, 30 Oct 2018 10:01:55 -0300 Subject: [PATCH] Make Config.dump_userconfig return the same as config-write-py --- qutebrowser/config/config.py | 16 ++--- qutebrowser/config/configcommands.py | 17 ++--- qutebrowser/config/configfiles.py | 101 --------------------------- qutebrowser/config/configutils.py | 100 ++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 120 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index facfcc55388..2c69ffa855e 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -461,15 +461,15 @@ def dump_userconfig(self): Return: The changed config part as string. """ - blocks = [] - for values in sorted(self, key=lambda v: v.opt.name): - if values: - blocks.append(str(values)) - - if not blocks: - return '' + options = [] + for values in self: + for scoped in values: + options.append((scoped.pattern, values.opt, scoped.value)) + bindings = dict(self.get_mutable_obj('bindings.commands')) + generator = configutils.ConfigPyGenerator(options, bindings, + commented=False) - return '\n'.join(blocks) + return generator.gen_text() class ConfigContainer: diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 8853f9ca382..64c819bef01 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -433,18 +433,13 @@ def config_write_py(self, filename=None, force=False, defaults=False): options = [(None, opt, opt.default) for _name, opt in sorted(configdata.DATA.items())] bindings = dict(configdata.DATA['bindings.default'].default) - commented = True + text = configutils.ConfigPyGenerator(options, bindings, + commented=True).gen_text() else: - options = [] - for values in self._config: - for scoped in values: - options.append((scoped.pattern, values.opt, scoped.value)) - bindings = dict(self._config.get_mutable_obj('bindings.commands')) - commented = False - - writer = configfiles.ConfigPyWriter(options, bindings, - commented=commented) + text = self._config.dump_userconfig() + try: - writer.write(filename) + with open(filename, 'w', encoding='utf-8') as f: + f.write(text) except OSError as e: raise cmdexc.CommandError(str(e)) diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index b4c8ea4ec78..ef2371ead18 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -426,107 +426,6 @@ def pattern(self, pattern): yield container -class ConfigPyWriter: - - """Writer for config.py files from given settings.""" - - def __init__(self, options, bindings, *, commented): - self._options = options - self._bindings = bindings - self._commented = commented - - def write(self, filename): - """Write the config to the given file.""" - with open(filename, 'w', encoding='utf-8') as f: - f.write('\n'.join(self._gen_lines())) - - def _line(self, line): - """Get an (optionally commented) line.""" - if self._commented: - if line.startswith('#'): - return '#' + line - else: - return '# ' + line - else: - return line - - def _gen_lines(self): - """Generate a config.py with the given settings/bindings. - - Yields individual lines. - """ - yield from self._gen_header() - yield from self._gen_options() - yield from self._gen_bindings() - - def _gen_header(self): - """Generate the initial header of the config.""" - yield self._line("# Autogenerated config.py") - yield self._line("# Documentation:") - yield self._line("# qute://help/configuring.html") - yield self._line("# qute://help/settings.html") - yield '' - if self._commented: - # When generated from an autoconfig.yml with commented=False, - # we don't want to load that autoconfig.yml anymore. - yield self._line("# This is here so configs done via the GUI are " - "still loaded.") - yield self._line("# Remove it to not load settings done via the " - "GUI.") - yield self._line("config.load_autoconfig()") - yield '' - else: - yield self._line("# Uncomment this to still load settings " - "configured via autoconfig.yml") - yield self._line("# config.load_autoconfig()") - yield '' - - def _gen_options(self): - """Generate the options part of the config.""" - for pattern, opt, value in self._options: - if opt.name in ['bindings.commands', 'bindings.default']: - continue - - for line in textwrap.wrap(opt.description): - yield self._line("# {}".format(line)) - - yield self._line("# Type: {}".format(opt.typ.get_name())) - - valid_values = opt.typ.get_valid_values() - if valid_values is not None and valid_values.generate_docs: - yield self._line("# Valid values:") - for val in valid_values: - try: - desc = valid_values.descriptions[val] - yield self._line("# - {}: {}".format(val, desc)) - except KeyError: - yield self._line("# - {}".format(val)) - - if pattern is None: - yield self._line('c.{} = {!r}'.format(opt.name, value)) - else: - yield self._line('config.set({!r}, {!r}, {!r})'.format( - opt.name, value, str(pattern))) - yield '' - - def _gen_bindings(self): - """Generate the bindings part of the config.""" - normal_bindings = self._bindings.pop('normal', {}) - if normal_bindings: - yield self._line('# Bindings for normal mode') - for key, command in sorted(normal_bindings.items()): - yield self._line('config.bind({!r}, {!r})'.format( - key, command)) - yield '' - - for mode, mode_bindings in sorted(self._bindings.items()): - yield self._line('# Bindings for {} mode'.format(mode)) - for key, command in sorted(mode_bindings.items()): - yield self._line('config.bind({!r}, {!r}, mode={!r})'.format( - key, command, mode)) - yield '' - - def read_config_py(filename, raising=False): """Read a config.py file. diff --git a/qutebrowser/config/configutils.py b/qutebrowser/config/configutils.py index 96fc0f02d57..75ac5d26582 100644 --- a/qutebrowser/config/configutils.py +++ b/qutebrowser/config/configutils.py @@ -22,6 +22,7 @@ import attr +import textwrap from qutebrowser.utils import utils from qutebrowser.config import configexc @@ -184,3 +185,102 @@ def get_for_pattern(self, pattern, *, fallback=True): return UNSET return self._get_fallback(fallback) + + +class ConfigPyGenerator: + + """Generator of config.py-like strings from given settings.""" + + def __init__(self, options, bindings, *, commented): + self._options = options + self._bindings = bindings + self._commented = commented + + def _line(self, line): + """Get an (optionally commented) line.""" + if self._commented: + if line.startswith('#'): + return '#' + line + else: + return '# ' + line + else: + return line + + def gen_text(self): + return '\n'.join(self._gen_lines()) + + def _gen_lines(self): + """Generate a config.py with the given settings/bindings. + + Yields individual lines. + """ + yield from self._gen_header() + yield from self._gen_options() + yield from self._gen_bindings() + + def _gen_header(self): + """Generate the initial header of the config.""" + yield self._line("# Autogenerated config.py") + yield self._line("# Documentation:") + yield self._line("# qute://help/configuring.html") + yield self._line("# qute://help/settings.html") + yield '' + if self._commented: + # When generated from an autoconfig.yml with commented=False, + # we don't want to load that autoconfig.yml anymore. + yield self._line("# This is here so configs done via the GUI are " + "still loaded.") + yield self._line("# Remove it to not load settings done via the " + "GUI.") + yield self._line("config.load_autoconfig()") + yield '' + else: + yield self._line("# Uncomment this to still load settings " + "configured via autoconfig.yml") + yield self._line("# config.load_autoconfig()") + yield '' + + def _gen_options(self): + """Generate the options part of the config.""" + for pattern, opt, value in self._options: + if opt.name in ['bindings.commands', 'bindings.default']: + continue + + for line in textwrap.wrap(opt.description): + yield self._line("# {}".format(line)) + + yield self._line("# Type: {}".format(opt.typ.get_name())) + + valid_values = opt.typ.get_valid_values() + if valid_values is not None and valid_values.generate_docs: + yield self._line("# Valid values:") + for val in valid_values: + try: + desc = valid_values.descriptions[val] + yield self._line("# - {}: {}".format(val, desc)) + except KeyError: + yield self._line("# - {}".format(val)) + + if pattern is None: + yield self._line('c.{} = {!r}'.format(opt.name, value)) + else: + yield self._line('config.set({!r}, {!r}, {!r})'.format( + opt.name, value, str(pattern))) + yield '' + + def _gen_bindings(self): + """Generate the bindings part of the config.""" + normal_bindings = self._bindings.pop('normal', {}) + if normal_bindings: + yield self._line('# Bindings for normal mode') + for key, command in sorted(normal_bindings.items()): + yield self._line('config.bind({!r}, {!r})'.format( + key, command)) + yield '' + + for mode, mode_bindings in sorted(self._bindings.items()): + yield self._line('# Bindings for {} mode'.format(mode)) + for key, command in sorted(mode_bindings.items()): + yield self._line('config.bind({!r}, {!r}, mode={!r})'.format( + key, command, mode)) + yield ''