From 5efca155948bc467e4fb7b19dafd98d47e33745b Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Thu, 30 Mar 2017 17:45:51 +0100 Subject: [PATCH] Put option comments right above the option value Problem: I like to edit `~/.config/qutebrowser/qutebrowser.conf` manually with Vim. This works great, except that the current format is a bit of a pain to deal with: [section-name] # section description # # [ Description of all the options] actual options So if I want to know the description or what the default value is, I need to scroll up and back down. Solution: change the order of the comments to: # section description [section-name] # Option description option = value # Option description two optiontwo = value # Hello, world! [section-two] ... Which is much more convenient (and also what almost any other program does). (This patch changes much less code than it looks in the diff; I just de-looped and moved `_str_option_desc` below `_str_items` as that makes more sense since it gets called by `_str_items`). --- qutebrowser/config/config.py | 78 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 05d71605f..83e0e9c8f 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -471,10 +471,9 @@ class ConfigManager(QObject): """Get the whole config as a string.""" lines = configdata.FIRST_COMMENT.strip('\n').splitlines() for sectname, sect in self.sections.items(): - lines.append('\n[{}]'.format(sectname)) - lines += self._str_section_desc(sectname) - lines += self._str_option_desc(sectname, sect) - lines += self._str_items(sect) + lines += ['\n'] + self._str_section_desc(sectname) + lines.append('[{}]'.format(sectname)) + lines += self._str_items(sectname, sect) return '\n'.join(lines) + '\n' def _str_section_desc(self, sectname): @@ -489,42 +488,7 @@ class ConfigManager(QObject): lines += wrapper.wrap(secline) return lines - def _str_option_desc(self, sectname, sect): - """Get the option description strings for sect/sectname.""" - wrapper = textwrapper.TextWrapper(initial_indent='#' + ' ' * 5, - subsequent_indent='#' + ' ' * 5) - lines = [] - if not getattr(sect, 'descriptions', None): - return lines - - for optname, option in sect.items(): - - lines.append('#') - typestr = ' ({})'.format(option.typ.get_name()) - lines.append("# {}{}:".format(optname, typestr)) - - try: - desc = self.sections[sectname].descriptions[optname] - except KeyError: - log.config.exception("No description for {}.{}!".format( - sectname, optname)) - continue - for descline in desc.splitlines(): - lines += wrapper.wrap(descline) - valid_values = option.typ.get_valid_values() - if valid_values is not None: - if valid_values.descriptions: - for val in valid_values: - desc = valid_values.descriptions[val] - lines += wrapper.wrap(" {}: {}".format(val, desc)) - else: - lines += wrapper.wrap("Valid values: {}".format(', '.join( - valid_values))) - lines += wrapper.wrap("Default: {}".format( - option.values['default'])) - return lines - - def _str_items(self, sect): + def _str_items(self, sectname, sect): """Get the option items as string for sect.""" lines = [] for optname, option in sect.items(): @@ -535,9 +499,43 @@ class ConfigManager(QObject): # configparser can't handle = in keys :( optname = optname.replace('=', '') keyval = '{} = {}'.format(optname, value) + lines += self._str_option_desc(sectname, sect, optname, option) lines.append(keyval) return lines + def _str_option_desc(self, sectname, sect, optname, option): + """Get the option description strings for a single option.""" + wrapper = textwrapper.TextWrapper(initial_indent='#' + ' ' * 5, + subsequent_indent='#' + ' ' * 5) + lines = [] + if not getattr(sect, 'descriptions', None): + return lines + + lines.append('') + typestr = ' ({})'.format(option.typ.get_name()) + lines.append("# {}{}:".format(optname, typestr)) + + try: + desc = self.sections[sectname].descriptions[optname] + except KeyError: + log.config.exception("No description for {}.{}!".format( + sectname, optname)) + return [] + for descline in desc.splitlines(): + lines += wrapper.wrap(descline) + valid_values = option.typ.get_valid_values() + if valid_values is not None: + if valid_values.descriptions: + for val in valid_values: + desc = valid_values.descriptions[val] + lines += wrapper.wrap(" {}: {}".format(val, desc)) + else: + lines += wrapper.wrap("Valid values: {}".format(', '.join( + valid_values))) + lines += wrapper.wrap("Default: {}".format( + option.values['default'])) + return lines + def _get_real_sectname(self, cp, sectname): """Get an old or new section name based on a configparser.