From 59948a038c66f13ab33fddcd7ec543ac103af961 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Mon, 9 Mar 2015 15:10:17 +1300 Subject: [PATCH] Add new UrlCompletion model which includes web history and quickmarks. I went to some effort to avoid duplipcating code which which leads to some arguably ugly class method calling. --- qutebrowser/browser/commands.py | 2 +- qutebrowser/completion/completer.py | 4 +- qutebrowser/completion/models/completion.py | 67 +++++++++++++++++---- qutebrowser/utils/usertypes.py | 4 +- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 29b76de88..d34af6ccd 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -280,7 +280,7 @@ class CommandDispatcher: @cmdutils.register(instance='command-dispatcher', name='open', maxsplit=0, scope='window', - completion=[usertypes.Completion.web_history_by_url]) + completion=[usertypes.Completion.url_history_and_quickmarks]) def openurl(self, url=None, bg=False, tab=False, window=False, count: {'special': 'count'}=None): """Open a URL in the current/[count]th tab. diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py index bed659799..2f7b223b3 100644 --- a/qutebrowser/completion/completer.py +++ b/qutebrowser/completion/completer.py @@ -85,8 +85,8 @@ class Completer(QObject): models.CommandCompletionModel(self), self) self._models[usertypes.Completion.helptopic] = CFM( models.HelpCompletionModel(self), self) - self._models[usertypes.Completion.web_history_by_url] = CFM( - models.WebHistoryCompletionModel('url', self), self) + self._models[usertypes.Completion.url_history_and_quickmarks] = CFM( + models.UrlCompletionModel('url', self), self) def _init_setting_completions(self): """Initialize setting completion models.""" diff --git a/qutebrowser/completion/models/completion.py b/qutebrowser/completion/models/completion.py index dc196a65c..27c3411f2 100644 --- a/qutebrowser/completion/models/completion.py +++ b/qutebrowser/completion/models/completion.py @@ -215,6 +215,32 @@ class HelpCompletionModel(base.BaseCompletionModel): self.new_item(cat, name, desc) +class UrlCompletionModel(base.BaseCompletionModel): + + """A CompletionModel which combines both quickmarks and web history + URLs. Used for the `open` command.""" + + def __init__(self, match_field='url', 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.changed.connect(lambda : + WebHistoryCompletionModel.history_changed( + self, self._histcat, self._histstore)) + + def sort(self, column, order=Qt.AscendingOrder): + # sort on atime, descending + # Ignoring the arguments because they are hardcoded in the CFM + # anyway. + self._histcat.sortChildren(2, Qt.DescendingOrder) + + class WebHistoryCompletionModel(base.BaseCompletionModel): """A CompletionModel filled with global browsing history.""" @@ -224,20 +250,33 @@ class WebHistoryCompletionModel(base.BaseCompletionModel): def __init__(self, match_field='url', parent=None): super().__init__(parent) - self.cat = self.new_category("History") - self.history = objreg.get('web-history') + self._histcat = self.new_category("History") + self._histstore = objreg.get('web-history') - for entry in self.history: - if entry.url: - self.new_item(self.cat, entry.url, "") + self.fill_model(self, self._histcat, self._histstore) - self.history.changed.connect(self.history_changed) + self._histstore.changed.connect(lambda : + self.history_changed(self._histcat, + self._histstore)) - def history_changed(self): + @staticmethod + def fill_model(model, cat=None, histstore=None): + if not histstore: + histstore = objreg.get('web-history') + if not cat: + cat = model.new_category("History") + + for entry in histstore: + model.new_item(cat, entry.url, "", entry.atime) + + def history_changed(self, cat, histstore=None): + if not histstore: + histstore = objreg.get('web-history') # Assuming the web-history.changed signal is emitted once for each # new history item and that signal handlers are run immediately. - if self.history._history[-1].url: - self.new_item(self.cat, self.history._history[-1].url, "") + if histstore._history[-1].url: + self.new_item(cat, histstore._history[-1].url, "", + str(histstore._history[-1].atime)) class QuickmarkCompletionModel(base.BaseCompletionModel): @@ -247,16 +286,20 @@ class QuickmarkCompletionModel(base.BaseCompletionModel): def __init__(self, match_field='url', parent=None): super().__init__(parent) + self.fill_model(self, match_field, parent) - cat = self.new_category("Quickmarks") + @staticmethod + def fill_model(model, match_field='url', parent=None, cat=None): + 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: - self.new_item(cat, qm_url, qm_name) + model.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) + model.new_item(cat, qm_name, qm_url) else: raise ValueError("Invalid value '{}' for match_field!".format( match_field)) diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index d959f59ab..17f7d2178 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -237,8 +237,8 @@ KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt', # Available command completions Completion = enum('Completion', ['command', 'section', 'option', 'value', 'helptopic', 'quickmark_by_url', - 'quickmark_by_name', 'web_history_by_url', - 'sessions']) + 'quickmark_by_name', + 'url_history_and_quickmarks', 'sessions']) class Question(QObject):