Add url history completion for open.

Adds a basic completion model implementation around the global browser
history and registers that for the open command.

Modifies WebHistory to add an __iter__ method and to use a dict instead of a
set to store an entire HistoryEntry for each archived item instead of just the
URL. Brief tests showed that the lookup time for set and dict are very
similar. They are at least on the same order of magnitude. Testing membership
of a list on the other hand, as was the case before a set was used, was four
orders of magnitude slower on my machine.
This commit is contained in:
Jimmy 2015-03-05 16:44:46 +13:00 committed by Florian Bruhin
parent 0778e33142
commit f6a7ef3985
6 changed files with 43 additions and 5 deletions

View File

@ -280,7 +280,7 @@ class CommandDispatcher:
@cmdutils.register(instance='command-dispatcher', name='open',
maxsplit=0, scope='window',
completion=[usertypes.Completion.quickmark_by_url])
completion=[usertypes.Completion.web_history_by_url])
def openurl(self, url=None, bg=False, tab=False, window=False,
count: {'special': 'count'}=None):
"""Open a URL in the current/[count]th tab.

View File

@ -74,11 +74,16 @@ class WebHistory(QWebHistoryInterface):
super().__init__(parent)
self._lineparser = lineparser.AppendLineParser(
standarddir.data(), 'history', parent=self)
self._old_urls = set()
self._old_urls = {}
with self._lineparser.open():
for line in self._lineparser:
_time, url = line.rstrip().split(maxsplit=1)
self._old_urls.add(url)
atime, url = line.rstrip().split(maxsplit=1)
# This de-duplicates history entries. We keep later ones in the
# file which usually the last ones accessed. If you want
# to keep information about multiple hits change the
# items in old_urls to be lists or change HistoryEntry
# to have a list of atimes.
self._old_urls[url] = HistoryEntry(atime, url)
self._new_history = []
self._saved_count = 0
self._old_hit = 0
@ -92,6 +97,10 @@ class WebHistory(QWebHistoryInterface):
def __getitem__(self, key):
return self._new_history[key]
def __iter__(self):
import itertools
return itertools.chain(self._old_urls.values(), iter(self._new_history))
def get_recent(self):
"""Get the most recent history entries."""
old = self._lineparser.get_recent()

View File

@ -85,6 +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)
def _init_setting_completions(self):
"""Initialize setting completion models."""

View File

@ -215,6 +215,30 @@ class HelpCompletionModel(base.BaseCompletionModel):
self.new_item(cat, name, desc)
class WebHistoryCompletionModel(base.BaseCompletionModel):
"""A CompletionModel filled with global browsing history."""
# pylint: disable=abstract-method
def __init__(self, match_field='url', parent=None):
super().__init__(parent)
self.cat = self.new_category("History")
self.history = objreg.get('web-history')
for entry in self.history:
if entry.url:
self.new_item(self.cat, entry.url, "")
self.history.changed.connect(self.history_changed)
def history_changed(self):
# 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, "")
class QuickmarkCompletionModel(base.BaseCompletionModel):
"""A CompletionModel filled with all quickmarks."""

View File

@ -137,6 +137,8 @@ class CompletionFilterModel(QSortFilterProxyModel):
# TODO more sophisticated filtering
if not self.pattern:
return True
if not data:
return False
return self.pattern.casefold() in data.casefold()
def intelligentLessThan(self, lindex, rindex):

View File

@ -237,7 +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', 'sessions'])
'quickmark_by_name', 'web_history_by_url',
'sessions'])
class Question(QObject):