Refactor command handling file layout

This commit is contained in:
Florian Bruhin 2014-01-29 06:28:21 +01:00
parent f5af700f1c
commit 8dcdae00b9
5 changed files with 80 additions and 72 deletions

View File

@ -17,7 +17,7 @@ A command class can set the following properties:
desc -- Description of the command
"""
from qutebrowser.commands.utils import Command
from qutebrowser.commands.template import Command
class Open(Command):

View File

@ -0,0 +1,12 @@
"""Exception classes for commands.utils and commands.template.
Defined here to avoid circular dependency hell.
"""
class NoSuchCommandError(ValueError):
pass
class ArgumentCountError(TypeError):
pass

View File

@ -90,12 +90,12 @@ class KeyParser(QObject):
try:
self.commandparser.run(cmdstr_hay, count=count, ignore_exc=False)
except NoSuchCommandError:
return
pass
except ArgumentCountError:
logging.debug('Filling statusbar with partial command {}'.format(
cmdstr_hay))
self.set_cmd_text.emit(cmdstr_hay + ' ')
return
return
def _match_key(self, cmdstr_needle):
"""Tries to match a given cmdstr with any defined command"""

View File

@ -0,0 +1,62 @@
import logging
from PyQt5.QtCore import QObject, pyqtSignal
from qutebrowser.commands.exceptions import ArgumentCountError
class Command(QObject):
"""Base skeleton for a command. See the module help for
qutebrowser.commands.commands for details.
"""
# FIXME:
# we should probably have some kind of typing / argument casting for args
# this might be combined with help texts or so as well
nargs = 0
name = None
mainname = None
signal = None
count = False
split_args = True
signal = pyqtSignal(tuple)
hide = False
desc = "" # FIXME add descriptions everywhere
def __init__(self):
super().__init__()
if self.name is None:
self.name = self.__class__.__name__.lower()
if isinstance(self.name, str):
self.mainname = self.name
else:
self.mainname = self.name[0]
def check(self, args):
"""Check if the argument count is valid. Raise ArgumentCountError if
not.
"""
if ((isinstance(self.nargs, int) and len(args) != self.nargs) or
(self.nargs == '?' and len(args) > 1) or
(self.nargs == '+' and len(args) < 1)):
# for nargs == '*', anything is okay
raise ArgumentCountError
def run(self, args=None, count=None):
"""Runs the command.
args -- Arguments to the command.
count -- Command repetition count.
"""
dbgout = ["command called:", self.mainname]
if args:
dbgout += args
if count is not None:
dbgout.append("(count={})".format(count))
logging.debug(' '.join(dbgout))
argv = [self.mainname]
if args is not None:
argv += args
self.signal.emit((count, argv))

View File

@ -1,29 +1,20 @@
"""Various command utils and the Command base class"""
import inspect
import logging
import shlex
from PyQt5.QtCore import QObject, pyqtSignal
import qutebrowser.commands
from qutebrowser.commands.exceptions import (ArgumentCountError,
NoSuchCommandError)
from qutebrowser.utils.completion import CompletionModel
cmd_dict = {}
class ArgumentCountError(TypeError):
pass
class NoSuchCommandError(ValueError):
pass
def register_all():
"""Register and initialize all commands."""
# We do this here to avoid a circular import, since commands.commands
# imports Command from this module.
import qutebrowser.commands
for (name, cls) in inspect.getmembers( # pylint: disable=unused-variable
qutebrowser.commands, (lambda o: inspect.isclass(o) and
o.__module__ == 'qutebrowser.commands')):
@ -108,60 +99,3 @@ class CommandCompletionModel(CompletionModel):
cmdlist.append([obj.mainname, obj.desc])
self._data['Commands'] = sorted(cmdlist)
self.init_data()
class Command(QObject):
"""Base skeleton for a command. See the module help for
qutebrowser.commands.commands for details.
"""
# FIXME:
# we should probably have some kind of typing / argument casting for args
# this might be combined with help texts or so as well
nargs = 0
name = None
mainname = None
signal = None
count = False
split_args = True
signal = pyqtSignal(tuple)
hide = False
desc = "" # FIXME add descriptions everywhere
def __init__(self):
super().__init__()
if self.name is None:
self.name = self.__class__.__name__.lower()
if isinstance(self.name, str):
self.mainname = self.name
else:
self.mainname = self.name[0]
def check(self, args):
"""Check if the argument count is valid. Raise ArgumentCountError if
not.
"""
if ((isinstance(self.nargs, int) and len(args) != self.nargs) or
(self.nargs == '?' and len(args) > 1) or
(self.nargs == '+' and len(args) < 1)):
# for nargs == '*', anything is okay
raise ArgumentCountError
def run(self, args=None, count=None):
"""Runs the command.
args -- Arguments to the command.
count -- Command repetition count.
"""
dbgout = ["command called:", self.mainname]
if args:
dbgout += args
if count is not None:
dbgout.append("(count={})".format(count))
logging.debug(' '.join(dbgout))
argv = [self.mainname]
if args is not None:
argv += args
self.signal.emit((count, argv))