Use multiple CommandParser instances

This commit is contained in:
Florian Bruhin 2014-01-20 17:20:17 +01:00
parent 46e846afb9
commit 1373b4dab2
3 changed files with 29 additions and 26 deletions

View File

@ -33,7 +33,7 @@ class QuteBrowser(QApplication):
self.mainwindow = MainWindow() self.mainwindow = MainWindow()
self.commandparser = cmdutils.CommandParser() self.commandparser = cmdutils.CommandParser()
self.keyparser = KeyParser(self.mainwindow, self.commandparser) self.keyparser = KeyParser(self.mainwindow)
self.aboutToQuit.connect(self.config.save) self.aboutToQuit.connect(self.config.save)
self.mainwindow.tabs.keypress.connect(self.keyparser.handle) self.mainwindow.tabs.keypress.connect(self.keyparser.handle)
@ -43,6 +43,8 @@ class QuteBrowser(QApplication):
self.mainwindow.status.cmd.got_cmd.connect( self.mainwindow.status.cmd.got_cmd.connect(
self.mainwindow.tabs.setFocus) self.mainwindow.tabs.setFocus)
self.commandparser.error.connect(self.mainwindow.status.disp_error) self.commandparser.error.connect(self.mainwindow.status.disp_error)
self.keyparser.commandparser.error.connect(
self.mainwindow.status.disp_error)
self.keyparser.keystring_updated.connect( self.keyparser.keystring_updated.connect(
self.mainwindow.status.txt.set_keystring) self.mainwindow.status.txt.set_keystring)

View File

@ -3,7 +3,7 @@ import re
from PyQt5.QtCore import QObject, pyqtSignal from PyQt5.QtCore import QObject, pyqtSignal
from qutebrowser.commands.utils import ArgumentCountError from qutebrowser.commands.utils import CommandParser, ArgumentCountError
class KeyParser(QObject): class KeyParser(QObject):
"""Parser for vim-like key sequences""" """Parser for vim-like key sequences"""
@ -14,15 +14,15 @@ class KeyParser(QObject):
keystring_updated = pyqtSignal(str) keystring_updated = pyqtSignal(str)
# Keybindings # Keybindings
bindings = {} bindings = {}
cmdparser = None commandparser = None
MATCH_PARTIAL = 0 MATCH_PARTIAL = 0
MATCH_DEFINITIVE = 1 MATCH_DEFINITIVE = 1
MATCH_NONE = 2 MATCH_NONE = 2
def __init__(self, mainwindow, commandparser): def __init__(self, mainwindow):
super().__init__(mainwindow) super().__init__(mainwindow)
self.cmdparser = commandparser self.commandparser = CommandParser()
def from_config_sect(self, sect): def from_config_sect(self, sect):
"""Loads keybindings from a ConfigParser section, in the config format """Loads keybindings from a ConfigParser section, in the config format
@ -88,15 +88,15 @@ class KeyParser(QObject):
# If we get a ValueError (invalid cmd) here, something is very wrong, # If we get a ValueError (invalid cmd) here, something is very wrong,
# so we don't catch it # so we don't catch it
(cmd, args) = self.cmdparser.parse(cmdstr_hay) self.commandparser.parse(cmdstr_hay)
try: try:
self.cmdparser.check(cmd, args) self.commandparser.check()
except ArgumentCountError: except ArgumentCountError:
logging.debug('Filling statusbar with partial command {}'.format( logging.debug('Filling statusbar with partial command {}'.format(
cmdstr_hay)) cmdstr_hay))
self.set_cmd_text.emit(':{} '.format(cmdstr_hay)) self.set_cmd_text.emit(':{} '.format(cmdstr_hay))
return return
self.cmdparser.run(cmd, args, count=count) self.commandparser.run(count=count)
def _match_key(self, cmdstr_needle): def _match_key(self, cmdstr_needle):
"""Tries to match a given cmdstr with any defined command""" """Tries to match a given cmdstr with any defined command"""

View File

@ -23,16 +23,16 @@ def register_all():
cmd_dict[obj.name] = obj cmd_dict[obj.name] = obj
class CommandParser(QObject): class CommandParser(QObject):
# FIXME
#
# this should work differently somehow, e.g. more than one instance, and
# remember args/cmd in between.
"""Parser for qutebrowser commandline commands""" """Parser for qutebrowser commandline commands"""
text = ''
cmd = ''
args = []
error = pyqtSignal(str) # Emitted if there's an error error = pyqtSignal(str) # Emitted if there's an error
def parse(self, text): def parse(self, text):
"""Parses a command and runs its handler""" """Parses a command and runs its handler"""
parts = text.strip().split(maxsplit=1) self.text = text
parts = self.text.strip().split(maxsplit=1)
# FIXME maybe we should handle unambigious shorthands for commands # FIXME maybe we should handle unambigious shorthands for commands
# here? Or at least we should add :q for :quit. # here? Or at least we should add :q for :quit.
@ -49,28 +49,29 @@ class CommandParser(QObject):
args = shlex.split(parts[1]) args = shlex.split(parts[1])
else: else:
args = [parts[1]] args = [parts[1]]
return (cmd, args) self.cmd = cmd
self.args = args
def check(self, cmd, args): def check(self):
try: try:
cmd.check(args) self.cmd.check(self.args)
except ArgumentCountError: except ArgumentCountError:
self.error.emit("{}: invalid argument count".format(cmd)) self.error.emit("{}: invalid argument count".format(self.cmd))
raise raise
def run(self, count=None):
if count is not None:
self.cmd.run(self.args, count=count)
else:
self.cmd.run(self.args)
def parse_check_run(self, text, count=None): def parse_check_run(self, text, count=None):
try: try:
(cmd, args) = self.parse(text) self.parse(text)
self.check(cmd, args) self.check()
except (ArgumentCountError, ValueError): except (ArgumentCountError, ValueError):
return return
self.run(cmd, args) self.run()
def run(self, cmd, args, count=None):
if count is not None:
cmd.run(args, count=count)
else:
cmd.run(args)
class Command(QObject): class Command(QObject):
"""Base skeleton for a command. See the module help for """Base skeleton for a command. See the module help for