diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index d702994d2..45a0fbff7 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -164,7 +164,20 @@ class Config: """Returns True if option is in section.""" return option in self.config[section] - @cmdutils.register(instance='config', completion=['setting']) + @cmdutils.register(name='get', instance='config', completion=['setting'], + split_args=False) + def get_wrapper(self, sectopt): + """Wrapper for the get-command to have section/option in one arg. + + Arguments: + secopt: Section and option, delimited by a space. + + Return: + The value of the section/option. + + """ + return self.get(*sectopt.split()) + def get(self, section, option, fallback=_UNSET, raw=False): """Get the value from a section/option. diff --git a/qutebrowser/models/commandcompletion.py b/qutebrowser/models/commandcompletion.py index 28695732a..77c0627a4 100644 --- a/qutebrowser/models/commandcompletion.py +++ b/qutebrowser/models/commandcompletion.py @@ -17,8 +17,6 @@ """A CompletionModel filled with all commands and descriptions.""" -from collections import OrderedDict - from qutebrowser.commands.utils import cmd_dict from qutebrowser.models.completion import CompletionModel @@ -35,7 +33,7 @@ class CommandCompletionModel(CompletionModel): cmdlist = [] for obj in set(cmd_dict.values()): if not obj.hide: - cmdlist.append([obj.name, obj.desc]) - data = OrderedDict() - data['Commands'] = sorted(cmdlist) - self.init_data(data) + cmdlist.append((obj.name, obj.desc)) + cat = self.new_category("Commands") + for (name, desc) in sorted(cmdlist): + self.new_item(cat, name, desc) diff --git a/qutebrowser/models/completion.py b/qutebrowser/models/completion.py index d12968f55..f612c79ae 100644 --- a/qutebrowser/models/completion.py +++ b/qutebrowser/models/completion.py @@ -20,6 +20,8 @@ import logging from PyQt5.QtCore import Qt, QVariant, QAbstractItemModel, QModelIndex +ROLE_MARKS = Qt.UserRole +ROLE_FULLTEXT = Qt.UserRole + 1 class CompletionModel(QAbstractItemModel): @@ -92,23 +94,41 @@ class CompletionModel(QAbstractItemModel): idx = self.index(k, 0, cat) old = self.data(idx).value() marks = self._get_marks(needle, old) - self.setData(idx, marks, Qt.UserRole) + self.setData(idx, marks, ROLE_MARKS) - def init_data(self, data): - """Initialize the Qt model based on the data given. + def new_category(self, name): + """Add a new category to the model. Args: - data: dict of data to process. + name: The name of the category to add. + + Return: + The created CompletionItem. """ - for (cat, items) in data.items(): - newcat = CompletionItem([cat], self._root) - self._id_map[id(newcat)] = newcat - self._root.children.append(newcat) - for item in items: - newitem = CompletionItem(item, newcat) - self._id_map[id(newitem)] = newitem - newcat.children.append(newitem) + cat = CompletionItem([name], self._root) + self._id_map[id(cat)] = cat + self._root.children.append(cat) + return cat + + def new_item(self, cat, name, desc, completion=None): + """Add a new item to a category. + + Args: + cat: The parent category. + name: The name of the item. + desc: The description of the item. + completion: The long text to insert for a completion. + None if it's the same as name. + + Return: + The created CompletionItem. + + """ + item = CompletionItem((name, desc), parent=cat, fulltext=completion) + self._id_map[id(item)] = item + cat.children.append(item) + return item def removeRows(self, position=0, count=1, parent=QModelIndex()): """Remove rows from the model. @@ -171,7 +191,7 @@ class CompletionModel(QAbstractItemModel): Args: index: The QModelIndex for which to get data for. - roel: The role to use for the data. + role: The role to use for the data. Return: The data as QVariant or an invalid QVariant on error. @@ -334,21 +354,25 @@ class CompletionItem(): children: The children of this item. _data: The data of this item. _marks: The marks of this item. + _fulltext: The full text to insert when completing. + None if _data[0] already is the full text. """ - def __init__(self, data, parent=None): + def __init__(self, data, parent=None, fulltext=None): """Constructor for CompletionItem. Args: data: The data for the model, as tuple (columns). parent: An optional parent item. + fulltext: The full text to insert when completing. """ self.parent = parent self.children = [] self._data = data self._marks = [] + self._fulltext = fulltext def data(self, column, role=Qt.DisplayRole): """Get the data for role/column. @@ -366,8 +390,10 @@ class CompletionItem(): """ if role == Qt.DisplayRole: return self._data[column] - elif role == Qt.UserRole: + elif role == ROLE_MARKS: return self._marks + elif role == ROLE_FULLTEXT: + return self._fulltext else: raise ValueError("Invalid role {}".format(role)) @@ -385,8 +411,10 @@ class CompletionItem(): """ if role == Qt.DisplayRole: self._data[column] = value - elif role == Qt.UserRole: + elif role == ROLE_MARKS: self._marks = value + elif role == ROLE_FULLTEXT: + self._fulltext = value else: raise ValueError("Invalid role {}".format(role)) diff --git a/qutebrowser/models/settingcompletion.py b/qutebrowser/models/settingcompletion.py index 2925d550f..e77e9ad67 100644 --- a/qutebrowser/models/settingcompletion.py +++ b/qutebrowser/models/settingcompletion.py @@ -17,10 +17,6 @@ """A CompletionModel filled with settings and their descriptions.""" -import logging - -from collections import OrderedDict - from qutebrowser.models.completion import CompletionModel from qutebrowser.config.configdata import configdata @@ -33,11 +29,8 @@ class SettingCompletionModel(CompletionModel): def __init__(self, parent=None): super().__init__(parent) - data = OrderedDict() for secname, secdata in configdata().items(): - newdata = [] + cat = self.new_category(secname) for name in secdata.values.keys(): - newdata.append((name, secdata.descriptions[name])) - data[secname] = newdata - logging.debug("Setting data: {}".format(data)) - self.init_data(data) + self.new_item(cat, name, secdata.descriptions[name], + '{} {}'.format(secname, name)) diff --git a/qutebrowser/widgets/completion.py b/qutebrowser/widgets/completion.py index 6d1cb8742..4f2596566 100644 --- a/qutebrowser/widgets/completion.py +++ b/qutebrowser/widgets/completion.py @@ -34,6 +34,7 @@ from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption, import qutebrowser.config.config as config import qutebrowser.commands.utils as cmdutils +from qutebrowser.models.completion import ROLE_MARKS, ROLE_FULLTEXT from qutebrowser.config.style import get_stylesheet from qutebrowser.commands.parsers import split_cmdline from qutebrowser.models.completionfilter import CompletionFilterModel @@ -48,7 +49,7 @@ class CompletionView(QTreeView): Based on QTreeView but heavily customized so root elements show as category headers, and children show as flat list. - Highlights completions based on marks in the UserRole. + Highlights completions based on marks in the ROLE_MARKS data. Attributes: _model: The currently active filter model. @@ -259,10 +260,12 @@ class CompletionView(QTreeView): idx = self._next_idx(shift) self.selectionModel().setCurrentIndex( idx, QItemSelectionModel.ClearAndSelect) - data = self._model.data(idx) + data = self._model.data(idx, role=ROLE_FULLTEXT) + if data is None: + data = self._model.data(idx) if data is not None: self._ignore_next = True - self.change_completed_part.emit(self._model.data(idx)) + self.change_completed_part.emit(data) class _CompletionItemDelegate(QStyledItemDelegate): @@ -407,7 +410,7 @@ class _CompletionItemDelegate(QStyledItemDelegate): self._doc.setDocumentMargin(2) if index.column() == 0: - marks = index.data(Qt.UserRole) + marks = index.data(ROLE_MARKS) for mark in marks: cur = QTextCursor(self._doc) cur.setPosition(mark[0])