Add cmdutils.Value instead of using count=True/win_id=True
This commit is contained in:
parent
d549d4d5e2
commit
569bb0fa09
@ -480,8 +480,9 @@ For `typing.Union` types, the given `choices` are only checked if other types
|
||||
The following arguments are supported for `@cmdutils.argument`:
|
||||
|
||||
- `flag`: Customize the short flag (`-x`) the argument will get.
|
||||
- `win_id=True`: Mark the argument as special window ID argument.
|
||||
- `count=True`: Mark the argument as special count argument.
|
||||
- `value`: Tell qutebrowser to fill the argument with special values:
|
||||
- `value=cmdutils.Value.count`: The `count` given by the user to the command.
|
||||
- `value=cmdutils.Value.win_id`: The window ID of the current window.
|
||||
- `completion`: A completion function (see `qutebrowser.completions.models.*`)
|
||||
to use when completing arguments for the given command.
|
||||
- `choices`: The allowed string choices for the argument.
|
||||
|
@ -21,9 +21,12 @@
|
||||
|
||||
import inspect
|
||||
import typing
|
||||
import enum
|
||||
|
||||
from qutebrowser.utils import qtutils
|
||||
from qutebrowser.commands import command, cmdexc
|
||||
# pylint: disable=unused-import
|
||||
from qutebrowser.utils.usertypes import CommandValue as Value
|
||||
|
||||
|
||||
class CommandError(cmdexc.Error):
|
||||
|
@ -230,7 +230,7 @@ class CommandDispatcher:
|
||||
tabbar.setSelectionBehaviorOnRemove(old_selection_behavior)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_close(self, prev=False, next_=False, opposite=False,
|
||||
force=False, count=None):
|
||||
"""Close the current/[count]th tab.
|
||||
@ -253,7 +253,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
name='tab-pin')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_pin(self, count=None):
|
||||
"""Pin/Unpin the current/[count]th tab.
|
||||
|
||||
@ -274,7 +274,7 @@ class CommandDispatcher:
|
||||
@cmdutils.register(instance='command-dispatcher', name='open',
|
||||
maxsplit=0, scope='window')
|
||||
@cmdutils.argument('url', completion=urlmodel.url)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def openurl(self, url=None, related=False,
|
||||
bg=False, tab=False, window=False, count=None, secure=False,
|
||||
private=False):
|
||||
@ -372,7 +372,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', name='reload',
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def reloadpage(self, force=False, count=None):
|
||||
"""Reload the current/[count]th tab.
|
||||
|
||||
@ -385,7 +385,7 @@ class CommandDispatcher:
|
||||
tab.reload(force=force)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def stop(self, count=None):
|
||||
"""Stop loading in the current/[count]th tab.
|
||||
|
||||
@ -423,7 +423,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', name='print',
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
@cmdutils.argument('pdf', flag='f', metavar='file')
|
||||
def printpage(self, preview=False, count=None, *, pdf=None):
|
||||
"""Print the current/[count]th tab.
|
||||
@ -514,7 +514,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('win_id', completion=miscmodels.window)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_give(self, win_id: int = None, keep: bool = False,
|
||||
count: int = None) -> None:
|
||||
"""Give the current tab to a new or existing window if win_id given.
|
||||
@ -575,7 +575,7 @@ class CommandDispatcher:
|
||||
raise cmdutils.CommandError(e)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def back(self, tab=False, bg=False, window=False, count=1):
|
||||
"""Go back in the history of the current tab.
|
||||
|
||||
@ -588,7 +588,7 @@ class CommandDispatcher:
|
||||
self._back_forward(tab, bg, window, count, forward=False)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def forward(self, tab=False, bg=False, window=False, count=1):
|
||||
"""Go forward in the history of the current tab.
|
||||
|
||||
@ -603,7 +603,7 @@ class CommandDispatcher:
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('where', choices=['prev', 'next', 'up', 'increment',
|
||||
'decrement'])
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def navigate(self, where: str, tab: bool = False, bg: bool = False,
|
||||
window: bool = False, count: int = 1) -> None:
|
||||
"""Open typical prev/next links or navigate using the URL path.
|
||||
@ -668,7 +668,7 @@ class CommandDispatcher:
|
||||
raise cmdutils.CommandError(e)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def scroll_px(self, dx: int, dy: int, count: int = 1) -> None:
|
||||
"""Scroll the current tab by 'count * dx/dy' pixels.
|
||||
|
||||
@ -684,7 +684,7 @@ class CommandDispatcher:
|
||||
self._current_widget().scroller.delta(dx, dy)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def scroll(self, direction: str, count: int = 1) -> None:
|
||||
"""Scroll the current tab in the given direction.
|
||||
|
||||
@ -721,7 +721,7 @@ class CommandDispatcher:
|
||||
func(count=count)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
@cmdutils.argument('horizontal', flag='x')
|
||||
def scroll_to_perc(self, perc: float = None, horizontal: bool = False,
|
||||
count: int = None) -> None:
|
||||
@ -762,7 +762,7 @@ class CommandDispatcher:
|
||||
self._current_widget().scroller.to_anchor(name)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
@cmdutils.argument('top_navigate', metavar='ACTION',
|
||||
choices=('prev', 'decrement'))
|
||||
@cmdutils.argument('bottom_navigate', metavar='ACTION',
|
||||
@ -891,7 +891,7 @@ class CommandDispatcher:
|
||||
maybe=True)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def zoom_in(self, count=1, quiet=False):
|
||||
"""Increase the zoom level for the current tab.
|
||||
|
||||
@ -908,7 +908,7 @@ class CommandDispatcher:
|
||||
message.info("Zoom level: {}%".format(int(perc)), replace=True)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def zoom_out(self, count=1, quiet=False):
|
||||
"""Decrease the zoom level for the current tab.
|
||||
|
||||
@ -925,7 +925,7 @@ class CommandDispatcher:
|
||||
message.info("Zoom level: {}%".format(int(perc)), replace=True)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def zoom(self, zoom=None, count=None, quiet=False):
|
||||
"""Set the zoom level for the current tab.
|
||||
|
||||
@ -1005,7 +1005,7 @@ class CommandDispatcher:
|
||||
raise cmdutils.CommandError("Nothing to undo!")
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_prev(self, count=1):
|
||||
"""Switch to the previous tab, or switch [count] tabs back.
|
||||
|
||||
@ -1025,7 +1025,7 @@ class CommandDispatcher:
|
||||
log.webview.debug("First tab")
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_next(self, count=1):
|
||||
"""Switch to the next tab, or switch [count] tabs forward.
|
||||
|
||||
@ -1093,7 +1093,7 @@ class CommandDispatcher:
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
maxsplit=0)
|
||||
@cmdutils.argument('index', completion=miscmodels.buffer)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def buffer(self, index=None, count=None):
|
||||
"""Select tab by index or url/title best match.
|
||||
|
||||
@ -1123,7 +1123,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('index', choices=['last'])
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_focus(self, index: typing.Union[str, int] = None,
|
||||
count: int = None, no_last: bool = False) -> None:
|
||||
"""Select the tab given as argument/[count].
|
||||
@ -1165,7 +1165,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('index', choices=['+', '-'])
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_move(self, index: typing.Union[str, int] = None,
|
||||
count: int = None) -> None:
|
||||
"""Move the current tab according to the argument and [count].
|
||||
@ -1212,7 +1212,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
maxsplit=0, no_replace_variables=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def spawn(self, cmdline, userscript=False, verbose=False,
|
||||
output=False, detach=False, count=None):
|
||||
"""Spawn a command in a shell.
|
||||
@ -1830,7 +1830,7 @@ class CommandDispatcher:
|
||||
tab.search.search(text, **options)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def search_next(self, count=1):
|
||||
"""Continue the search to the ([count]th) next term.
|
||||
|
||||
@ -1864,7 +1864,7 @@ class CommandDispatcher:
|
||||
tab.search.next_result(result_cb=cb)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def search_prev(self, count=1):
|
||||
"""Continue the search to the ([count]th) previous term.
|
||||
|
||||
@ -1899,7 +1899,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_next_line(self, count=1):
|
||||
"""Move the cursor or selection to the next line.
|
||||
|
||||
@ -1910,7 +1910,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_prev_line(self, count=1):
|
||||
"""Move the cursor or selection to the prev line.
|
||||
|
||||
@ -1921,7 +1921,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_next_char(self, count=1):
|
||||
"""Move the cursor or selection to the next char.
|
||||
|
||||
@ -1932,7 +1932,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_prev_char(self, count=1):
|
||||
"""Move the cursor or selection to the previous char.
|
||||
|
||||
@ -1943,7 +1943,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_end_of_word(self, count=1):
|
||||
"""Move the cursor or selection to the end of the word.
|
||||
|
||||
@ -1954,7 +1954,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_next_word(self, count=1):
|
||||
"""Move the cursor or selection to the next word.
|
||||
|
||||
@ -1965,7 +1965,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_prev_word(self, count=1):
|
||||
"""Move the cursor or selection to the previous word.
|
||||
|
||||
@ -1988,7 +1988,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_start_of_next_block(self, count=1):
|
||||
"""Move the cursor or selection to the start of next block.
|
||||
|
||||
@ -1999,7 +1999,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_start_of_prev_block(self, count=1):
|
||||
"""Move the cursor or selection to the start of previous block.
|
||||
|
||||
@ -2010,7 +2010,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_end_of_next_block(self, count=1):
|
||||
"""Move the cursor or selection to the end of next block.
|
||||
|
||||
@ -2021,7 +2021,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', modes=[KeyMode.caret],
|
||||
scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def move_to_end_of_prev_block(self, count=1):
|
||||
"""Move the cursor or selection to the end of previous block.
|
||||
|
||||
@ -2056,7 +2056,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
debug=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def debug_webaction(self, action, count=1):
|
||||
"""Execute a webaction.
|
||||
|
||||
@ -2256,7 +2256,7 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
name='tab-mute')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def tab_mute(self, count=None):
|
||||
"""Mute/Unmute the current/[count]th tab.
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ class DownloadModel(QAbstractListModel):
|
||||
raise cmdutils.CommandError("There's no download {}!".format(count))
|
||||
|
||||
@cmdutils.register(instance='download-model', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def download_cancel(self, all_=False, count=0):
|
||||
"""Cancel the last/[count]th download.
|
||||
|
||||
@ -1039,7 +1039,7 @@ class DownloadModel(QAbstractListModel):
|
||||
download.cancel()
|
||||
|
||||
@cmdutils.register(instance='download-model', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def download_delete(self, count=0):
|
||||
"""Delete the last/[count]th download from disk.
|
||||
|
||||
@ -1060,7 +1060,7 @@ class DownloadModel(QAbstractListModel):
|
||||
log.downloads.debug("deleted download {}".format(download))
|
||||
|
||||
@cmdutils.register(instance='download-model', scope='window', maxsplit=0)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def download_open(self, cmdline: str = None, count: int = 0) -> None:
|
||||
"""Open the last/[count]th download.
|
||||
|
||||
@ -1086,7 +1086,7 @@ class DownloadModel(QAbstractListModel):
|
||||
download.open_file(cmdline)
|
||||
|
||||
@cmdutils.register(instance='download-model', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def download_retry(self, count=0):
|
||||
"""Retry the first failed/[count]th download.
|
||||
|
||||
@ -1121,7 +1121,7 @@ class DownloadModel(QAbstractListModel):
|
||||
download.remove()
|
||||
|
||||
@cmdutils.register(instance='download-model', scope='window')
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def download_remove(self, all_=False, count=0):
|
||||
"""Remove the last/[count]th download from the list.
|
||||
|
||||
|
@ -37,18 +37,13 @@ class ArgInfo:
|
||||
|
||||
"""Information about an argument."""
|
||||
|
||||
win_id = attr.ib(False)
|
||||
count = attr.ib(False)
|
||||
value = attr.ib(None)
|
||||
hide = attr.ib(False)
|
||||
metavar = attr.ib(None)
|
||||
flag = attr.ib(None)
|
||||
completion = attr.ib(None)
|
||||
choices = attr.ib(None)
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
if self.win_id and self.count:
|
||||
raise TypeError("Argument marked as both count/win_id!")
|
||||
|
||||
|
||||
class Command:
|
||||
|
||||
@ -116,7 +111,6 @@ class Command:
|
||||
self.parser.add_argument('-h', '--help', action=argparser.HelpAction,
|
||||
default=argparser.SUPPRESS, nargs=0,
|
||||
help=argparser.SUPPRESS)
|
||||
self._check_func()
|
||||
self.opt_args = collections.OrderedDict()
|
||||
self.namespace = None
|
||||
self._count = None
|
||||
@ -130,6 +124,7 @@ class Command:
|
||||
self._qute_args = getattr(self.handler, 'qute_args', {})
|
||||
self.handler.qute_args = None
|
||||
|
||||
self._check_func()
|
||||
self._inspect_func()
|
||||
|
||||
def _check_prerequisites(self, win_id):
|
||||
@ -154,9 +149,14 @@ class Command:
|
||||
def _check_func(self):
|
||||
"""Make sure the function parameters don't violate any rules."""
|
||||
signature = inspect.signature(self.handler)
|
||||
if 'self' in signature.parameters and self._instance is None:
|
||||
raise TypeError("{} is a class method, but instance was not "
|
||||
"given!".format(self.name[0]))
|
||||
if 'self' in signature.parameters:
|
||||
if self._instance is None:
|
||||
raise TypeError("{} is a class method, but instance was not "
|
||||
"given!".format(self.name[0]))
|
||||
arg_info = self.get_arg_info(signature.parameters['self'])
|
||||
if arg_info.value is not None:
|
||||
raise TypeError("{}: Can't fill 'self' with value!"
|
||||
.format(self.name))
|
||||
elif 'self' not in signature.parameters and self._instance is not None:
|
||||
raise TypeError("{} is not a class method, but instance was "
|
||||
"given!".format(self.name[0]))
|
||||
@ -186,13 +186,18 @@ class Command:
|
||||
True if the parameter is special, False otherwise.
|
||||
"""
|
||||
arg_info = self.get_arg_info(param)
|
||||
if arg_info.count:
|
||||
if arg_info.value is None:
|
||||
return False
|
||||
elif arg_info.value == usertypes.CommandValue.count:
|
||||
if param.default is inspect.Parameter.empty:
|
||||
raise TypeError("{}: handler has count parameter "
|
||||
"without default!".format(self.name))
|
||||
return True
|
||||
elif arg_info.win_id:
|
||||
elif arg_info.value == usertypes.CommandValue.win_id:
|
||||
return True
|
||||
else:
|
||||
raise TypeError("{}: Invalid value={!r} for argument '{}'!"
|
||||
.format(self.name, arg_info.value, param.name))
|
||||
return False
|
||||
|
||||
def _inspect_func(self):
|
||||
@ -325,9 +330,8 @@ class Command:
|
||||
return param.annotation
|
||||
elif param.default not in [None, inspect.Parameter.empty]:
|
||||
return type(param.default)
|
||||
elif arginfo.count or arginfo.win_id or param.kind in [
|
||||
inspect.Parameter.VAR_POSITIONAL,
|
||||
inspect.Parameter.VAR_KEYWORD]:
|
||||
elif arginfo.value or param.kind in [inspect.Parameter.VAR_POSITIONAL,
|
||||
inspect.Parameter.VAR_KEYWORD]:
|
||||
return None
|
||||
else:
|
||||
return str
|
||||
@ -447,15 +451,13 @@ class Command:
|
||||
# Special case for 'self'.
|
||||
self._get_self_arg(win_id, param, args)
|
||||
continue
|
||||
elif arg_info.count:
|
||||
# Special case for count parameter.
|
||||
elif arg_info.value == usertypes.CommandValue.count:
|
||||
self._get_count_arg(param, args, kwargs)
|
||||
continue
|
||||
# elif arg_info.win_id:
|
||||
elif arg_info.win_id:
|
||||
# Special case for win_id parameter.
|
||||
elif arg_info.value == usertypes.CommandValue.win_id:
|
||||
self._get_win_id_arg(win_id, param, args, kwargs)
|
||||
continue
|
||||
|
||||
value = self._get_param_value(param)
|
||||
if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:
|
||||
args.append(value)
|
||||
|
@ -79,7 +79,7 @@ class ConfigCommands:
|
||||
@cmdutils.register(instance='config-commands')
|
||||
@cmdutils.argument('option', completion=configmodel.option)
|
||||
@cmdutils.argument('value', completion=configmodel.value)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('pattern', flag='u')
|
||||
def set(self, win_id, option=None, value=None, temp=False, print_=False,
|
||||
*, pattern=None):
|
||||
@ -127,7 +127,7 @@ class ConfigCommands:
|
||||
@cmdutils.register(instance='config-commands', maxsplit=1,
|
||||
no_cmd_split=True, no_replace_variables=True)
|
||||
@cmdutils.argument('command', completion=configmodel.bind)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
def bind(self, win_id, key=None, command=None, *, mode='normal',
|
||||
default=False):
|
||||
"""Bind a key to a command.
|
||||
|
@ -45,7 +45,7 @@ class MacroRecorder:
|
||||
self._last_register = None
|
||||
|
||||
@cmdutils.register(instance='macro-recorder', name='record-macro')
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
def record_macro_command(self, win_id, register=None):
|
||||
"""Start or stop recording a macro.
|
||||
|
||||
@ -70,8 +70,8 @@ class MacroRecorder:
|
||||
self._recording_macro = register
|
||||
|
||||
@cmdutils.register(instance='macro-recorder', name='run-macro')
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def run_macro_command(self, win_id, count=1, register=None):
|
||||
"""Run a recorded macro.
|
||||
|
||||
|
@ -115,7 +115,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
|
||||
|
||||
@cmdutils.register(instance='status-command', name='set-cmd-text',
|
||||
scope='window', maxsplit=0)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def set_cmd_text_command(self, text, count=None, space=False, append=False,
|
||||
run_on_count=False):
|
||||
"""Preset the statusbar to some text.
|
||||
|
@ -508,7 +508,7 @@ class SessionManager(QObject):
|
||||
|
||||
@cmdutils.register(instance='session-manager')
|
||||
@cmdutils.argument('name', completion=miscmodels.session)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('with_private', flag='p')
|
||||
def session_save(self, name: typing.Union[str, Sentinel] = default,
|
||||
current: bool = False,
|
||||
|
@ -44,7 +44,7 @@ from qutebrowser.qt import sip
|
||||
|
||||
|
||||
@cmdutils.register(maxsplit=1, no_cmd_split=True, no_replace_variables=True)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
def later(ms: int, command: str, win_id: int) -> None:
|
||||
"""Execute a command after some time.
|
||||
|
||||
@ -74,8 +74,8 @@ def later(ms: int, command: str, win_id: int) -> None:
|
||||
|
||||
|
||||
@cmdutils.register(maxsplit=1, no_cmd_split=True, no_replace_variables=True)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def repeat(times: int, command: str, win_id: int, count: int = None) -> None:
|
||||
"""Repeat a given command.
|
||||
|
||||
@ -95,8 +95,8 @@ def repeat(times: int, command: str, win_id: int, count: int = None) -> None:
|
||||
|
||||
|
||||
@cmdutils.register(maxsplit=1, no_cmd_split=True, no_replace_variables=True)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def run_with_count(count_arg: int, command: str, win_id: int,
|
||||
count: int = 1) -> None:
|
||||
"""Run a command with the given count.
|
||||
@ -122,7 +122,7 @@ def message_error(text):
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def message_info(text, count=1):
|
||||
"""Show an info message in the statusbar.
|
||||
|
||||
@ -288,8 +288,8 @@ def debug_set_fake_clipboard(s=None):
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def repeat_command(win_id, count=None):
|
||||
"""Repeat the last executed command.
|
||||
|
||||
@ -358,7 +358,7 @@ def debug_log_filter(filters: str) -> None:
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('current_win_id', win_id=True)
|
||||
@cmdutils.argument('current_win_id', value=cmdutils.Value.win_id)
|
||||
def window_only(current_win_id):
|
||||
"""Close all windows except for the current one."""
|
||||
for win_id, window in objreg.window_registry.items():
|
||||
@ -377,7 +377,7 @@ def nop():
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
def version(win_id, paste=False):
|
||||
"""Show version information.
|
||||
|
||||
|
@ -256,6 +256,14 @@ MessageLevel = enum.Enum('MessageLevel', ['error', 'warning', 'info'])
|
||||
IgnoreCase = enum.Enum('IgnoreCase', ['smart', 'never', 'always'])
|
||||
|
||||
|
||||
class CommandValue(enum.Enum):
|
||||
|
||||
"""Special values which are injected when running a command handler."""
|
||||
|
||||
count = 1
|
||||
win_id = 2
|
||||
|
||||
|
||||
class Question(QObject):
|
||||
|
||||
"""A question asked to the user, e.g. via the status bar.
|
||||
|
@ -190,23 +190,39 @@ class TestRegister:
|
||||
|
||||
def test_win_id(self):
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
def fun(win_id):
|
||||
"""Blah."""
|
||||
assert objects.commands['fun']._get_call_args(42) == ([42], {})
|
||||
|
||||
def test_count(self):
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def fun(count=0):
|
||||
"""Blah."""
|
||||
assert objects.commands['fun']._get_call_args(42) == ([0], {})
|
||||
|
||||
def test_fill_self(self):
|
||||
with pytest.raises(TypeError, match="fun: Can't fill 'self' with "
|
||||
"value!"):
|
||||
@cmdutils.register(instance='foobar')
|
||||
@cmdutils.argument('self', value=cmdutils.Value.count)
|
||||
def fun(self):
|
||||
"""Blah."""
|
||||
|
||||
def test_fill_invalid(self):
|
||||
with pytest.raises(TypeError, match="fun: Invalid value='foo' for "
|
||||
"argument 'arg'!"):
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('arg', value='foo')
|
||||
def fun(arg):
|
||||
"""Blah."""
|
||||
|
||||
def test_count_without_default(self):
|
||||
with pytest.raises(TypeError, match="fun: handler has count parameter "
|
||||
"without default!"):
|
||||
@cmdutils.register()
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def fun(count):
|
||||
"""Blah."""
|
||||
|
||||
@ -344,6 +360,17 @@ class TestArgument:
|
||||
}
|
||||
assert fun.qute_args == expected
|
||||
|
||||
def test_arginfo_boolean(self):
|
||||
@cmdutils.argument('special1', value=cmdutils.Value.count)
|
||||
@cmdutils.argument('special2', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('normal')
|
||||
def fun(special1, special2, normal):
|
||||
"""Blah."""
|
||||
|
||||
assert fun.qute_args['special1'].value
|
||||
assert fun.qute_args['special2'].value
|
||||
assert not fun.qute_args['normal'].value
|
||||
|
||||
def test_wrong_order(self):
|
||||
"""When @cmdutils.argument is used above (after) @register, fail."""
|
||||
with pytest.raises(ValueError, match=r"@cmdutils.argument got called "
|
||||
@ -353,13 +380,6 @@ class TestArgument:
|
||||
def fun(bar):
|
||||
"""Blah."""
|
||||
|
||||
def test_count_and_win_id_same_arg(self):
|
||||
with pytest.raises(TypeError,
|
||||
match="Argument marked as both count/win_id!"):
|
||||
@cmdutils.argument('arg', count=True, win_id=True)
|
||||
def fun(arg=0):
|
||||
"""Blah."""
|
||||
|
||||
def test_no_docstring(self, caplog):
|
||||
with caplog.at_level(logging.WARNING):
|
||||
@cmdutils.register()
|
||||
|
@ -112,12 +112,12 @@ def cmdutils_patch(monkeypatch, stubs, miscmodels_patch):
|
||||
"""docstring."""
|
||||
|
||||
@cmdutils.argument('url', completion=miscmodels_patch.url)
|
||||
@cmdutils.argument('count', count=True)
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
def openurl(url=None, related=False, bg=False, tab=False, window=False,
|
||||
count=None):
|
||||
"""docstring."""
|
||||
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
|
||||
@cmdutils.argument('command', completion=miscmodels_patch.command)
|
||||
def bind(key, win_id, command=None, *, mode='normal'):
|
||||
"""docstring."""
|
||||
|
Loading…
Reference in New Issue
Block a user