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:
parent
0778e33142
commit
f6a7ef3985
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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."""
|
||||
|
@ -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."""
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user