Config update and cleanup
This commit is contained in:
parent
4b3ae3f013
commit
062e385028
@ -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()),
|
||||
|
@ -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}"
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user