Config update and cleanup

This commit is contained in:
Florian Bruhin 2014-02-25 21:43:58 +01:00
parent 4b3ae3f013
commit 062e385028
3 changed files with 155 additions and 81 deletions

View File

@ -27,6 +27,7 @@ from configparser import (ConfigParser, ExtendedInterpolation, NoSectionError,
from qutebrowser.utils.misc import read_file
import qutebrowser.config.options as opt
import qutebrowser.config.sections as sect
config = None
state = None
@ -54,7 +55,7 @@ class ConfigStructure:
def __init__(self):
self.config = OrderedDict([
('general', KeyValueSection(
('general', sect.KeyValue(
('show_completion', opt.ShowCompletion()),
('completion_height', opt.CompletionHeight()),
('ignorecase', opt.IgnoreCase()),
@ -64,7 +65,7 @@ class ConfigStructure:
('zoomlevels', opt.ZoomLevels()),
('defaultzoom', opt.DefaultZoom()),
)),
('tabbar', KeyValueSection(
('tabbar', sect.KeyValue(
('movable', opt.Movable()),
('closebuttons', opt.CloseButtons()),
('scrollbuttons', opt.ScrollButtons()),
@ -72,16 +73,10 @@ class ConfigStructure:
('select_on_remove', opt.SelectOnRemove()),
('last_close', opt.LastClose()),
)),
('searchengines', ValueListSection(
opt.SearchEngineKeyValue()
)),
('keybind', ValueListSection(
opt.KeybindKeyValue()
)),
('aliases', ValueListSection(
opt.AliasKeyValue()
)),
('colors', KeyValueSection(
('searchengines', sect.SearchEngines()),
('keybind', sect.KeyBindings()),
('aliases', sect.Aliases()),
('colors', sect.KeyValue(
('completion.fg', opt.CompletionFgColor()),
('completion.item.bg', opt.CompletionItemBgColor()),
('completion.category.bg', opt.CompletionCategoryBgColor()),

View File

@ -33,17 +33,17 @@ class CompletionHeight(template.SettingValue):
default = "50%"
def validate(self, value):
if value.endswith('%'):
def validate(self):
if self.value.endswith('%'):
try:
intval = int(value.rstrip('%'))
intval = int(self.value.rstrip('%'))
except ValueError:
return False
else:
return 0 <= intval <= 100
else:
try:
intval = int(value)
intval = int(self.value)
except ValueError:
return False
else:
@ -75,21 +75,21 @@ class AutoSearch(template.BoolSettingValue):
"""Whether to start a search when something else than an URL is entered."""
values = [("naive", "Use simple/naive check."),
("dns", "Use DNS requests (might be slow!)."),
("false", "Never search automatically.")]
valid_values = [("naive", "Use simple/naive check."),
("dns", "Use DNS requests (might be slow!)."),
("false", "Never search automatically.")]
default = "naive"
def validate(self, value):
if value.lower() in ["naive", "dns"]:
def validate(self):
if self.value.lower() in ["naive", "dns"]:
return True
else:
return super().validate(value)
return super().validate(self.value)
def transform(self, value):
if value.lower() in ["naive", "dns"]:
return value.lower()
elif super().transform(value):
def transform(self):
if self.value.lower() in ["naive", "dns"]:
return self.value.lower()
elif super().transform(self.value):
# boolean true is an alias for naive matching
return "naive"
else:
@ -137,7 +137,7 @@ class Position(template.SettingValue):
"""The position of the tab bar."""
values = ["north", "south", "east", "west"]
valid_values = ["north", "south", "east", "west"]
default = "north"
@ -145,9 +145,9 @@ class SelectOnRemove(template.SettingValue):
"""Which tab to select when the focused tab is removed."""
values = [("left", "Select the tab on the left."),
("right", "Select the tab on the right."),
("previous", "Select the previously selected tab.")]
valid_values = [("left", "Select the tab on the left."),
("right", "Select the tab on the right."),
("previous", "Select the previously selected tab.")]
default = "previous"
@ -155,9 +155,9 @@ class LastClose(template.SettingValue):
"""Behaviour when the last tab is closed."""
values = [("ignore", "Don't do anything."),
("blank", "Load about:blank."),
("quit", "Quit qutebrowser.")]
valid_values = [("ignore", "Don't do anything."),
("blank", "Load about:blank."),
("quit", "Quit qutebrowser.")]
default = "ignore"
### FIXME what to do with list-style sections?
@ -167,8 +167,8 @@ class SearchEngine(template.SettingValue):
"""A search engine setting."""
def validate(self, value):
return "{}" in value
def validate(self):
return "{}" in self.value
class CompletionFgColor(template.ColorSettingValue):
@ -260,7 +260,8 @@ class StatusbarFgErrorColor(template.ColorSettingValue):
"""Foreground color of the statusbar if there was an error."""
default = "${statusbar.fg}"
default = StatusbarFgColor.default
default_conf = "${statusbar.fg}"
class StatusbarBgErrorColor(template.ColorSettingValue):
@ -281,7 +282,8 @@ class StatusbarUrlFgColor(template.ColorSettingValue):
"""Default foreground color of the URL in the statusbar."""
default = "${statusbar.fg}"
default = StatusbarFgColor.default
default_conf = "${statusbar.fg}"
class StatusbarUrlSuccessFgColor(template.ColorSettingValue):
@ -353,18 +355,21 @@ class CompletionFont(template.FontSettingValue):
"""Font used in the completion widget."""
default = "8pt ${_monospace}"
default = MonospaceFonts.default
default_conf = "8pt ${_monospace}"
class TabbarFont(template.FontSettingValue):
"""Font used in the tabbar."""
default = "8pt ${_monospace}"
default = MonospaceFonts.default
default_conf = "8pt ${_monospace}"
class StatusbarFont(template.FontSettingValue):
"""Font used in the statusbar."""
default = "8pt ${_monospace}"
default = MonospaceFonts.default
default_conf = "8pt ${_monospace}"

View File

@ -22,50 +22,84 @@ import qutebrowser.commands.utils as cmdutils
class SettingValue:
"""Base class for settings. The docstring is used as a description."""
"""Base class for setting values.
# Possible values, if they are fixed.
# Either a list of strings, or a list of (value, desc) tuples.
values = None
Intended to be subclassed by config value "types".
# Default value if user has not overriden it, as a string.
Attributes:
valid_values: Possible values if they can be expressed as a fixed
string. Either a list of strings, or a list of (value,
desc) tuples.
# FIXME actually handle tuples and stuff when validating
default: Default value if the user has not overridden it, as a string.
default_conf: Default value for the config, with interpolation.
value: (property) The currently valid, most important, transformed
value.
rawvalue: The current value as a raw string.
typestr: The name of the type to appear in the config.
"""
valid_values = None
default = None
default_conf = None
typestr = None
rawvalue = None
def transform(self, value):
def __init__(self, rawval=None):
"""Constructor.
Args:
rawval: Raw value to set.
"""
if rawval is not None:
self.rawvalue = rawval
def __str__(self):
"""Get raw string value."""
return self.rawvalue if self.rawvalue is not None else ''
@property
def value(self):
"""Get the currently valid value."""
# FIXME handle default properly
#if self._rawvalue is not None:
# val = self.rawvalue
#else:
# val = self.default
return self.transform()
def transform(self):
"""Transform the setting value.
This method can assume the value is indeed a valid value.
The default implementation returns the original value.
Args:
value: The value to transform.
Return:
The transformed value.
"""
return value
return self.value
def validate(self, value):
def validate(self):
"""Validate value against possible values.
The default implementation checks the value against self.values if it
was defined.
Args:
value: The value to validate.
The default implementation checks the value against self.valid_values
if it was defined.
Return:
Ture if validation succeeded, False otherwise.
Raise:
NotImplementedError if self.values is not defined and this method
should be overridden.
NotImplementedError if self.valid_values is not defined and this
method should be overridden.
"""
if self.values is not None:
return value in self.values
if self.valid_values is not None:
return self.value in self.valid_values
else:
raise NotImplementedError
@ -74,29 +108,32 @@ class BoolSettingValue(SettingValue):
"""Base class for a boolean setting."""
values = ['true', 'false']
valid_values = ['true', 'false']
typestr = 'bool'
# Taken from configparser
_BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
def transform(self, value):
return self._BOOLEAN_STATES[value.lower()]
def transform(self):
return self._BOOLEAN_STATES[self.value.lower()]
def validate(self, value):
return value.lower() in self._BOOLEAN_STATES
def validate(self):
return self.value.lower() in self._BOOLEAN_STATES
class IntSettingValue(SettingValue):
"""Base class for an integer setting."""
def transform(self, value):
return int(value)
typestr = 'int'
def validate(self, value):
def transform(self):
return int(self.value)
def validate(self):
try:
int(value)
int(self.value)
except ValueError:
return False
else:
@ -107,10 +144,12 @@ class ListSettingValue(SettingValue):
"""Base class for a (string-)list setting."""
def transform(self, value):
return value.split(',')
typestr = 'string-list'
def validate(self, value):
def transform(self):
return self.value.split(',')
def validate(self):
return True
@ -118,13 +157,15 @@ class IntListSettingValue(ListSettingValue):
"""Base class for an int-list setting."""
def transform(self, value):
vals = super().transform(value)
typestr = 'int-list'
def transform(self):
vals = super().transform(self.value)
return map(int, vals)
def validate(self, value):
def validate(self):
try:
self.transform(value)
self.transform(self.value)
except ValueError:
return False
else:
@ -135,15 +176,17 @@ class CommandSettingValue(SettingValue):
"""Base class for a command value with arguments."""
values = cmdutils.cmd_dict.values()
typestr = 'command'
def validate(self, value):
valid_values = cmdutils.cmd_dict.items()
def validate(self):
# We need to import this here to avoid circular dependencies
from qutebrowser.commands.parsers import (CommandParser,
NoSuchCommandError)
cp = CommandParser()
try:
cp.parse(value)
cp.parse(self.value)
except NoSuchCommandError:
return False
else:
@ -154,7 +197,9 @@ class ColorSettingValue(SettingValue):
"""Base class for a color value."""
def validate(self, value):
typestr = 'color'
def validate(self):
# FIXME validate colors
return True
@ -163,6 +208,35 @@ class FontSettingValue(SettingValue):
"""Base class for a font value."""
def validate(self, value):
typestr = 'font'
def validate(self):
# FIXME validate fonts
return True
class ValueListSection:
"""This class represents a section with a list key-value settings.
These are settings inside sections which don't have fixed keys, but instead
have a dynamic list of "key = value" pairs, like keybindings or
searchengines.
They basically consist of two different SettingValues and have no defaults.
Attributes:
values: An OrderedDict with key as index and value as value.
default: An OrderedDict with the default configuration as strings.
types: A tuple for (keytype, valuetype)
"""
values = None
default = None
types = None
def __str__(self):
"""Get the key = value pairs as a string."""
return '\n'.join('{} = {}'.format(key.rawvalue, val.rawvalue)
for key, val in self.values)