Start new config subsystem

This commit is contained in:
Florian Bruhin 2014-02-24 07:17:17 +01:00
parent dc18ec4e0d
commit 395acffdc4
3 changed files with 575 additions and 0 deletions

View File

@ -21,10 +21,12 @@ import os
import io
import os.path
import logging
from collections import OrderedDict
from configparser import (ConfigParser, ExtendedInterpolation, NoSectionError,
NoOptionError)
from qutebrowser.utils.misc import read_file
from qutebrowser.config.options import *
config = None
state = None
@ -46,6 +48,47 @@ def init(confdir):
state = Config(confdir, 'state', always_save=True)
class ConfigStructure:
def __init__(self):
self.config = OrderedDict([
('general', KeyValueSection(
('show_completion', ShowCompletion()),
('completion_height', CompletionHeight()),
('ignorecase', IgnoreCase()),
('wrapsearch', WrapSearch()),
('startpage', StartPage()),
('auto_search', AutoSearch()),
('zoomlevels', ZoomLevels()),
('defaultzoom', DefaultZoom()),
)),
('tabbar', KeyValueSection(
('movable', Movable()),
('closebuttons', CloseButtons()),
('scrollbuttons', ScrollButtons()),
('position', Position()),
('select_on_remove', SelectOnRemove()),
('last_close', LastClose()),
)),
('searchengines', ValueListSection(
SearchEngineKeyValue()
)),
('keybind', ValueListSection(
KeybindKeyValue()
)),
('aliases', ValueListSection(
AliasKeyValue()
)),
('colors', KeyValueSection(
('completion.fg', CompletionFgColor()),
('completion.item.bg', CompletionItemBgColor()),
# FIXME ...
)),
('fonts', KeyValueSection(
)),
])
class Config(ConfigParser):
"""Our own ConfigParser subclass.

View File

@ -0,0 +1,370 @@
# 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."""
from qutebrowser.config.templates import *
class ShowCompletion(BoolSettingValue):
"""Whether to show the autocompletion window or not."""
default = "true"
class CompletionHeight(SettingValue):
"""The height of the completion, in px or as percentage of the window."""
default = "50%"
def validate(self, value):
if value.endswith('%'):
try:
intval = int(value.rstrip('%'))
except ValueError:
return False
else:
return 0 <= intval <= 100
else:
try:
intval = int(value)
except ValueError:
return False
else:
return intval > 0
class IgnoreCase(BoolSettingValue):
"""Whether to do case-insensitive searching."""
default = "true"
class WrapSearch(BoolSettingValue):
"""Whether to wrap search to the top when arriving at the end."""
default = "true"
class StartPage(ListSettingValue):
"""The default page(s) to open at the start, separated with commas."""
default = "http://www.duckduckgo.com/"
class AutoSearch(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.")]
default = "naive"
def validate(self, value):
if value.lower() in ["naive", "dns"]:
return True
else:
return super().validate(value)
return True
else:
return super().validate(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(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(IntSettingValue):
"""The default zoom level."""
# FIXME we might want to validate if defaultzoom is in zoomlevels...
default = "100"
class Movable(BoolSettingValue):
"""Whether tabs should be movable."""
default = "true"
class CloseButtons(BoolSettingValue):
"""Whether tabs should have close-buttons."""
default = "false"
class ScrollButtons(BoolSettingValue):
"""Whether there should be scroll buttons if there are too many tabs."""
default = "true"
class Position(SettingValue):
"""The position of the tab bar."""
values = ["north", "south", "east", "west"]
default = "north"
class SelectOnRemove(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.")]
default = "previous"
class LastClose(SettingValue):
"""Behaviour when the last tab is closed."""
values = [("ignore", "Don't do anything."),
("blank", "Load about:blank."),
("quit", "Quit qutebrowser.")]
default = "ignore"
### FIXME what to do with list-style sections?
class SearchEngine(SettingValue):
"""A search engine setting."""
def validate(self, value):
return "{}" in value
class CompletionFgColor(ColorSettingValue):
"""Text color of the completion widget."""
default = "#333333"
class CompletionItemBgColor(ColorSettingValue):
"""Background color of completion widget items."""
default = "white"
class CompletionCategoryBgColor(ColorSettingValue):
"""Background color of the completion widget category headers."""
default = ("completion.category.bg = qlineargradient("
"x1:0, y1:0, x2:0, y2:1, stop:0 #e4e4e4, stop:1 #dbdbdb")
class CompletionCategoryTopBorderColor(ColorSettingValue):
"""Top border color of the completion widget category headers."""
default = "#808080"
class CompletionCategoryBottomBorderColor(ColorSettingValue):
"""Bottom border color of the completion widget category headers."""
default = "#bbbbbb"
class CompletionItemSelectedFgColor(ColorSettingValue):
"""Foreground color of the selected completion item."""
default = "#333333"
class CompletionItemSelectedBgColor(ColorSettingValue):
"""Background color of the selected completion item."""
default = "#ffec8b"
class CompletionItemSelectedTopBorderColor(ColorSettingValue):
"""Top border color of the selected completion item."""
default = "#f2f2c0"
class CompletionItemSelectedBottomBorderColor(ColorSettingValue):
"""Bottom border color of the selected completion item."""
default = "#ffec8b"
class CompletionMatchFgColor(ColorSettingValue):
"""Foreground color of the matched text in the completion."""
default = "red"
class StatusbarBgColor(ColorSettingValue):
"""Background color of the statusbar."""
default = "black"
class StatusbarFgColor(ColorSettingValue):
"""Foreground color of the statusbar."""
default = "white"
class StatusbarFgErrorColor(ColorSettingValue):
"""Foreground color of the statusbar if there was an error."""
default = "${statusbar.fg}"
class StatusbarBgErrorColor(ColorSettingValue):
"""Background color of the statusbar if there was an error."""
default = "red"
class StatusbarProgressBgColor(ColorSettingValue):
"""Background color of the progress bar."""
default = "white"
class StatusbarUrlFgColor(ColorSettingValue):
"""Default foreground color of the URL in the statusbar."""
default = "${statusbar.fg}"
class StatusbarUrlSuccessFgColor(ColorSettingValue):
"""Foreground color of the URL in the statusbar on successful load."""
default = "lime"
class StatusbarUrlErrorFgColor(ColorSettingValue):
"""Foreground color of the URL in the statusbar on error."""
default = "orange"
class StatusbarUrlWarnFgColor(ColorSettingValue):
"""Foreground color of the URL in the statusbar when there's a warning."""
default = "yellow"
class StatusbarUrlHoverFgColor(ColorSettingValue):
"""Foreground color of the URL in the statusbar for hovered links."""
default = "aqua"
class TabFgColor(ColorSettingValue):
"""Foreground color of the tabbar."""
default = "white"
class TabBgColor(ColorSettingValue):
"""Background color of the tabbar."""
default = "grey"
class TabSelectedBgColor(ColorSettingValue):
"""Background color of the tabbar for the selected tab."""
default = "black"
class TabSeperatorColor(ColorSettingValue):
"""Color for the tab seperator."""
default = "white"
class MonospaceFonts(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(FontSettingValue):
"""Font used in the completion widget."""
default = "8pt ${_monospace}"
class TabbarFont(FontSettingValue):
"""Font used in the tabbar."""
default = "8pt ${_monospace}"
class StatusbarFont(FontSettingValue):
"""Font used in the statusbar."""
default = "8pt ${_monospace}"

View File

@ -0,0 +1,162 @@
# 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/>.
"""Templates for setting options."""
import qutebrowser.commands.utils as cmdutils
class SettingValue:
"""Base class for settings. The docstring is used as a description."""
# Possible values, if they are fixed.
# Either a list of strings, or a list of (value, desc) tuples.
values = None
# Default value if user has not overriden it, as a string.
default = 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.
Args:
value: The value to transform.
Return:
The transformed value.
"""
return value
def validate(self, value):
"""Validate value against possible values.
The default implementation checks the value against self.values if it
was defined.
Args:
value: The value to validate.
Return:
Ture if validation succeeded, False otherwise.
Raise:
NotImplementedError if self.values is not defined and this method
should be overridden.
"""
if self.values is not None:
return value in self.values
else:
raise NotImplementedError
class BoolSettingValue(SettingValue):
"""Base class for a boolean setting."""
values = ['true', 'false']
# 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, value):
return value.lower() in self._BOOLEAN_STATES
class IntSettingValue(SettingValue):
"""Base class for an integer setting."""
def transform(self, value):
return int(value)
def validate(self, value):
try:
int(value)
except ValueError:
return False
else:
return True
class ListSettingValue(SettingValue):
"""Base class for a (string-)list setting."""
def transform(self, value):
return value.split(',')
def validate(self, value):
return True
class IntListSettingValue(ListSettingValue):
"""Base class for an int-list setting."""
def transform(self, value):
vals = super().transform(value)
return map(int, vals)
def validate(self, value)
try:
self.transform(value)
except ValueError:
return False
else:
return True
class CommandSettingValue(SettingValue):
"""Base class for a command value with arguments."""
values = cmdutils.cmd_dict.values()
def validate(self, value):
cp = cmdutils.CommandParser()
try:
cp.parse(value)
except cmdutils.NoSuchCommandError:
return False
else:
return True
class ColorSettingValue(SettingValue):
"""Base class for a color value."""
def validate(self, value):
# FIXME validate colors
return True
class FontSettingValue(SettingValue):
"""Base class for a font value."""
def validate(self, value):
# FIXME validate fonts
return True