Refactor how completions are organized.
This commit is contained in:
parent
34b24aafa8
commit
0b975db4dd
@ -24,7 +24,7 @@ from PyQt5.QtCore import pyqtSlot, QObject, QTimer, Qt
|
||||
from qutebrowser.config import config, configdata
|
||||
from qutebrowser.commands import cmdutils, runners
|
||||
from qutebrowser.utils import usertypes, log, objreg, utils
|
||||
from qutebrowser.completion.models import completion as models
|
||||
from qutebrowser.completion.models import miscmodels, urlmodel, configmodel
|
||||
from qutebrowser.completion.models.sortfilter import (
|
||||
CompletionFilterModel as CFM)
|
||||
|
||||
@ -82,26 +82,27 @@ class Completer(QObject):
|
||||
def _init_static_completions(self):
|
||||
"""Initialize the static completion models."""
|
||||
self._models[usertypes.Completion.command] = CFM(
|
||||
models.CommandCompletionModel(self), self)
|
||||
miscmodels.CommandCompletionModel(self), self)
|
||||
self._models[usertypes.Completion.helptopic] = CFM(
|
||||
models.HelpCompletionModel(self), self)
|
||||
miscmodels.HelpCompletionModel(self), self)
|
||||
self._models[usertypes.Completion.url] = CFM(
|
||||
models.UrlCompletionModel(self), self,
|
||||
urlmodel.UrlCompletionModel(self), self,
|
||||
dumb_sort=Qt.DescendingOrder)
|
||||
|
||||
def _init_setting_completions(self):
|
||||
"""Initialize setting completion models."""
|
||||
self._models[usertypes.Completion.section] = CFM(
|
||||
models.SettingSectionCompletionModel(self), self)
|
||||
configmodel.SettingSectionCompletionModel(self), self)
|
||||
self._models[usertypes.Completion.option] = {}
|
||||
self._models[usertypes.Completion.value] = {}
|
||||
for sectname in configdata.DATA:
|
||||
model = models.SettingOptionCompletionModel(sectname, self)
|
||||
model = configmodel.SettingOptionCompletionModel(sectname, self)
|
||||
self._models[usertypes.Completion.option][sectname] = CFM(
|
||||
model, self)
|
||||
self._models[usertypes.Completion.value][sectname] = {}
|
||||
for opt in configdata.DATA[sectname].keys():
|
||||
model = models.SettingValueCompletionModel(sectname, opt, self)
|
||||
model = configmodel.SettingValueCompletionModel(sectname, opt,
|
||||
self)
|
||||
self._models[usertypes.Completion.value][sectname][opt] = CFM(
|
||||
model, self)
|
||||
|
||||
@ -114,9 +115,9 @@ class Completer(QObject):
|
||||
except KeyError:
|
||||
pass
|
||||
self._models[usertypes.Completion.quickmark_by_url] = CFM(
|
||||
models.QuickmarkCompletionModel('url', self), self)
|
||||
miscmodels.QuickmarkCompletionModel('url', self), self)
|
||||
self._models[usertypes.Completion.quickmark_by_name] = CFM(
|
||||
models.QuickmarkCompletionModel('name', self), self)
|
||||
miscmodels.QuickmarkCompletionModel('name', self), self)
|
||||
|
||||
@pyqtSlot()
|
||||
def init_session_completion(self):
|
||||
@ -126,7 +127,7 @@ class Completer(QObject):
|
||||
except KeyError:
|
||||
pass
|
||||
self._models[usertypes.Completion.sessions] = CFM(
|
||||
models.SessionCompletionModel(self), self)
|
||||
miscmodels.SessionCompletionModel(self), self)
|
||||
|
||||
def _get_completion_model(self, completion, parts, cursor_part):
|
||||
"""Get a completion model based on an enum member.
|
||||
|
@ -17,13 +17,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""CompletionModels for different usages."""
|
||||
"""CompletionModels for the config."""
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, Qt
|
||||
|
||||
from qutebrowser.config import config, configdata
|
||||
from qutebrowser.utils import log, qtutils, objreg
|
||||
from qutebrowser.commands import cmdutils
|
||||
from qutebrowser.completion.models import base
|
||||
|
||||
|
||||
@ -148,168 +147,3 @@ class SettingValueCompletionModel(base.BaseCompletionModel):
|
||||
if not ok:
|
||||
raise ValueError("Setting data failed! (section: {}, option: {}, "
|
||||
"value: {})".format(section, option, value))
|
||||
|
||||
|
||||
class CommandCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with all commands and descriptions."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
assert cmdutils.cmd_dict
|
||||
cmdlist = []
|
||||
for obj in set(cmdutils.cmd_dict.values()):
|
||||
if (obj.hide or (obj.debug and not objreg.get('args').debug) or
|
||||
obj.deprecated):
|
||||
pass
|
||||
else:
|
||||
cmdlist.append((obj.name, obj.desc))
|
||||
for name, cmd in config.section('aliases').items():
|
||||
cmdlist.append((name, "Alias for '{}'".format(cmd)))
|
||||
cat = self.new_category("Commands")
|
||||
for (name, desc) in sorted(cmdlist):
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
|
||||
class HelpCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with help topics."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._init_commands()
|
||||
self._init_settings()
|
||||
|
||||
def _init_commands(self):
|
||||
"""Fill completion with :command entries."""
|
||||
assert cmdutils.cmd_dict
|
||||
cmdlist = []
|
||||
for obj in set(cmdutils.cmd_dict.values()):
|
||||
if (obj.hide or (obj.debug and not objreg.get('args').debug) or
|
||||
obj.deprecated):
|
||||
pass
|
||||
else:
|
||||
cmdlist.append((':' + obj.name, obj.desc))
|
||||
cat = self.new_category("Commands")
|
||||
for (name, desc) in sorted(cmdlist):
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
def _init_settings(self):
|
||||
"""Fill completion with section->option entries."""
|
||||
cat = self.new_category("Settings")
|
||||
for sectname, sectdata in configdata.DATA.items():
|
||||
for optname in sectdata.keys():
|
||||
try:
|
||||
desc = sectdata.descriptions[optname]
|
||||
except (KeyError, AttributeError):
|
||||
# Some stuff (especially ValueList items) don't have a
|
||||
# description.
|
||||
desc = ""
|
||||
else:
|
||||
desc = desc.splitlines()[0]
|
||||
name = '{}->{}'.format(sectname, optname)
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
|
||||
class UrlCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A model which combines quickmarks and web history URLs.
|
||||
|
||||
Used for the `open` command."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._quickcat = self.new_category("Quickmarks")
|
||||
self._histcat = self.new_category("History")
|
||||
self._histstore = objreg.get('web-history')
|
||||
|
||||
WebHistoryCompletionModel.fill_model(self, cat=self._histcat)
|
||||
QuickmarkCompletionModel.fill_model(self, cat=self._quickcat)
|
||||
|
||||
self._histstore.item_added.connect(
|
||||
lambda e: WebHistoryCompletionModel.history_changed(
|
||||
self, e, self._histcat))
|
||||
|
||||
|
||||
class WebHistoryCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with global browsing history."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._histcat = self.new_category("History")
|
||||
self._histstore = objreg.get('web-history')
|
||||
|
||||
self.fill_model(self, self._histcat, self._histstore)
|
||||
|
||||
self._histstore.item_added.connect(
|
||||
lambda e: self.history_changed(e, self._histcat))
|
||||
|
||||
@staticmethod
|
||||
def fill_model(model, cat=None, histstore=None):
|
||||
"""Fill the given model/category with the given history."""
|
||||
if not histstore:
|
||||
histstore = objreg.get('web-history')
|
||||
if not cat:
|
||||
cat = model.new_category("History")
|
||||
|
||||
for entry in histstore:
|
||||
atime = int(entry.atime)
|
||||
model.new_item(cat, entry.url, "", str(atime), sort=atime)
|
||||
|
||||
def history_changed(self, entry, cat):
|
||||
"""Slot called when a new history item was added."""
|
||||
if entry.url:
|
||||
atime = int(entry.atime)
|
||||
self.new_item(cat, entry.url, "", str(atime), sort=atime)
|
||||
|
||||
|
||||
class QuickmarkCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with all quickmarks."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, match_field='url', parent=None):
|
||||
super().__init__(parent)
|
||||
self.fill_model(self, match_field)
|
||||
|
||||
@staticmethod
|
||||
def fill_model(model, match_field='url', cat=None):
|
||||
"""Fill the given model/category with quickmarks."""
|
||||
if not cat:
|
||||
cat = model.new_category("Quickmarks")
|
||||
quickmarks = objreg.get('quickmark-manager').marks.items()
|
||||
|
||||
if match_field == 'url':
|
||||
for qm_name, qm_url in quickmarks:
|
||||
model.new_item(cat, qm_url, qm_name)
|
||||
elif match_field == 'name':
|
||||
for qm_name, qm_url in quickmarks:
|
||||
model.new_item(cat, qm_name, qm_url)
|
||||
else:
|
||||
raise ValueError("Invalid value '{}' for match_field!".format(
|
||||
match_field))
|
||||
|
||||
|
||||
class SessionCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with session names."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
cat = self.new_category("Sessions")
|
||||
for name in objreg.get('session-manager').list_sessions():
|
||||
self.new_item(cat, name)
|
124
qutebrowser/completion/models/miscmodels.py
Normal file
124
qutebrowser/completion/models/miscmodels.py
Normal file
@ -0,0 +1,124 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Misc. CompletionModels."""
|
||||
|
||||
from qutebrowser.config import config, configdata
|
||||
from qutebrowser.utils import objreg
|
||||
from qutebrowser.commands import cmdutils
|
||||
from qutebrowser.completion.models import base
|
||||
|
||||
|
||||
class CommandCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with all commands and descriptions."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
assert cmdutils.cmd_dict
|
||||
cmdlist = []
|
||||
for obj in set(cmdutils.cmd_dict.values()):
|
||||
if (obj.hide or (obj.debug and not objreg.get('args').debug) or
|
||||
obj.deprecated):
|
||||
pass
|
||||
else:
|
||||
cmdlist.append((obj.name, obj.desc))
|
||||
for name, cmd in config.section('aliases').items():
|
||||
cmdlist.append((name, "Alias for '{}'".format(cmd)))
|
||||
cat = self.new_category("Commands")
|
||||
for (name, desc) in sorted(cmdlist):
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
|
||||
class HelpCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with help topics."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._init_commands()
|
||||
self._init_settings()
|
||||
|
||||
def _init_commands(self):
|
||||
"""Fill completion with :command entries."""
|
||||
assert cmdutils.cmd_dict
|
||||
cmdlist = []
|
||||
for obj in set(cmdutils.cmd_dict.values()):
|
||||
if (obj.hide or (obj.debug and not objreg.get('args').debug) or
|
||||
obj.deprecated):
|
||||
pass
|
||||
else:
|
||||
cmdlist.append((':' + obj.name, obj.desc))
|
||||
cat = self.new_category("Commands")
|
||||
for (name, desc) in sorted(cmdlist):
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
def _init_settings(self):
|
||||
"""Fill completion with section->option entries."""
|
||||
cat = self.new_category("Settings")
|
||||
for sectname, sectdata in configdata.DATA.items():
|
||||
for optname in sectdata.keys():
|
||||
try:
|
||||
desc = sectdata.descriptions[optname]
|
||||
except (KeyError, AttributeError):
|
||||
# Some stuff (especially ValueList items) don't have a
|
||||
# description.
|
||||
desc = ""
|
||||
else:
|
||||
desc = desc.splitlines()[0]
|
||||
name = '{}->{}'.format(sectname, optname)
|
||||
self.new_item(cat, name, desc)
|
||||
|
||||
|
||||
class QuickmarkCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with all quickmarks."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, match_field='url', parent=None):
|
||||
super().__init__(parent)
|
||||
cat = self.new_category("Quickmarks")
|
||||
quickmarks = objreg.get('quickmark-manager').marks.items()
|
||||
if match_field == 'url':
|
||||
for qm_name, qm_url in quickmarks:
|
||||
self.new_item(cat, qm_url, qm_name)
|
||||
elif match_field == 'name':
|
||||
for qm_name, qm_url in quickmarks:
|
||||
self.new_item(cat, qm_name, qm_url)
|
||||
else:
|
||||
raise ValueError("Invalid value '{}' for match_field!".format(
|
||||
match_field))
|
||||
|
||||
|
||||
class SessionCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A CompletionModel filled with session names."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
cat = self.new_category("Sessions")
|
||||
for name in objreg.get('session-manager').list_sessions():
|
||||
self.new_item(cat, name)
|
61
qutebrowser/completion/models/urlmodel.py
Normal file
61
qutebrowser/completion/models/urlmodel.py
Normal file
@ -0,0 +1,61 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""CompletionModels for URLs."""
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
from qutebrowser.utils import objreg
|
||||
from qutebrowser.completion.models import base
|
||||
|
||||
|
||||
class UrlCompletionModel(base.BaseCompletionModel):
|
||||
|
||||
"""A model which combines quickmarks and web history URLs.
|
||||
|
||||
Used for the `open` command."""
|
||||
|
||||
# pylint: disable=abstract-method
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._quickmark_cat = self.new_category("Quickmarks")
|
||||
self._history_cat = self.new_category("History")
|
||||
|
||||
quickmarks = objreg.get('quickmark-manager').marks.items()
|
||||
history = objreg.get('web-history')
|
||||
|
||||
for qm_name, qm_url in quickmarks:
|
||||
self.new_item(self._quickmark_cat, qm_url, qm_name)
|
||||
|
||||
for entry in history:
|
||||
atime = int(entry.atime)
|
||||
self.new_item(self._history_cat, entry.url, "", str(atime),
|
||||
sort=atime)
|
||||
|
||||
history.item_added.connect(self.on_history_item_added)
|
||||
|
||||
@pyqtSlot(object)
|
||||
def on_history_item_added(self, item):
|
||||
"""Slot called when a new history item was added."""
|
||||
if item.url:
|
||||
atime = int(item.atime)
|
||||
self.new_item(self._quickmark_cat, item.url, "", str(atime),
|
||||
sort=atime)
|
Loading…
Reference in New Issue
Block a user