From 7fc5e42ccae0b19ee41de90458c4d6f13ff92fc4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 4 Oct 2017 11:14:24 +0200 Subject: [PATCH] Initial :config-write-py implementation --- qutebrowser/config/config.py | 10 +++++++--- qutebrowser/config/configcommands.py | 30 +++++++++++++++++++++++++++- qutebrowser/config/configfiles.py | 22 ++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index d6dbd1e86..ffd0780d9 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -223,6 +223,11 @@ class Config(QObject): self._mutables = {} self._yaml = yaml_config + def __iter__(self): + """Iterate over Option, value tuples.""" + for name, value in sorted(self._values.items()): + yield (self.get_opt(name), value) + def init_save_manager(self, save_manager): """Make sure the config gets saved properly. @@ -365,10 +370,9 @@ class Config(QObject): The changed config part as string. """ lines = [] - for optname, value in sorted(self._values.items()): - opt = self.get_opt(optname) + for opt, value in self: str_value = opt.typ.to_str(value) - lines.append('{} = {}'.format(optname, str_value)) + lines.append('{} = {}'.format(opt.name, str_value)) if not lines: lines = [''] return '\n'.join(lines) diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 0eb93387e..5249ca778 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -27,7 +27,7 @@ from PyQt5.QtCore import QUrl from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.completion.models import configmodel from qutebrowser.utils import objreg, utils, message, standarddir -from qutebrowser.config import configtypes, configexc, configfiles +from qutebrowser.config import configtypes, configexc, configfiles, configdata from qutebrowser.misc import editor @@ -246,3 +246,31 @@ class ConfigCommands: filename = os.path.join(standarddir.config(), 'config.py') ed.edit_file(filename) + + @cmdutils.register(instance='config-commands') + def config_write_py(self, filename=None, force=False, defaults=False): + """Write the current configuration to a config.py file. + + Args: + filename: The file to write to, or None for the default config.py. + force: Force overwriting existing files. + defaults: Write the defaults instead of values configured via :set. + """ + if filename is None: + filename = os.path.join(standarddir.config(), 'config.py') + else: + filename = os.path.expanduser(filename) + + if os.path.exists(filename) and not force: + raise cmdexc.CommandError("{} already exists - use --force to " + "overwrite!".format(filename)) + + if defaults: + options = [(opt, opt.default) + for _name, opt in sorted(configdata.DATA.items())] + bindings = dict(configdata.DATA['bindings.default'].default) + else: + options = list(self._config) + bindings = dict(self._config.get_obj('bindings.commands')) + + configfiles.write_config_py(filename, options, bindings) diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index e1c6f720c..fe55312f1 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -245,6 +245,28 @@ class ConfigAPI: self._keyconfig.unbind(key, mode=mode) +def write_config_py(filename, options, bindings): + """Write a config.py file from given values.""" + with open(filename, 'w', encoding='utf-8') as f: + for opt, value in options: + if opt.name in ['bindings.commands', 'bindings.default']: + continue + for line in textwrap.wrap(opt.description): + f.write('# {}\n'.format(line)) + f.write('c.{} = {!r}\n\n'.format(opt.name, value)) + + normal_bindings = bindings.pop('normal', {}) + f.write('# Bindings for normal mode\n') + for key, command in sorted(normal_bindings.items()): + f.write('config.bind({!r}, {!r})\n'.format(key, command)) + + for mode, mode_bindings in sorted(bindings.items()): + f.write('\n# Bindings for {} mode\n'.format(mode)) + for key, command in sorted(mode_bindings.items()): + f.write('config.bind({!r}, {!r}, mode={!r})\n'.format( + key, command, mode)) + + def read_config_py(filename, raising=False): """Read a config.py file.