Add modes=[]/not_modes=[] to cmdutils.register

This commit is contained in:
Florian Bruhin 2014-04-25 10:10:58 +02:00
parent 2c34a016db
commit 7787a67c45
8 changed files with 50 additions and 16 deletions

2
TODO
View File

@ -79,8 +79,6 @@ catch import errors for PyQt and QtWebKit
Allow binding to empty values for keys to override defaults
How do we handle empty values in input bar?
Human-readable error messages for unknown settings / wrong interpolations / ...
- Add mode=[]/no_mode=[] to cmdutils.register so we can avoid executing
commands in the wrong mode
- Add more element-selection-detection code (with options?) based on:
-> javascript: http://stackoverflow.com/a/2848120/2085149
-> microFocusChanged and check active element via:

View File

@ -19,7 +19,8 @@
import logging
from qutebrowser.commands.exceptions import ArgumentCountError
from qutebrowser.commands.exceptions import (ArgumentCountError,
InvalidModeError)
from PyQt5.QtCore import pyqtSignal, QObject
@ -55,7 +56,7 @@ class Command(QObject):
signal = pyqtSignal(tuple)
def __init__(self, name, maxsplit, hide, nargs, count, desc, instance,
handler, completion):
handler, completion, modes, not_modes):
super().__init__()
self.name = name
self.maxsplit = maxsplit
@ -66,18 +67,27 @@ class Command(QObject):
self.instance = instance
self.handler = handler
self.completion = completion
self.modes = modes
self.not_modes = not_modes
def check(self, args):
"""Check if the argument count is valid.
Raise ArgumentCountError if not.
"""Check if the argument count is valid and the command is permitted.
Args:
args: The supplied arguments
Raise:
ArgumentCountError if the argument count is wrong.
InvalidModeError if the command can't be called in this mode.
"""
import qutebrowser.keyinput.modes as modeman
if self.modes is not None and modeman.manager.mode not in self.modes:
raise InvalidModeError("This command is only allowed in {} "
"mode.".format('/'.join(self.modes)))
elif (self.not_modes is not None and
modeman.manager.mode in self.not_modes):
raise InvalidModeError("This command is not allowed in {} "
"mode.".format('/'.join(self.not_modes)))
if self.nargs[1] is None and self.nargs[0] <= len(args):
pass
elif self.nargs[0] <= len(args) <= self.nargs[1]:

View File

@ -33,3 +33,10 @@ class ArgumentCountError(TypeError):
"""Raised when a command was called with an invalid count of arguments."""
pass
class InvalidModeError(Exception):
"""Raised when a command is called in a wrong input mode."""
pass

View File

@ -24,7 +24,7 @@ import qutebrowser.config.config as config
import qutebrowser.commands.utils as cmdutils
import qutebrowser.utils.message as message
from qutebrowser.commands.exceptions import (ArgumentCountError,
NoSuchCommandError)
NoSuchCommandError, InvalidModeError)
def split_cmdline(text):
@ -202,6 +202,7 @@ class CommandParser:
NoSuchCommandError: if a command wasn't found.
ArgumentCountError: if a command was called with the wrong count of
arguments.
InvalidModeError: if a command can't be called in this mode.
Return:
True if command was called (handler returnstatus is ignored!).
@ -228,5 +229,11 @@ class CommandParser:
return False
else:
raise
except InvalidModeError as e:
if ignore_exc:
message.error("{}: {}".format(self._cmd.name, e))
return False
else:
raise
self._run(count=count)
return True

View File

@ -47,10 +47,11 @@ class register: # pylint: disable=invalid-name
hide: Whether to hide the command or not.
completion: Which completion to use for arguments, as a list of
strings.
modes/not_modes: List of modes to use/not use.
"""
def __init__(self, instance=None, name=None, nargs=None, maxsplit=-1,
hide=False, completion=None):
hide=False, completion=None, modes=None, not_modes=None):
"""Save decorator arguments.
Gets called on parse-time with the decorator arguments.
@ -58,12 +59,16 @@ class register: # pylint: disable=invalid-name
Args:
See class attributes.
"""
if modes is not None and not_modes is not None:
raise ValueError("Only modes or not_modes can be given!")
self.name = name
self.maxsplit = maxsplit
self.hide = hide
self.nargs = nargs
self.instance = instance
self.completion = completion
self.modes = modes
self.not_modes = not_modes
def __call__(self, func):
"""Register the command before running the function.
@ -95,7 +100,8 @@ class register: # pylint: disable=invalid-name
cmd = Command(name=mainname, maxsplit=self.maxsplit,
hide=self.hide, nargs=nargs, count=count, desc=desc,
instance=self.instance, handler=func,
completion=self.completion)
completion=self.completion, modes=self.modes,
not_modes=self.not_modes)
for name in names:
cmd_dict[name] = cmd
return func

View File

@ -158,7 +158,8 @@ class ModeManager(QObject):
logging.debug("New mode stack: {}".format(self._mode_stack))
self.left.emit(mode)
@cmdutils.register(instance='modeman', name='leave_mode', hide=True)
@cmdutils.register(instance='modeman', name='leave_mode',
not_modes=['normal'], hide=True)
def leave_current_mode(self):
if self.mode == "normal":
raise ValueError("Can't leave normal mode!")

View File

@ -297,12 +297,14 @@ class CompletionView(QTreeView):
selmod.clearSelection()
selmod.clearCurrentIndex()
@cmdutils.register(instance='mainwindow.completion', hide=True)
@cmdutils.register(instance='mainwindow.completion', hide=True,
modes=['command'])
def completion_item_prev(self):
"""Select the previous completion item."""
self._next_prev_item(prev=True)
@cmdutils.register(instance='mainwindow.completion', hide=True)
@cmdutils.register(instance='mainwindow.completion', hide=True,
modes=['command'])
def completion_item_next(self):
"""Select the next completion item."""
self._next_prev_item(prev=False)

View File

@ -290,7 +290,8 @@ class _Command(QLineEdit):
self.setFocus()
self.show_cmd.emit()
@cmdutils.register(instance='mainwindow.status.cmd', hide=True)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
modes=['command'])
def command_history_prev(self):
"""Handle Up presses (go back in history)."""
try:
@ -303,7 +304,8 @@ class _Command(QLineEdit):
if item:
self.set_cmd_text(item)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
modes=['command'])
def command_history_next(self):
"""Handle Down presses (go forward in history)."""
if not self.history.browsing:
@ -315,7 +317,8 @@ class _Command(QLineEdit):
if item:
self.set_cmd_text(item)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True)
@cmdutils.register(instance='mainwindow.status.cmd', hide=True,
modes=['command'])
def command_accept(self):
"""Handle the command in the status bar.