Refactor completion handling
This commit is contained in:
parent
746179d87c
commit
533d82417e
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
"""Module containing command managers (SearchManager and CommandManager)."""
|
"""Module containing command managers (SearchManager and CommandManager)."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||||
from PyQt5.QtWebKitWidgets import QWebPage
|
from PyQt5.QtWebKitWidgets import QWebPage
|
||||||
|
|
||||||
@ -40,8 +42,9 @@ def split_cmdline(text):
|
|||||||
parts = manager.parse(text)
|
parts = manager.parse(text)
|
||||||
except NoSuchCommandError:
|
except NoSuchCommandError:
|
||||||
parts = text.split(' ')
|
parts = text.split(' ')
|
||||||
if text.endswith(' '):
|
if text.endswith(' '):
|
||||||
parts.append('')
|
parts.append('')
|
||||||
|
logging.debug("Split parts: {}".format(parts))
|
||||||
return parts
|
return parts
|
||||||
|
|
||||||
|
|
||||||
@ -166,10 +169,15 @@ class CommandManager:
|
|||||||
if len(parts) == 1:
|
if len(parts) == 1:
|
||||||
args = []
|
args = []
|
||||||
else:
|
else:
|
||||||
|
logging.debug("Splitting '{}' with max {} splits".format(
|
||||||
|
parts[1], cmd.maxsplit))
|
||||||
args = parts[1].split(maxsplit=cmd.maxsplit)
|
args = parts[1].split(maxsplit=cmd.maxsplit)
|
||||||
self._cmd = cmd
|
self._cmd = cmd
|
||||||
self._args = args
|
self._args = args
|
||||||
return [cmdstr] + args
|
retargs = args[:]
|
||||||
|
if text.endswith(' ') and len(args) <= cmd.maxsplit:
|
||||||
|
retargs.append('')
|
||||||
|
return [cmdstr] + retargs
|
||||||
|
|
||||||
def _check(self):
|
def _check(self):
|
||||||
"""Check if the argument count for the command is correct."""
|
"""Check if the argument count for the command is correct."""
|
||||||
|
@ -58,7 +58,7 @@ class CompletionView(QTreeView):
|
|||||||
Attributes:
|
Attributes:
|
||||||
_model: The currently active filter model.
|
_model: The currently active filter model.
|
||||||
_lastmodel: The model set in the last iteration.
|
_lastmodel: The model set in the last iteration.
|
||||||
_completion_models: dict of available completion models.
|
_models: dict of available completion models.
|
||||||
_enabled: Whether showing the CompletionView is enabled.
|
_enabled: Whether showing the CompletionView is enabled.
|
||||||
_completing: Whether we're currently completing something.
|
_completing: Whether we're currently completing something.
|
||||||
_height: The height to use for the CompletionView.
|
_height: The height to use for the CompletionView.
|
||||||
@ -107,20 +107,22 @@ class CompletionView(QTreeView):
|
|||||||
self._enabled = config.get('completion', 'show')
|
self._enabled = config.get('completion', 'show')
|
||||||
self._model = None
|
self._model = None
|
||||||
self._lastmodel = None
|
self._lastmodel = None
|
||||||
self._completion_models = {
|
self._models = {
|
||||||
'command': CompletionFilterModel(CommandCompletionModel(self)),
|
'command': CompletionFilterModel(CommandCompletionModel(self)),
|
||||||
'section': CompletionFilterModel(SettingSectionCompletionModel(
|
'section': CompletionFilterModel(
|
||||||
self)),
|
SettingSectionCompletionModel(self)),
|
||||||
|
'option': {},
|
||||||
|
'value': {},
|
||||||
}
|
}
|
||||||
for sect in configdata.DATA.keys():
|
for sect in configdata.DATA.keys():
|
||||||
self._completion_models['option_' + sect] = CompletionFilterModel(
|
self._models['option'][sect] = CompletionFilterModel(
|
||||||
SettingOptionCompletionModel(sect, self))
|
SettingOptionCompletionModel(sect, self))
|
||||||
|
self._models['value'][sect] = {}
|
||||||
for opt in configdata.DATA[sect].keys():
|
for opt in configdata.DATA[sect].keys():
|
||||||
try:
|
try:
|
||||||
modelname = 'value_{}_{}'.format(sect, opt)
|
self._models['value'][sect][opt] = (
|
||||||
self._completion_models[modelname] = (
|
CompletionFilterModel(SettingValueCompletionModel(
|
||||||
CompletionFilterModel(SettingValueCompletionModel(sect,
|
sect, opt, self)))
|
||||||
opt, self)))
|
|
||||||
except NoCompletionsError:
|
except NoCompletionsError:
|
||||||
pass
|
pass
|
||||||
self._completing = False
|
self._completing = False
|
||||||
@ -176,28 +178,39 @@ class CompletionView(QTreeView):
|
|||||||
parts: The command chunks to get a completion for.
|
parts: The command chunks to get a completion for.
|
||||||
"""
|
"""
|
||||||
if len(parts) == 1:
|
if len(parts) == 1:
|
||||||
return 'command'
|
# parts = [''] or something like ['set']
|
||||||
# try to delegate to the command
|
return self._models['command']
|
||||||
|
# delegate completion to command
|
||||||
try:
|
try:
|
||||||
completions = cmdutils.cmd_dict[parts[0]].completion
|
completions = cmdutils.cmd_dict[parts[0]].completion
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
# entering an unknown command
|
||||||
return None
|
return None
|
||||||
logging.debug("completions: {}".format(completions))
|
logging.debug("completions: {}".format(completions))
|
||||||
if completions is None:
|
if completions is None:
|
||||||
|
# command without any available completions
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
compl = completions[len(parts) - 2]
|
idx = len(parts[1:]) - 1
|
||||||
|
completion_name = completions[idx]
|
||||||
|
logging.debug('partlen: {}, modelname {}'.format(
|
||||||
|
len(parts[1:]), completion_name))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
# More arguments than completions
|
||||||
return None
|
return None
|
||||||
if compl == 'option':
|
if completion_name == 'option':
|
||||||
compl = 'option_' + parts[-2]
|
section = parts[-2]
|
||||||
elif compl == 'value':
|
model = self._models['option'].get(section)
|
||||||
compl = 'value_{}_{}'.format(parts[-3], parts[-2])
|
elif completion_name == 'value':
|
||||||
if compl in self._completion_models:
|
section = parts[-3]
|
||||||
return compl
|
option = parts[-2]
|
||||||
|
try:
|
||||||
|
model = self._models['value'][section][option]
|
||||||
|
except KeyError:
|
||||||
|
model = None
|
||||||
else:
|
else:
|
||||||
logging.debug("No completion model for {}.".format(compl))
|
model = self._models.get(completion_name)
|
||||||
return None
|
return model
|
||||||
|
|
||||||
def _next_prev_item(self, prev):
|
def _next_prev_item(self, prev):
|
||||||
"""Handle a tab press for the CompletionView.
|
"""Handle a tab press for the CompletionView.
|
||||||
@ -225,13 +238,11 @@ class CompletionView(QTreeView):
|
|||||||
Called from cmd_text_changed().
|
Called from cmd_text_changed().
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
model: An index into self._completion_models.
|
model: The model to use.
|
||||||
"""
|
"""
|
||||||
self._lastmodel = self._model
|
logging.debug("Setting model to {}".format(model.__class__.__name__))
|
||||||
m = self._completion_models[model]
|
self.setModel(model)
|
||||||
logging.debug("Setting model to {}".format(m))
|
self._model = model
|
||||||
self.setModel(m)
|
|
||||||
self._model = m
|
|
||||||
self.expandAll()
|
self.expandAll()
|
||||||
self.resizeColumnToContents(0)
|
self.resizeColumnToContents(0)
|
||||||
|
|
||||||
@ -263,7 +274,15 @@ class CompletionView(QTreeView):
|
|||||||
parts = split_cmdline(text)
|
parts = split_cmdline(text)
|
||||||
|
|
||||||
model = self._get_new_completion(parts)
|
model = self._get_new_completion(parts)
|
||||||
|
if model is None:
|
||||||
|
logging.debug("No completion model for {}.".format(parts))
|
||||||
|
else:
|
||||||
|
logging.debug("New completion: {} / last: {}".format(
|
||||||
|
model.srcmodel.__class__.__name__,
|
||||||
|
self._lastmodel.srcmodel.__class__.__name__ if self._lastmodel
|
||||||
|
is not None else "None"))
|
||||||
if model != self._lastmodel:
|
if model != self._lastmodel:
|
||||||
|
self._lastmodel = model
|
||||||
if model is None:
|
if model is None:
|
||||||
self.hide()
|
self.hide()
|
||||||
self._completing = False
|
self._completing = False
|
||||||
|
Loading…
Reference in New Issue
Block a user