Use @cmdutils.argument for completions

This commit is contained in:
Florian Bruhin 2016-05-10 23:04:52 +02:00
parent 3ab40bbc23
commit c33f0c3512
8 changed files with 41 additions and 45 deletions

View File

@ -453,6 +453,7 @@ The following arguments are supported for `@cmdutils.argument`:
- `win_id=True`: Mark the argument as special window ID argument - `win_id=True`: Mark the argument as special window ID argument
- `count=True`: Mark the argument as special count argument - `count=True`: Mark the argument as special count argument
- `hide=True`: Hide the argument from the documentation - `hide=True`: Hide the argument from the documentation
- `completion`: A `usertypes.Completion` member to use as completion.
The name of an argument will always be the parameter name, with any trailing The name of an argument will always be the parameter name, with any trailing
underscores stripped. underscores stripped.

View File

@ -722,8 +722,8 @@ class Quitter:
# segfaults. # segfaults.
QTimer.singleShot(0, functools.partial(qApp.exit, status)) QTimer.singleShot(0, functools.partial(qApp.exit, status))
@cmdutils.register(instance='quitter', name='wq', @cmdutils.register(instance='quitter', name='wq')
completion=[usertypes.Completion.sessions]) @cmdutils.argument('name', completion=usertypes.Completion.sessions)
def save_and_quit(self, name=sessions.default): def save_and_quit(self, name=sessions.default):
"""Save open pages and quit. """Save open pages and quit.

View File

@ -226,8 +226,8 @@ class CommandDispatcher:
tabbar.setSelectionBehaviorOnRemove(old_selection_behavior) tabbar.setSelectionBehaviorOnRemove(old_selection_behavior)
@cmdutils.register(instance='command-dispatcher', name='open', @cmdutils.register(instance='command-dispatcher', name='open',
maxsplit=0, scope='window', maxsplit=0, scope='window')
completion=[usertypes.Completion.url]) @cmdutils.argument('url', completion=usertypes.Completion.url)
@cmdutils.argument('count', count=True) @cmdutils.argument('count', count=True)
def openurl(self, url=None, bg=False, tab=False, window=False, count=None): def openurl(self, url=None, bg=False, tab=False, window=False, count=None):
"""Open a URL in the current/[count]th tab. """Open a URL in the current/[count]th tab.
@ -863,8 +863,8 @@ class CommandDispatcher:
raise cmdexc.CommandError(e) raise cmdexc.CommandError(e)
self._open(url, tab, bg, window) self._open(url, tab, bg, window)
@cmdutils.register(instance='command-dispatcher', scope='window', @cmdutils.register(instance='command-dispatcher', scope='window')
completion=[usertypes.Completion.tab]) @cmdutils.argument('index', completion=usertypes.Completion.tab)
def buffer(self, index): def buffer(self, index):
"""Select tab by index or url/title best match. """Select tab by index or url/title best match.
@ -1087,8 +1087,8 @@ class CommandDispatcher:
quickmark_manager.prompt_save(self._win_id, self._current_url()) quickmark_manager.prompt_save(self._win_id, self._current_url())
@cmdutils.register(instance='command-dispatcher', scope='window', @cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0, maxsplit=0)
completion=[usertypes.Completion.quickmark_by_name]) @cmdutils.argument('name', completion=usertypes.Completion.quickmark_by_name)
def quickmark_load(self, name, tab=False, bg=False, window=False): def quickmark_load(self, name, tab=False, bg=False, window=False):
"""Load a quickmark. """Load a quickmark.
@ -1118,8 +1118,8 @@ class CommandDispatcher:
"Bookmarked {}!".format(url.toDisplayString())) "Bookmarked {}!".format(url.toDisplayString()))
@cmdutils.register(instance='command-dispatcher', scope='window', @cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0, maxsplit=0)
completion=[usertypes.Completion.bookmark_by_url]) @cmdutils.argument('url', completion=usertypes.Completion.bookmark_by_url)
def bookmark_load(self, url, tab=False, bg=False, window=False): def bookmark_load(self, url, tab=False, bg=False, window=False):
"""Load a bookmark. """Load a bookmark.
@ -1303,8 +1303,8 @@ class CommandDispatcher:
message.info(self._win_id, "Dumped page to {}.".format(dest)) message.info(self._win_id, "Dumped page to {}.".format(dest))
@cmdutils.register(instance='command-dispatcher', name='help', @cmdutils.register(instance='command-dispatcher', name='help',
completion=[usertypes.Completion.helptopic],
scope='window') scope='window')
@cmdutils.argument('topic', completion=usertypes.Completion.helptopic)
def show_help(self, tab=False, bg=False, window=False, topic=None): def show_help(self, tab=False, bg=False, window=False, topic=None):
r"""Show help about a command or setting. r"""Show help about a command or setting.

View File

@ -204,8 +204,8 @@ class QuickmarkManager(UrlMarkManager):
else: else:
set_mark() set_mark()
@cmdutils.register(instance='quickmark-manager', maxsplit=0, @cmdutils.register(instance='quickmark-manager', maxsplit=0)
completion=[usertypes.Completion.quickmark_by_name]) @cmdutils.argument('name', completion=usertypes.Completion.quickmark_by_name)
def quickmark_del(self, name): def quickmark_del(self, name):
"""Delete a quickmark. """Delete a quickmark.
@ -284,8 +284,8 @@ class BookmarkManager(UrlMarkManager):
self.changed.emit() self.changed.emit()
self.added.emit(title, urlstr) self.added.emit(title, urlstr)
@cmdutils.register(instance='bookmark-manager', maxsplit=0, @cmdutils.register(instance='bookmark-manager', maxsplit=0)
completion=[usertypes.Completion.bookmark_by_url]) @cmdutils.argument('url', completion=usertypes.Completion.bookmark_by_url)
def bookmark_del(self, url): def bookmark_del(self, url):
"""Delete a bookmark. """Delete a bookmark.

View File

@ -40,7 +40,7 @@ class ArgInfo:
"""Information about an argument.""" """Information about an argument."""
def __init__(self, win_id=False, count=False, flag=None, hide=False, def __init__(self, win_id=False, count=False, flag=None, hide=False,
metavar=None): metavar=None, completion=None):
if win_id and count: if win_id and count:
raise TypeError("Argument marked as both count/win_id!") raise TypeError("Argument marked as both count/win_id!")
self.win_id = win_id self.win_id = win_id
@ -48,18 +48,21 @@ class ArgInfo:
self.flag = flag self.flag = flag
self.hide = hide self.hide = hide
self.metavar = metavar self.metavar = metavar
self.completion = completion
def __eq__(self, other): def __eq__(self, other):
return (self.win_id == other.win_id and return (self.win_id == other.win_id and
self.count == other.count and self.count == other.count and
self.flag == other.flag and self.flag == other.flag and
self.hide == other.hide and self.hide == other.hide and
self.metavar == other.metavar) self.metavar == other.metavar and
self.completion == other.completion)
def __repr__(self): def __repr__(self):
return utils.get_repr(self, win_id=self.win_id, count=self.count, return utils.get_repr(self, win_id=self.win_id, count=self.count,
flag=self.flag, hide=self.hide, flag=self.flag, hide=self.hide,
metavar=self.metavar, constructor=True) metavar=self.metavar, completion=self.completion,
constructor=True)
class Command: class Command:
@ -90,10 +93,9 @@ class Command:
""" """
def __init__(self, *, handler, name, instance=None, maxsplit=None, def __init__(self, *, handler, name, instance=None, maxsplit=None,
hide=False, completion=None, modes=None, not_modes=None, hide=False, modes=None, not_modes=None, needs_js=False,
needs_js=False, debug=False, ignore_args=False, debug=False, ignore_args=False, deprecated=False,
deprecated=False, no_cmd_split=False, no_cmd_split=False, star_args_optional=False, scope='global'):
star_args_optional=False, scope='global'):
# I really don't know how to solve this in a better way, I tried. # I really don't know how to solve this in a better way, I tried.
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
if modes is not None and not_modes is not None: if modes is not None and not_modes is not None:
@ -115,7 +117,6 @@ class Command:
self.hide = hide self.hide = hide
self.deprecated = deprecated self.deprecated = deprecated
self._instance = instance self._instance = instance
self.completion = completion
self._modes = modes self._modes = modes
self._not_modes = not_modes self._not_modes = not_modes
self._scope = scope self._scope = scope
@ -148,10 +149,11 @@ class Command:
args = self._inspect_func() args = self._inspect_func()
if self.completion is not None and len(self.completion) > len(args): self.completion = []
raise ValueError("Got {} completions, but only {} " for arg in args:
"arguments!".format(len(self.completion), arg_completion = self.get_arg_info(arg).completion
len(args))) if arg_completion is not None:
self.completion.append(arg_completion)
def _check_prerequisites(self, win_id): def _check_prerequisites(self, win_id):
"""Check if the command is permitted to run currently. """Check if the command is permitted to run currently.
@ -264,7 +266,7 @@ class Command:
log.commands.vdebug('Adding arg {} of type {} -> {}'.format( log.commands.vdebug('Adding arg {} of type {} -> {}'.format(
param.name, typ, callsig)) param.name, typ, callsig))
self.parser.add_argument(*args, **kwargs) self.parser.add_argument(*args, **kwargs)
return signature.parameters.keys() return signature.parameters.values()
def _param_to_argparse_kwargs(self, param, typ): def _param_to_argparse_kwargs(self, param, typ):
"""Get argparse keyword arguments for a parameter. """Get argparse keyword arguments for a parameter.

View File

@ -686,9 +686,10 @@ class ConfigManager(QObject):
raise cmdexc.CommandError("set: {} - {}".format( raise cmdexc.CommandError("set: {} - {}".format(
e.__class__.__name__, e)) e.__class__.__name__, e))
@cmdutils.register(name='set', instance='config', @cmdutils.register(name='set', instance='config')
completion=[Completion.section, Completion.option, @cmdutils.argument('section_', completion=Completion.section)
Completion.value]) @cmdutils.argument('option', completion=Completion.option)
@cmdutils.argument('value', completion=Completion.value)
@cmdutils.argument('win_id', win_id=True) @cmdutils.argument('win_id', win_id=True)
def set_command(self, win_id, section_=None, option=None, value=None, def set_command(self, win_id, section_=None, option=None, value=None,
temp=False, print_=False): temp=False, print_=False):

View File

@ -356,8 +356,8 @@ class SessionManager(QObject):
sessions.append(base) sessions.append(base)
return sessions return sessions
@cmdutils.register(completion=[usertypes.Completion.sessions], @cmdutils.register(instance='session-manager')
instance='session-manager') @cmdutils.argument('name', completion=usertypes.Completion.sessions)
def session_load(self, name, clear=False, temp=False, force=False): def session_load(self, name, clear=False, temp=False, force=False):
"""Load a session. """Load a session.
@ -384,10 +384,9 @@ class SessionManager(QObject):
for win in old_windows: for win in old_windows:
win.close() win.close()
@cmdutils.register(name=['session-save', 'w'], @cmdutils.register(name=['session-save', 'w'], instance='session-manager')
completion=[usertypes.Completion.sessions],
instance='session-manager')
@cmdutils.argument('win_id', win_id=True) @cmdutils.argument('win_id', win_id=True)
@cmdutils.argument('name', completion=usertypes.Completion.sessions)
def session_save(self, win_id, name: str=default, current=False, def session_save(self, win_id, name: str=default, current=False,
quiet=False, force=False): quiet=False, force=False):
"""Save a session. """Save a session.
@ -420,8 +419,8 @@ class SessionManager(QObject):
message.info(win_id, "Saved session {}.".format(name), message.info(win_id, "Saved session {}.".format(name),
immediately=True) immediately=True)
@cmdutils.register(completion=[usertypes.Completion.sessions], @cmdutils.register(instance='session-manager')
instance='session-manager') @cmdutils.argument('name', completion=usertypes.Completion.sessions)
def session_delete(self, name, force=False): def session_delete(self, name, force=False):
"""Delete a session. """Delete a session.

View File

@ -174,13 +174,6 @@ class TestRegister:
pass pass
assert cmdutils.cmd_dict['fun'].hide assert cmdutils.cmd_dict['fun'].hide
def test_wrong_completion_count(self):
with pytest.raises(ValueError):
@cmdutils.register(completion=['one', 'two'])
def fun(arg):
"""Blah."""
pass
def test_star_args(self): def test_star_args(self):
"""Check handling of *args.""" """Check handling of *args."""
@cmdutils.register() @cmdutils.register()