2014-09-02 21:54:07 +02:00
|
|
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
|
|
|
|
|
|
|
# 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/>.
|
|
|
|
|
|
|
|
"""argparse.ArgumentParser subclass to parse qutebrowser commands."""
|
|
|
|
|
2014-09-03 10:47:27 +02:00
|
|
|
|
2014-09-02 21:54:07 +02:00
|
|
|
import argparse
|
|
|
|
|
2014-09-04 17:59:50 +02:00
|
|
|
from PyQt5.QtCore import QCoreApplication, QUrl
|
|
|
|
|
2014-09-03 10:47:27 +02:00
|
|
|
from qutebrowser.commands import cmdexc
|
|
|
|
from qutebrowser.utils import utils
|
|
|
|
|
2014-09-02 21:54:07 +02:00
|
|
|
|
2014-09-04 17:59:50 +02:00
|
|
|
SUPPRESS = argparse.SUPPRESS
|
|
|
|
|
|
|
|
|
2014-09-02 21:54:07 +02:00
|
|
|
class ArgumentParserError(Exception):
|
|
|
|
|
|
|
|
"""Exception raised when the ArgumentParser signals an error."""
|
|
|
|
|
|
|
|
|
2014-09-04 17:58:28 +02:00
|
|
|
class ArgumentParserExit(Exception):
|
|
|
|
|
|
|
|
"""Exception raised when the argument parser exitted."""
|
|
|
|
|
|
|
|
def __init__(self, status, msg):
|
|
|
|
self.status = status
|
|
|
|
super().__init__(msg)
|
|
|
|
|
|
|
|
|
2014-09-04 17:59:50 +02:00
|
|
|
class HelpAction(argparse.Action):
|
|
|
|
|
2014-09-05 06:57:02 +02:00
|
|
|
"""Argparse action to open the help page in the browser.
|
|
|
|
|
|
|
|
This is horrible encapsulation, but I can't think of a good way to do this
|
|
|
|
better...
|
|
|
|
"""
|
|
|
|
|
2014-09-04 17:59:50 +02:00
|
|
|
def __call__(self, parser, _namespace, _values, _option_string=None):
|
|
|
|
QCoreApplication.instance().mainwindow.tabs.tabopen(
|
|
|
|
QUrl('qute:help/commands.html#{}'.format(parser.name)))
|
|
|
|
parser.exit()
|
|
|
|
|
|
|
|
|
2014-09-02 21:54:07 +02:00
|
|
|
class ArgumentParser(argparse.ArgumentParser):
|
|
|
|
|
2014-09-03 10:47:27 +02:00
|
|
|
"""Subclass ArgumentParser to be more suitable for runtime parsing."""
|
|
|
|
|
2014-09-05 06:38:23 +02:00
|
|
|
def __init__(self, name, *args, **kwargs):
|
2014-09-04 17:59:50 +02:00
|
|
|
self.name = name
|
2014-09-05 06:38:23 +02:00
|
|
|
super().__init__(*args, add_help=False, prog=name, **kwargs)
|
2014-09-02 21:54:07 +02:00
|
|
|
|
|
|
|
def exit(self, status=0, msg=None):
|
2014-09-04 17:58:28 +02:00
|
|
|
raise ArgumentParserExit(status, msg)
|
2014-09-02 21:54:07 +02:00
|
|
|
|
|
|
|
def error(self, msg):
|
2014-09-03 10:47:27 +02:00
|
|
|
raise ArgumentParserError(msg[0].upper() + msg[1:])
|
|
|
|
|
|
|
|
|
|
|
|
def enum_getter(enum):
|
|
|
|
"""Function factory to get an enum getter."""
|
|
|
|
|
|
|
|
def _get_enum_item(key):
|
|
|
|
"""Helper function to get an enum item.
|
|
|
|
|
|
|
|
Passes through existing items unmodified.
|
|
|
|
"""
|
|
|
|
if isinstance(key, enum):
|
|
|
|
return key
|
|
|
|
try:
|
|
|
|
return enum[key.replace('-', '_')]
|
|
|
|
except KeyError:
|
|
|
|
raise cmdexc.ArgumentTypeError("Invalid value {}.".format(key))
|
|
|
|
|
|
|
|
return _get_enum_item
|
|
|
|
|
|
|
|
|
|
|
|
def multitype_conv(tpl):
|
|
|
|
"""Function factory to get a type converter for a choice of types."""
|
|
|
|
|
|
|
|
def _convert(value):
|
|
|
|
"""Convert a value according to an iterable of possible arg types."""
|
|
|
|
for typ in tpl:
|
|
|
|
if isinstance(typ, str):
|
|
|
|
if value == typ:
|
|
|
|
return value
|
|
|
|
elif utils.is_enum(typ):
|
|
|
|
return enum_getter(typ)(value)
|
|
|
|
elif callable(typ):
|
|
|
|
# int, float, etc.
|
|
|
|
if isinstance(value, typ):
|
|
|
|
return value
|
|
|
|
try:
|
|
|
|
return typ(value)
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
raise cmdexc.ArgumentTypeError('Invalid value {}.'.format(value))
|
|
|
|
|
|
|
|
return _convert
|