Start refactoring new config to use types
This commit is contained in:
parent
641efb5c18
commit
40d7fc6f14
@ -245,16 +245,16 @@ class KeyParser(QObject):
|
||||
|
||||
"""
|
||||
for (key, cmd) in sect.items():
|
||||
if key.value.startswith('@') and key.value.endswith('@'):
|
||||
if key.startswith('@') and key.endswith('@'):
|
||||
# normalize keystring
|
||||
keystr = self._normalize_keystr(key.value.strip('@'))
|
||||
keystr = self._normalize_keystr(key.strip('@'))
|
||||
logging.debug('registered mod key: {} -> {}'.format(keystr,
|
||||
cmd.value))
|
||||
self._modifier_bindings[keystr] = cmd.value
|
||||
else:
|
||||
logging.debug('registered key: {} -> {}'.format(key.value,
|
||||
logging.debug('registered key: {} -> {}'.format(key,
|
||||
cmd.value))
|
||||
self._bindings[key.value] = cmd.value
|
||||
self._bindings[key] = cmd.value
|
||||
|
||||
def handle(self, e):
|
||||
"""Handle a new keypress and call the respective handlers.
|
||||
|
@ -27,8 +27,9 @@ from configparser import (ConfigParser, ExtendedInterpolation, NoSectionError,
|
||||
NoOptionError)
|
||||
|
||||
#from qutebrowser.utils.misc import read_file
|
||||
import qutebrowser.config.options as opt
|
||||
import qutebrowser.config.conftypes as types
|
||||
import qutebrowser.config.sections as sect
|
||||
from qutebrowser.config.templates import SettingValue
|
||||
|
||||
config = None
|
||||
state = None
|
||||
@ -119,66 +120,212 @@ class NewConfig:
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
MONOSPACE = ('Monospace, "DejaVu Sans Mono", Consolas, Monaco, '
|
||||
'"Bitstream Vera Sans Mono", "Andale Mono", '
|
||||
'"Liberation Mono", "Courier New", Courier, monospace, '
|
||||
'Fixed, Terminal')
|
||||
|
||||
self.config = OrderedDict([
|
||||
('general', sect.KeyValue(
|
||||
('show_completion', opt.ShowCompletion()),
|
||||
('completion_height', opt.CompletionHeight()),
|
||||
('ignorecase', opt.IgnoreCase()),
|
||||
('wrapsearch', opt.WrapSearch()),
|
||||
('startpage', opt.StartPage()),
|
||||
('auto_search', opt.AutoSearch()),
|
||||
('zoomlevels', opt.ZoomLevels()),
|
||||
('defaultzoom', opt.DefaultZoom()),
|
||||
('show_completion',
|
||||
SettingValue(types.Bool, "true"),
|
||||
"Whether to show the autocompletion window or not."),
|
||||
|
||||
('completion_height',
|
||||
SettingValue(types.PercOrInt, "50%"),
|
||||
"The height of the completion, in px or as percentage of the "
|
||||
"window."),
|
||||
|
||||
('ignorecase',
|
||||
SettingValue(types.Bool, "true"),
|
||||
"Whether to do case-insensitive searching."),
|
||||
|
||||
('wrapsearch',
|
||||
SettingValue(types.Bool, "true"),
|
||||
"Whether to wrap search to the top when arriving at the "
|
||||
"end."),
|
||||
|
||||
('startpage',
|
||||
SettingValue(types.List, "http://www.duckduckgo.com"),
|
||||
"The default page(s) to open at the start, separated with "
|
||||
"commas."),
|
||||
|
||||
('auto_search',
|
||||
SettingValue(types.AutoSearch, "naive"),
|
||||
"Whether to start a search when something else than an URL "
|
||||
"is entered."),
|
||||
|
||||
('zoomlevels',
|
||||
SettingValue(types.Int, "25,33,50,67,75,90,100,110,125,150,"
|
||||
"175,200,250,300,400,500"),
|
||||
"The available zoom levels, separated by commas."),
|
||||
|
||||
('defaultzoom',
|
||||
SettingValue(types.Int, "100"),
|
||||
"The default zoom level."),
|
||||
)),
|
||||
|
||||
('tabbar', sect.KeyValue(
|
||||
('movable', opt.Movable()),
|
||||
('closebuttons', opt.CloseButtons()),
|
||||
('scrollbuttons', opt.ScrollButtons()),
|
||||
('position', opt.Position()),
|
||||
('select_on_remove', opt.SelectOnRemove()),
|
||||
('last_close', opt.LastClose()),
|
||||
('movable',
|
||||
SettingValue(types.Bool, "true"),
|
||||
"Whether tabs should be movable."),
|
||||
|
||||
('closebuttons',
|
||||
SettingValue(types.Bool, "false"),
|
||||
"Whether tabs should have close-buttons."),
|
||||
|
||||
('scrollbuttons',
|
||||
SettingValue(types.Bool, "true"),
|
||||
"Whether there should be scroll buttons if there are too "
|
||||
"many tabs."),
|
||||
|
||||
('position',
|
||||
SettingValue(types.Position, "north"),
|
||||
"The position of the tab bar."),
|
||||
|
||||
('select_on_remove',
|
||||
SettingValue(types.SelectOnRemove, "previous"),
|
||||
"Which tab to select when the focused tab is removed."),
|
||||
|
||||
('last_close',
|
||||
SettingValue(types.LastClose, "ignore"),
|
||||
"Behaviour when the last tab is closed."),
|
||||
)),
|
||||
|
||||
('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()),
|
||||
('completion.fg',
|
||||
SettingValue(types.Color, "#333333"),
|
||||
"Text color of the completion widget."),
|
||||
|
||||
('completion.item.bg',
|
||||
SettingValue(types.Color, "white"),
|
||||
"Background color of completion widget items."),
|
||||
|
||||
('completion.category.bg',
|
||||
SettingValue(
|
||||
types.Color,
|
||||
"qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #e4e4e4, "
|
||||
"stop:1 #dbdbdb)"),
|
||||
"Background color of the completion widget category "
|
||||
"headers."),
|
||||
|
||||
('completion.category.border.top',
|
||||
opt.CompletionCategoryTopBorderColor()),
|
||||
SettingValue(types.Color, "#808080"),
|
||||
"Top border color of the completion widget category "
|
||||
"headers."),
|
||||
|
||||
('completion.category.border.bottom',
|
||||
opt.CompletionCategoryBottomBorderColor()),
|
||||
SettingValue(types.Color, "#bbbbbb"),
|
||||
"Bottom border color of the completion widget category "
|
||||
"headers."),
|
||||
|
||||
('completion.item.selected.fg',
|
||||
opt.CompletionItemSelectedFgColor()),
|
||||
SettingValue(types.Color, "#333333"),
|
||||
"Foreground color of the selected completion item."),
|
||||
|
||||
('completion.item.selected.bg',
|
||||
opt.CompletionItemSelectedBgColor()),
|
||||
SettingValue(types.Color, "#ffec8b"),
|
||||
"Background color of the selected completion item."),
|
||||
|
||||
('completion.item.selected.border.top',
|
||||
opt.CompletionItemSelectedTopBorderColor()),
|
||||
SettingValue(types.Color, "#f2f2c0"),
|
||||
"Top border color of the completion widget category "
|
||||
"headers."),
|
||||
|
||||
('completion.item.selected.border.bottom',
|
||||
opt.CompletionCategoryBottomBorderColor()),
|
||||
SettingValue(types.Color, "#ffec8b"),
|
||||
"Bottom border color of the selected completion item."),
|
||||
|
||||
('completion.match.fg',
|
||||
opt.CompletionMatchFgColor()),
|
||||
('statusbar.bg', opt.StatusbarBgColor()),
|
||||
('statusbar.fg', opt.StatusbarFgColor()),
|
||||
('statusbar.bg.error', opt.StatusbarBgErrorColor()),
|
||||
('statusbar.fg.error', opt.StatusbarFgErrorColor()),
|
||||
('statusbar.progress.bg', opt.StatusbarProgressBgColor()),
|
||||
('statusbar.url.fg', opt.StatusbarUrlFgColor()),
|
||||
('statusbar.url.fg.success', opt.StatusbarUrlHoverFgColor()),
|
||||
('statusbar.url.fg.error', opt.StatusbarUrlErrorFgColor()),
|
||||
('statusbar.url.fg.warn', opt.StatusbarUrlWarnFgColor()),
|
||||
('statusbar.url.fg.hover', opt.StatusbarUrlHoverFgColor()),
|
||||
('tab.fg', opt.TabFgColor()),
|
||||
('tab.bg', opt.TabBgColor()),
|
||||
('tab.bg.selected', opt.TabSelectedBgColor()),
|
||||
('tab.seperator', opt.TabSeperatorColor()),
|
||||
SettingValue(types.Color, "red"),
|
||||
"Foreground color of the matched text in the completion."),
|
||||
|
||||
('statusbar.bg',
|
||||
SettingValue(types.Color, "black"),
|
||||
"Foreground color of the statusbar."),
|
||||
|
||||
('statusbar.fg',
|
||||
SettingValue(types.Color, "white"),
|
||||
"Foreground color of the statusbar."),
|
||||
|
||||
('statusbar.bg.error',
|
||||
SettingValue(types.Color, "red"),
|
||||
"Background color of the statusbar if there was an error."),
|
||||
|
||||
('statusbar.fg.error',
|
||||
SettingValue(types.Color, "white", "${statusbar.fg}"),
|
||||
"Foreground color of the statusbar if there was an error."),
|
||||
|
||||
('statusbar.progress.bg',
|
||||
SettingValue(types.Color, "white"),
|
||||
"Background color of the progress bar."),
|
||||
|
||||
('statusbar.url.fg',
|
||||
SettingValue(types.Color, "white", "${statusbar.fg}"),
|
||||
"Default foreground color of the URL in the statusbar."),
|
||||
|
||||
('statusbar.url.fg.success',
|
||||
SettingValue(types.Color, "lime"),
|
||||
"Foreground color of the URL in the statusbar on successful "
|
||||
"load."),
|
||||
|
||||
('statusbar.url.fg.error',
|
||||
SettingValue(types.Color, "orange"),
|
||||
"Foreground color of the URL in the statusbar on error."),
|
||||
|
||||
('statusbar.url.fg.warn',
|
||||
SettingValue(types.Color, "yellow"),
|
||||
"Foreground color of the URL in the statusbar when there's a "
|
||||
"warning."),
|
||||
|
||||
('statusbar.url.fg.hover',
|
||||
SettingValue(types.Color, "aqua"),
|
||||
"Foreground color of the URL in the statusbar for hovered "
|
||||
"links."),
|
||||
|
||||
('tab.fg',
|
||||
SettingValue(types.Color, "white"),
|
||||
"Foreground color of the tabbar."),
|
||||
|
||||
('tab.bg',
|
||||
SettingValue(types.Color, "grey"),
|
||||
"Background color of the tabbar."),
|
||||
|
||||
('tab.bg.selected',
|
||||
SettingValue(types.Color, "black"),
|
||||
"Background color of the tabbar for the selected tab."),
|
||||
|
||||
('tab.seperator',
|
||||
SettingValue(types.Color, "white"),
|
||||
"Color for the tab seperator."),
|
||||
)),
|
||||
|
||||
('fonts', sect.KeyValue(
|
||||
('_monospace', opt.MonospaceFonts()),
|
||||
('completion', opt.CompletionFont()),
|
||||
('tabbar', opt.TabbarFont()),
|
||||
('statusbar', opt.StatusbarFont()),
|
||||
('_monospace',
|
||||
SettingValue(types.Font, MONOSPACE),
|
||||
"Default monospace fonts."),
|
||||
|
||||
('completion',
|
||||
SettingValue(types.Font, "8pt " + MONOSPACE,
|
||||
"8pt ${_monospace}"),
|
||||
"Font used in the completion widget."),
|
||||
|
||||
('tabbar',
|
||||
SettingValue(types.Font, "8pt " + MONOSPACE,
|
||||
"8pt ${_monospace}"),
|
||||
"Font used in the tabbar."),
|
||||
|
||||
('statusbar',
|
||||
SettingValue(types.Font, "8pt " + MONOSPACE,
|
||||
"8pt ${_monospace}"),
|
||||
"Font used in the statusbar."),
|
||||
|
||||
)),
|
||||
])
|
||||
|
||||
|
294
qutebrowser/config/conftypes.py
Normal file
294
qutebrowser/config/conftypes.py
Normal file
@ -0,0 +1,294 @@
|
||||
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Setting options used for qutebrowser."""
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
|
||||
|
||||
class BaseType:
|
||||
|
||||
"""A type used for a setting value.
|
||||
|
||||
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
|
||||
typestr: The name of the type to appear in the config.
|
||||
|
||||
"""
|
||||
|
||||
typestr = None
|
||||
valid_values = None
|
||||
|
||||
def transform(self, value):
|
||||
"""Transform the setting value.
|
||||
|
||||
This method can assume the value is indeed a valid value.
|
||||
|
||||
The default implementation returns the original value.
|
||||
|
||||
Return:
|
||||
The transformed value.
|
||||
|
||||
"""
|
||||
return value
|
||||
|
||||
def validate(self):
|
||||
"""Validate value against possible values.
|
||||
|
||||
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.valid_values is not defined and this
|
||||
method should be overridden.
|
||||
|
||||
"""
|
||||
if self.valid_values is not None:
|
||||
return self.value in self.valid_values
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
class String(BaseType):
|
||||
|
||||
"""Base class for a string setting (case-insensitive)."""
|
||||
|
||||
typestr = 'string'
|
||||
|
||||
def transform(self, value):
|
||||
return value.lower()
|
||||
|
||||
|
||||
class Bool(BaseType):
|
||||
|
||||
"""Base class for a boolean setting."""
|
||||
|
||||
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 validate(self):
|
||||
return self.value.lower() in self._BOOLEAN_STATES
|
||||
|
||||
|
||||
class Int(BaseType):
|
||||
|
||||
"""Base class for an integer setting."""
|
||||
|
||||
typestr = 'int'
|
||||
|
||||
def transform(self, value):
|
||||
return int(value)
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
int(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class List(BaseType):
|
||||
|
||||
"""Base class for a (string-)list setting."""
|
||||
|
||||
typestr = 'string-list'
|
||||
|
||||
def transform(self, value):
|
||||
return value.split(',')
|
||||
|
||||
def validate(self):
|
||||
return True
|
||||
|
||||
|
||||
class IntList(List):
|
||||
|
||||
"""Base class for an int-list setting."""
|
||||
|
||||
typestr = 'int-list'
|
||||
|
||||
def transform(self, value):
|
||||
vals = super().transform(value)
|
||||
return map(int, vals)
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
self.transform(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class PercOrInt(BaseType):
|
||||
|
||||
"""Percentage or integer."""
|
||||
|
||||
def validate(self):
|
||||
if self.value.endswith('%'):
|
||||
try:
|
||||
intval = int(self.value.rstrip('%'))
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return 0 <= intval <= 100
|
||||
else:
|
||||
try:
|
||||
intval = int(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return intval > 0
|
||||
|
||||
|
||||
class Command(BaseType):
|
||||
|
||||
"""Base class for a command value with arguments."""
|
||||
|
||||
typestr = 'command'
|
||||
|
||||
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(self.value)
|
||||
except NoSuchCommandError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class Color(BaseType):
|
||||
|
||||
"""Base class for a color value."""
|
||||
|
||||
typestr = 'color'
|
||||
|
||||
def validate(self):
|
||||
# FIXME validate colors
|
||||
return True
|
||||
|
||||
|
||||
class Font(BaseType):
|
||||
|
||||
"""Base class for a font value."""
|
||||
|
||||
typestr = 'font'
|
||||
|
||||
def validate(self):
|
||||
# FIXME validate fonts
|
||||
return True
|
||||
|
||||
|
||||
class SearchEngineName(BaseType):
|
||||
|
||||
"""A search engine name."""
|
||||
|
||||
def validate(self):
|
||||
return True
|
||||
|
||||
|
||||
class SearchEngineUrl(BaseType):
|
||||
|
||||
"""A search engine URL."""
|
||||
|
||||
def validate(self):
|
||||
return "{}" in self.value
|
||||
|
||||
|
||||
class KeyBindingName(BaseType):
|
||||
|
||||
"""The name (keys) of a keybinding."""
|
||||
|
||||
def validate(self):
|
||||
# FIXME can we validate anything here?
|
||||
return True
|
||||
|
||||
|
||||
|
||||
class AutoSearch(Bool):
|
||||
|
||||
"""Whether to start a search when something else than an URL is entered."""
|
||||
|
||||
valid_values = [("naive", "Use simple/naive check."),
|
||||
("dns", "Use DNS requests (might be slow!)."),
|
||||
("false", "Never search automatically.")]
|
||||
|
||||
def validate(self):
|
||||
if self.value.lower() in ["naive", "dns"]:
|
||||
return True
|
||||
else:
|
||||
return super().validate(self.value)
|
||||
|
||||
def transform(self, value):
|
||||
if value.lower() in ["naive", "dns"]:
|
||||
return value.lower()
|
||||
elif super().transform(value):
|
||||
# boolean true is an alias for naive matching
|
||||
return "naive"
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class Position(String):
|
||||
|
||||
"""The position of the tab bar."""
|
||||
|
||||
valid_values = ["north", "south", "east", "west"]
|
||||
|
||||
|
||||
class SelectOnRemove(String):
|
||||
|
||||
"""Which tab to select when the focused tab is removed."""
|
||||
|
||||
valid_values = [("left", "Select the tab on the left."),
|
||||
("right", "Select the tab on the right."),
|
||||
("previous", "Select the previously selected tab.")]
|
||||
|
||||
|
||||
class LastClose(String):
|
||||
|
||||
"""Behaviour when the last tab is closed."""
|
||||
|
||||
valid_values = [("ignore", "Don't do anything."),
|
||||
("blank", "Load about:blank."),
|
||||
("quit", "Quit qutebrowser.")]
|
||||
|
||||
|
||||
class KeyBinding(Command):
|
||||
|
||||
"""The command of a keybinding."""
|
||||
|
||||
pass
|
||||
|
||||
|
@ -1,397 +0,0 @@
|
||||
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Setting options used for qutebrowser."""
|
||||
|
||||
import qutebrowser.config.templates as template
|
||||
|
||||
|
||||
class ShowCompletion(template.BoolSettingValue):
|
||||
|
||||
"""Whether to show the autocompletion window or not."""
|
||||
|
||||
default = "true"
|
||||
|
||||
|
||||
class CompletionHeight(template.SettingValue):
|
||||
|
||||
"""The height of the completion, in px or as percentage of the window."""
|
||||
|
||||
default = "50%"
|
||||
|
||||
def validate(self):
|
||||
if self.value.endswith('%'):
|
||||
try:
|
||||
intval = int(self.value.rstrip('%'))
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return 0 <= intval <= 100
|
||||
else:
|
||||
try:
|
||||
intval = int(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return intval > 0
|
||||
|
||||
|
||||
class IgnoreCase(template.BoolSettingValue):
|
||||
|
||||
"""Whether to do case-insensitive searching."""
|
||||
|
||||
default = "true"
|
||||
|
||||
|
||||
class WrapSearch(template.BoolSettingValue):
|
||||
|
||||
"""Whether to wrap search to the top when arriving at the end."""
|
||||
|
||||
default = "true"
|
||||
|
||||
|
||||
class StartPage(template.ListSettingValue):
|
||||
|
||||
"""The default page(s) to open at the start, separated with commas."""
|
||||
|
||||
default = "http://www.duckduckgo.com/"
|
||||
|
||||
|
||||
class AutoSearch(template.BoolSettingValue):
|
||||
|
||||
"""Whether to start a search when something else than an URL is entered."""
|
||||
|
||||
valid_values = [("naive", "Use simple/naive check."),
|
||||
("dns", "Use DNS requests (might be slow!)."),
|
||||
("false", "Never search automatically.")]
|
||||
default = "naive"
|
||||
|
||||
def validate(self):
|
||||
if self.value.lower() in ["naive", "dns"]:
|
||||
return True
|
||||
else:
|
||||
return super().validate(self.value)
|
||||
|
||||
def transform(self, value):
|
||||
if value.lower() in ["naive", "dns"]:
|
||||
return value.lower()
|
||||
elif super().transform(value):
|
||||
# boolean true is an alias for naive matching
|
||||
return "naive"
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class ZoomLevels(template.IntListSettingValue):
|
||||
|
||||
"""The available zoom levels, separated by commas."""
|
||||
|
||||
default = "25,33,50,67,75,90,100,110,125,150,175,200,250,300,400,500"
|
||||
|
||||
|
||||
class DefaultZoom(template.IntSettingValue):
|
||||
|
||||
"""The default zoom level."""
|
||||
|
||||
# FIXME we might want to validate if defaultzoom is in zoomlevels...
|
||||
|
||||
default = "100"
|
||||
|
||||
|
||||
class Movable(template.BoolSettingValue):
|
||||
|
||||
"""Whether tabs should be movable."""
|
||||
|
||||
default = "true"
|
||||
|
||||
|
||||
class CloseButtons(template.BoolSettingValue):
|
||||
|
||||
"""Whether tabs should have close-buttons."""
|
||||
|
||||
default = "false"
|
||||
|
||||
|
||||
class ScrollButtons(template.BoolSettingValue):
|
||||
|
||||
"""Whether there should be scroll buttons if there are too many tabs."""
|
||||
|
||||
default = "true"
|
||||
|
||||
|
||||
class Position(template.StringSettingValue):
|
||||
|
||||
"""The position of the tab bar."""
|
||||
|
||||
valid_values = ["north", "south", "east", "west"]
|
||||
default = "north"
|
||||
|
||||
|
||||
class SelectOnRemove(template.StringSettingValue):
|
||||
|
||||
"""Which tab to select when the focused tab is removed."""
|
||||
|
||||
valid_values = [("left", "Select the tab on the left."),
|
||||
("right", "Select the tab on the right."),
|
||||
("previous", "Select the previously selected tab.")]
|
||||
default = "previous"
|
||||
|
||||
|
||||
class LastClose(template.StringSettingValue):
|
||||
|
||||
"""Behaviour when the last tab is closed."""
|
||||
|
||||
valid_values = [("ignore", "Don't do anything."),
|
||||
("blank", "Load about:blank."),
|
||||
("quit", "Quit qutebrowser.")]
|
||||
default = "ignore"
|
||||
|
||||
|
||||
class CompletionFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Text color of the completion widget."""
|
||||
|
||||
default = "#333333"
|
||||
|
||||
|
||||
class CompletionItemBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of completion widget items."""
|
||||
|
||||
default = "white"
|
||||
|
||||
|
||||
class CompletionCategoryBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the completion widget category headers."""
|
||||
|
||||
default = ("qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #e4e4e4, "
|
||||
"stop:1 #dbdbdb)")
|
||||
|
||||
|
||||
class CompletionCategoryTopBorderColor(template.ColorSettingValue):
|
||||
|
||||
"""Top border color of the completion widget category headers."""
|
||||
|
||||
default = "#808080"
|
||||
|
||||
|
||||
class CompletionCategoryBottomBorderColor(template.ColorSettingValue):
|
||||
|
||||
"""Bottom border color of the completion widget category headers."""
|
||||
|
||||
default = "#bbbbbb"
|
||||
|
||||
|
||||
class CompletionItemSelectedFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the selected completion item."""
|
||||
|
||||
default = "#333333"
|
||||
|
||||
|
||||
class CompletionItemSelectedBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the selected completion item."""
|
||||
|
||||
default = "#ffec8b"
|
||||
|
||||
|
||||
class CompletionItemSelectedTopBorderColor(template.ColorSettingValue):
|
||||
|
||||
"""Top border color of the selected completion item."""
|
||||
|
||||
default = "#f2f2c0"
|
||||
|
||||
|
||||
class CompletionItemSelectedBottomBorderColor(template.ColorSettingValue):
|
||||
|
||||
"""Bottom border color of the selected completion item."""
|
||||
|
||||
default = "#ffec8b"
|
||||
|
||||
|
||||
class CompletionMatchFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the matched text in the completion."""
|
||||
|
||||
default = "red"
|
||||
|
||||
|
||||
class StatusbarBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the statusbar."""
|
||||
|
||||
default = "black"
|
||||
|
||||
|
||||
class StatusbarFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the statusbar."""
|
||||
|
||||
default = "white"
|
||||
|
||||
|
||||
class StatusbarFgErrorColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the statusbar if there was an error."""
|
||||
|
||||
default = StatusbarFgColor.default
|
||||
default_conf = "${statusbar.fg}"
|
||||
|
||||
|
||||
class StatusbarBgErrorColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the statusbar if there was an error."""
|
||||
|
||||
default = "red"
|
||||
|
||||
|
||||
class StatusbarProgressBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the progress bar."""
|
||||
|
||||
default = "white"
|
||||
|
||||
|
||||
class StatusbarUrlFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Default foreground color of the URL in the statusbar."""
|
||||
|
||||
default = StatusbarFgColor.default
|
||||
default_conf = "${statusbar.fg}"
|
||||
|
||||
|
||||
class StatusbarUrlSuccessFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the URL in the statusbar on successful load."""
|
||||
|
||||
default = "lime"
|
||||
|
||||
|
||||
class StatusbarUrlErrorFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the URL in the statusbar on error."""
|
||||
|
||||
default = "orange"
|
||||
|
||||
|
||||
class StatusbarUrlWarnFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the URL in the statusbar when there's a warning."""
|
||||
|
||||
default = "yellow"
|
||||
|
||||
|
||||
class StatusbarUrlHoverFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the URL in the statusbar for hovered links."""
|
||||
|
||||
default = "aqua"
|
||||
|
||||
|
||||
class TabFgColor(template.ColorSettingValue):
|
||||
|
||||
"""Foreground color of the tabbar."""
|
||||
|
||||
default = "white"
|
||||
|
||||
|
||||
class TabBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the tabbar."""
|
||||
|
||||
default = "grey"
|
||||
|
||||
|
||||
class TabSelectedBgColor(template.ColorSettingValue):
|
||||
|
||||
"""Background color of the tabbar for the selected tab."""
|
||||
|
||||
default = "black"
|
||||
|
||||
|
||||
class TabSeperatorColor(template.ColorSettingValue):
|
||||
|
||||
"""Color for the tab seperator."""
|
||||
|
||||
default = "white"
|
||||
|
||||
|
||||
class MonospaceFonts(template.FontSettingValue):
|
||||
|
||||
"""Default monospace fonts."""
|
||||
|
||||
default = ('Monospace, "DejaVu Sans Mono", Consolas, Monaco, '
|
||||
'"Bitstream Vera Sans Mono", "Andale Mono", "Liberation Mono", '
|
||||
'"Courier New", Courier, monospace, Fixed, Terminal')
|
||||
|
||||
|
||||
class CompletionFont(template.FontSettingValue):
|
||||
|
||||
"""Font used in the completion widget."""
|
||||
|
||||
default = "8pt " + MonospaceFonts.default
|
||||
default_conf = "8pt ${_monospace}"
|
||||
|
||||
|
||||
class TabbarFont(template.FontSettingValue):
|
||||
|
||||
"""Font used in the tabbar."""
|
||||
|
||||
default = "8pt " + MonospaceFonts.default
|
||||
default_conf = "8pt ${_monospace}"
|
||||
|
||||
|
||||
class StatusbarFont(template.FontSettingValue):
|
||||
|
||||
"""Font used in the statusbar."""
|
||||
|
||||
default = "8pt " + MonospaceFonts.default
|
||||
default_conf = "8pt ${_monospace}"
|
||||
|
||||
|
||||
class SearchEngineName(template.SettingValue):
|
||||
|
||||
"""A search engine name."""
|
||||
|
||||
def validate(self):
|
||||
return True
|
||||
|
||||
|
||||
class SearchEngineUrl(template.SettingValue):
|
||||
|
||||
"""A search engine URL."""
|
||||
|
||||
def validate(self):
|
||||
return "{}" in self.value
|
||||
|
||||
|
||||
class KeyBindingName(template.SettingValue):
|
||||
|
||||
"""The name (keys) of a keybinding."""
|
||||
|
||||
def validate(self):
|
||||
# FIXME can we validate anything here?
|
||||
return True
|
||||
|
||||
|
||||
class KeyBinding(template.CommandSettingValue):
|
||||
|
||||
"""The command of a keybinding."""
|
||||
|
||||
pass
|
@ -20,7 +20,7 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
import qutebrowser.config.templates as template
|
||||
import qutebrowser.config.options as opt
|
||||
import qutebrowser.config.conftypes as conftypes
|
||||
|
||||
|
||||
class KeyValue:
|
||||
@ -47,7 +47,9 @@ class KeyValue:
|
||||
|
||||
"""
|
||||
if args:
|
||||
self.values = OrderedDict(args)
|
||||
self.values = OrderedDict()
|
||||
for (k, settingval, desc) in args:
|
||||
self.values[k] = settingval
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Get the value for key.
|
||||
@ -89,7 +91,7 @@ class SearchEngines(template.ValueListSection):
|
||||
|
||||
"""Search engine config section."""
|
||||
|
||||
types = (opt.SearchEngineName, opt.SearchEngineUrl)
|
||||
types = (conftypes.SearchEngineName, conftypes.SearchEngineUrl)
|
||||
# FIXME how to handle interpolation here?
|
||||
default = OrderedDict([
|
||||
('DEFAULT', '${duckduckgo}'),
|
||||
@ -107,7 +109,7 @@ class KeyBindings(template.ValueListSection):
|
||||
|
||||
"""Keybindings config section."""
|
||||
|
||||
types = (opt.KeyBindingName, opt.KeyBinding)
|
||||
types = (conftypes.KeyBindingName, conftypes.KeyBinding)
|
||||
default = OrderedDict([
|
||||
('o', 'open'),
|
||||
('go', 'opencur'),
|
||||
@ -153,5 +155,5 @@ class Aliases(template.ValueListSection):
|
||||
|
||||
"""Aliases config section."""
|
||||
|
||||
types = (template.CommandSettingValue, template.CommandSettingValue)
|
||||
types = (conftypes.Command, conftypes.Command)
|
||||
default = OrderedDict()
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
|
||||
|
||||
class SettingValue:
|
||||
|
||||
@ -29,35 +27,27 @@ class SettingValue:
|
||||
Intended to be subclassed by config value "types".
|
||||
|
||||
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
|
||||
|
||||
typ: A BaseType subclass.
|
||||
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 __init__(self, rawval=None):
|
||||
def __init__(self, typ, default, default_conf=None):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
rawval: Raw value to set.
|
||||
typ: The BaseType to use.
|
||||
default: Raw value to set.
|
||||
default_conf: Raw value to set, for the config.
|
||||
|
||||
"""
|
||||
if rawval is not None:
|
||||
self.rawvalue = rawval
|
||||
self.typ = typ
|
||||
self.default = default
|
||||
self.default_conf = default_conf
|
||||
|
||||
def __str__(self):
|
||||
"""Get raw string value."""
|
||||
@ -74,160 +64,7 @@ class SettingValue:
|
||||
val = self.rawvalue
|
||||
else:
|
||||
val = self.default
|
||||
return self.transform(val)
|
||||
|
||||
def transform(self, value):
|
||||
"""Transform the setting value.
|
||||
|
||||
This method can assume the value is indeed a valid value.
|
||||
|
||||
The default implementation returns the original value.
|
||||
|
||||
Return:
|
||||
The transformed value.
|
||||
|
||||
"""
|
||||
return value
|
||||
|
||||
def validate(self):
|
||||
"""Validate value against possible values.
|
||||
|
||||
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.valid_values is not defined and this
|
||||
method should be overridden.
|
||||
|
||||
"""
|
||||
if self.valid_values is not None:
|
||||
return self.value in self.valid_values
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class StringSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a string setting (case-insensitive)."""
|
||||
|
||||
typestr = 'string'
|
||||
|
||||
def transform(self, value):
|
||||
return value.lower()
|
||||
|
||||
|
||||
class BoolSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a boolean setting."""
|
||||
|
||||
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 validate(self):
|
||||
return self.value.lower() in self._BOOLEAN_STATES
|
||||
|
||||
|
||||
class IntSettingValue(SettingValue):
|
||||
|
||||
"""Base class for an integer setting."""
|
||||
|
||||
typestr = 'int'
|
||||
|
||||
def transform(self, value):
|
||||
return int(value)
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
int(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class ListSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a (string-)list setting."""
|
||||
|
||||
typestr = 'string-list'
|
||||
|
||||
def transform(self, value):
|
||||
return value.split(',')
|
||||
|
||||
def validate(self):
|
||||
return True
|
||||
|
||||
|
||||
class IntListSettingValue(ListSettingValue):
|
||||
|
||||
"""Base class for an int-list setting."""
|
||||
|
||||
typestr = 'int-list'
|
||||
|
||||
def transform(self, value):
|
||||
vals = super().transform(value)
|
||||
return map(int, vals)
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
self.transform(self.value)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class CommandSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a command value with arguments."""
|
||||
|
||||
typestr = 'command'
|
||||
|
||||
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(self.value)
|
||||
except NoSuchCommandError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class ColorSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a color value."""
|
||||
|
||||
typestr = 'color'
|
||||
|
||||
def validate(self):
|
||||
# FIXME validate colors
|
||||
return True
|
||||
|
||||
|
||||
class FontSettingValue(SettingValue):
|
||||
|
||||
"""Base class for a font value."""
|
||||
|
||||
typestr = 'font'
|
||||
|
||||
def validate(self):
|
||||
# FIXME validate fonts
|
||||
return True
|
||||
return self.typ.transform(val)
|
||||
|
||||
|
||||
class ValueListSection:
|
||||
@ -255,7 +92,9 @@ class ValueListSection:
|
||||
def __init__(self):
|
||||
"""Wrap types over default values. Take care when overriding this."""
|
||||
self.values = OrderedDict()
|
||||
self.default = {self.types[0](key): self.types[1](value)
|
||||
keytype = self.types[0]()
|
||||
valtype = self.types[1]()
|
||||
self.default = {keytype.transform(key): valtype.transform(value)
|
||||
for key, value in self.default.items()}
|
||||
|
||||
def __getitem__(self, key):
|
||||
|
Loading…
Reference in New Issue
Block a user