diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index d82323f8b..29b76de88 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.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. diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py index 72982499e..c3e91412a 100644 --- a/qutebrowser/browser/history.py +++ b/qutebrowser/browser/history.py @@ -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() diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py index 52f396c1b..bed659799 100644 --- a/qutebrowser/completion/completer.py +++ b/qutebrowser/completion/completer.py @@ -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.""" diff --git a/qutebrowser/completion/models/completion.py b/qutebrowser/completion/models/completion.py index 11fa44a14..dc196a65c 100644 --- a/qutebrowser/completion/models/completion.py +++ b/qutebrowser/completion/models/completion.py @@ -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.""" diff --git a/qutebrowser/completion/models/sortfilter.py b/qutebrowser/completion/models/sortfilter.py index 8688c59ea..f7f70eb95 100644 --- a/qutebrowser/completion/models/sortfilter.py +++ b/qutebrowser/completion/models/sortfilter.py @@ -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): diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 05db40c4a..d959f59ab 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -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):