Move bind completion to configmodels.

When in miscmodels, the config module was unable to find the function.
It appears to be some sort of circular import issue:

```
  File "/home/rcorre/projects/contrib/qutebrowser/qutebrowser/app.py", line 44, in <module>
    from qutebrowser.completion.models import miscmodels
  File "/home/rcorre/projects/contrib/qutebrowser/qutebrowser/completion/models/miscmodels.py", line 24, in <module>
    from qutebrowser.completion.models import completionmodel, listcategory, util
  File "/home/rcorre/projects/contrib/qutebrowser/qutebrowser/completion/models/util.py", line 24, in <module>
    from qutebrowser.config import config
  File "/home/rcorre/projects/contrib/qutebrowser/qutebrowser/config/config.py", line 223, in <module>
    class ConfigCommands:
  File "/home/rcorre/projects/contrib/qutebrowser/qutebrowser/config/config.py", line 314, in ConfigCommands
    @cmdutils.argument('command', completion=miscmodels.bind)
AttributeError: module 'qutebrowser.completion.models.miscmodels' has no attribute 'bind'
```

As configmodel imports util (and thereby config as well) it is unclear
to me why moving bind() to configmodel actually fixes this, but it does.
This commit is contained in:
Ryan Roden-Corrent 2017-08-19 17:37:04 -04:00
parent 0286e9ddf2
commit 90c49b3fe7
5 changed files with 82 additions and 57 deletions

View File

@ -58,3 +58,24 @@ def value(optname, *values):
if vals is not None: if vals is not None:
model.add_category(listcategory.ListCategory("Completions", vals)) model.add_category(listcategory.ListCategory("Completions", vals))
return model return model
def bind(key):
"""A CompletionModel filled with all bindable commands and descriptions.
Args:
key: the key being bound.
"""
model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
cmd_text = config.key_instance.get_bindings_for('normal').get(key)
if cmd_text:
cmd_name = cmd_text.split(' ')[0]
cmd = cmdutils.cmd_dict.get(cmd_name)
data = [(cmd_text, cmd.desc, key)]
model.add_category(listcategory.ListCategory("Current", data))
cmdlist = util.get_cmd_completions(include_hidden=True,
include_aliases=True)
model.add_category(listcategory.ListCategory("Commands", cmdlist))
return model

View File

@ -19,16 +19,16 @@
"""Functions that return miscellaneous completion models.""" """Functions that return miscellaneous completion models."""
from qutebrowser.config import config, configdata from qutebrowser.config import configdata
from qutebrowser.utils import objreg, log from qutebrowser.utils import objreg, log
from qutebrowser.completion.models import completionmodel, listcategory from qutebrowser.completion.models import completionmodel, listcategory, util
from qutebrowser.commands import cmdutils
def command(): def command():
"""A CompletionModel filled with non-hidden commands and descriptions.""" """A CompletionModel filled with non-hidden commands and descriptions."""
model = completionmodel.CompletionModel(column_widths=(20, 60, 20)) model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
cmdlist = _get_cmd_completions(include_aliases=True, include_hidden=False) cmdlist = util.get_cmd_completions(include_aliases=True,
include_hidden=False)
model.add_category(listcategory.ListCategory("Commands", cmdlist)) model.add_category(listcategory.ListCategory("Commands", cmdlist))
return model return model
@ -37,8 +37,8 @@ def helptopic():
"""A CompletionModel filled with help topics.""" """A CompletionModel filled with help topics."""
model = completionmodel.CompletionModel() model = completionmodel.CompletionModel()
cmdlist = _get_cmd_completions(include_aliases=False, include_hidden=True, cmdlist = util.get_cmd_completions(include_aliases=False,
prefix=':') include_hidden=True, prefix=':')
settings = ((opt.name, opt.description) settings = ((opt.name, opt.description)
for opt in configdata.DATA.values()) for opt in configdata.DATA.values())
@ -122,51 +122,3 @@ def buffer():
model.add_category(cat) model.add_category(cat)
return model return model
def bind(key):
"""A CompletionModel filled with all bindable commands and descriptions.
Args:
key: the key being bound.
"""
model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
cmd_text = config.key_instance.get_bindings_for('normal').get(key)
if cmd_text:
cmd_name = cmd_text.split(' ')[0]
cmd = cmdutils.cmd_dict.get(cmd_name)
data = [(cmd_text, cmd.desc, key)]
model.add_category(listcategory.ListCategory("Current", data))
cmdlist = _get_cmd_completions(include_hidden=True, include_aliases=True)
model.add_category(listcategory.ListCategory("Commands", cmdlist))
return model
def _get_cmd_completions(include_hidden, include_aliases, prefix=''):
"""Get a list of completions info for commands, sorted by name.
Args:
include_hidden: True to include commands annotated with hide=True.
include_aliases: True to include command aliases.
prefix: String to append to the command name.
Return: A list of tuples of form (name, description, bindings).
"""
assert cmdutils.cmd_dict
cmdlist = []
cmd_to_keys = config.key_instance.get_reverse_bindings_for('normal')
for obj in set(cmdutils.cmd_dict.values()):
hide_debug = obj.debug and not objreg.get('args').debug
hide_hidden = obj.hide and not include_hidden
if not (hide_debug or hide_hidden or obj.deprecated):
bindings = ', '.join(cmd_to_keys.get(obj.name, []))
cmdlist.append((prefix + obj.name, obj.desc, bindings))
if include_aliases:
for name, cmd in config.val.aliases.items():
bindings = ', '.join(cmd_to_keys.get(name, []))
cmdlist.append((name, "Alias for '{}'".format(cmd), bindings))
return cmdlist

View File

@ -0,0 +1,52 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2017 Ryan Roden-Corrent (rcorre) <ryan@rcorre.net>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Utility functions for completion models."""
from qutebrowser.utils import objreg
from qutebrowser.commands import cmdutils
from qutebrowser.config import config
def get_cmd_completions(include_hidden, include_aliases, prefix=''):
"""Get a list of completions info for commands, sorted by name.
Args:
include_hidden: True to include commands annotated with hide=True.
include_aliases: True to include command aliases.
prefix: String to append to the command name.
Return: A list of tuples of form (name, description, bindings).
"""
assert cmdutils.cmd_dict
cmdlist = []
cmd_to_keys = config.key_instance.get_reverse_bindings_for('normal')
for obj in set(cmdutils.cmd_dict.values()):
hide_debug = obj.debug and not objreg.get('args').debug
hide_hidden = obj.hide and not include_hidden
if not (hide_debug or hide_hidden or obj.deprecated):
bindings = ', '.join(cmd_to_keys.get(obj.name, []))
cmdlist.append((prefix + obj.name, obj.desc, bindings))
if include_aliases:
for name, cmd in config.val.aliases.items():
bindings = ', '.join(cmd_to_keys.get(name, []))
cmdlist.append((name, "Alias for '{}'".format(cmd), bindings))
return cmdlist

View File

@ -29,7 +29,7 @@ from qutebrowser.config import configdata, configexc, configtypes, configfiles
from qutebrowser.utils import utils, objreg, message, log, usertypes from qutebrowser.utils import utils, objreg, message, log, usertypes
from qutebrowser.misc import objects from qutebrowser.misc import objects
from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.commands import cmdexc, cmdutils
from qutebrowser.completion.models import configmodel, miscmodels from qutebrowser.completion.models import configmodel
# An easy way to access the config from other code via config.val.foo # An easy way to access the config from other code via config.val.foo
val = None val = None
@ -311,7 +311,7 @@ class ConfigCommands:
@cmdutils.register(instance='config-commands', maxsplit=1, @cmdutils.register(instance='config-commands', maxsplit=1,
no_cmd_split=True, no_replace_variables=True) no_cmd_split=True, no_replace_variables=True)
@cmdutils.argument('command', completion=miscmodels.bind) @cmdutils.argument('command', completion=configmodel.bind)
def bind(self, key, command=None, *, mode='normal', force=False): def bind(self, key, command=None, *, mode='normal', force=False):
"""Bind a key to a command. """Bind a key to a command.

View File

@ -546,7 +546,7 @@ def test_bind_completion(qtmodeltester, cmdutils_stub, config_stub,
- the binding (if any) is shown in the misc column - the binding (if any) is shown in the misc column
- aliases are included - aliases are included
""" """
model = miscmodels.bind('ZQ') model = configmodel.bind('ZQ')
model.set_pattern('') model.set_pattern('')
qtmodeltester.data_display_may_return_none = True qtmodeltester.data_display_may_return_none = True
qtmodeltester.check(model) qtmodeltester.check(model)