Skip to content

Commit

Permalink
Refactor how completions are organized.
Browse files Browse the repository at this point in the history
  • Loading branch information
The-Compiler committed Mar 11, 2015
1 parent 34b24aa commit 0b975db
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 177 deletions.
21 changes: 11 additions & 10 deletions qutebrowser/completion/completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
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)

Expand Down Expand Up @@ -82,26 +82,27 @@ def _model(self):
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)

Expand All @@ -114,9 +115,9 @@ def init_quickmark_completions(self):
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):
Expand All @@ -126,7 +127,7 @@ def init_session_completion(self):
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -148,168 +147,3 @@ def update_current_value(self, section, option):
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 changes: 124 additions & 0 deletions qutebrowser/completion/models/miscmodels.py
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit 0b975db

Please sign in to comment.