Use SQL completion for the open command.
Now that history, bookmark, and quickmark storage are SQL-backed, use a sql completion model to serve url completions.
This commit is contained in:
parent
6e1ea89ca1
commit
acea0d3c67
@ -19,180 +19,19 @@
|
||||
|
||||
"""Function to return the url completion model for the `open` command."""
|
||||
|
||||
import datetime
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, Qt
|
||||
|
||||
from qutebrowser.utils import objreg, utils, qtutils, log
|
||||
from qutebrowser.completion.models import base
|
||||
from qutebrowser.config import config
|
||||
|
||||
_URL_COLUMN = 0
|
||||
_TEXT_COLUMN = 1
|
||||
_TIME_COLUMN = 2
|
||||
_model = None
|
||||
_history_cat = None
|
||||
_quickmark_cat = None
|
||||
_bookmark_cat = None
|
||||
|
||||
|
||||
def _delete_url(completion):
|
||||
index = completion.currentIndex()
|
||||
qtutils.ensure_valid(index)
|
||||
category = index.parent()
|
||||
index = category.child(index.row(), _URL_COLUMN)
|
||||
qtutils.ensure_valid(category)
|
||||
if category.data() == 'Bookmarks':
|
||||
bookmark_manager = objreg.get('bookmark-manager')
|
||||
bookmark_manager.delete(index.data())
|
||||
elif category.data() == 'Quickmarks':
|
||||
quickmark_manager = objreg.get('quickmark-manager')
|
||||
sibling = index.sibling(index.row(), _TEXT_COLUMN)
|
||||
qtutils.ensure_valid(sibling)
|
||||
name = sibling.data()
|
||||
quickmark_manager.delete(name)
|
||||
|
||||
|
||||
def _remove_oldest_history():
|
||||
"""Remove the oldest history entry."""
|
||||
_history_cat.removeRow(0)
|
||||
|
||||
|
||||
def _add_history_entry(entry):
|
||||
"""Add a new history entry to the completion."""
|
||||
_model.new_item(_history_cat, entry.url.toDisplayString(),
|
||||
entry.title, _fmt_atime(entry.atime),
|
||||
sort=int(entry.atime), userdata=entry.url)
|
||||
|
||||
max_history = config.get('completion', 'web-history-max-items')
|
||||
if max_history != -1 and _history_cat.rowCount() > max_history:
|
||||
_remove_oldest_history()
|
||||
|
||||
|
||||
@config.change_filter('completion', 'timestamp-format')
|
||||
def _reformat_timestamps():
|
||||
"""Reformat the timestamps if the config option was changed."""
|
||||
for i in range(_history_cat.rowCount()):
|
||||
url_item = _history_cat.child(i, _URL_COLUMN)
|
||||
atime_item = _history_cat.child(i, _TIME_COLUMN)
|
||||
atime = url_item.data(base.Role.sort)
|
||||
atime_item.setText(_fmt_atime(atime))
|
||||
|
||||
|
||||
@pyqtSlot(object)
|
||||
def _on_history_item_added(entry):
|
||||
"""Slot called when a new history item was added."""
|
||||
for i in range(_history_cat.rowCount()):
|
||||
url_item = _history_cat.child(i, _URL_COLUMN)
|
||||
atime_item = _history_cat.child(i, _TIME_COLUMN)
|
||||
title_item = _history_cat.child(i, _TEXT_COLUMN)
|
||||
if url_item.data(base.Role.userdata) == entry.url:
|
||||
atime_item.setText(_fmt_atime(entry.atime))
|
||||
title_item.setText(entry.title)
|
||||
url_item.setData(int(entry.atime), base.Role.sort)
|
||||
break
|
||||
else:
|
||||
_add_history_entry(entry)
|
||||
|
||||
|
||||
@pyqtSlot()
|
||||
def _on_history_cleared():
|
||||
_history_cat.removeRows(0, _history_cat.rowCount())
|
||||
|
||||
|
||||
def _remove_item(data, category, column):
|
||||
"""Helper function for on_quickmark_removed and on_bookmark_removed.
|
||||
|
||||
Args:
|
||||
data: The item to search for.
|
||||
category: The category to search in.
|
||||
column: The column to use for matching.
|
||||
"""
|
||||
for i in range(category.rowCount()):
|
||||
item = category.child(i, column)
|
||||
if item.data(Qt.DisplayRole) == data:
|
||||
category.removeRow(i)
|
||||
break
|
||||
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_quickmark_removed(name):
|
||||
"""Called when a quickmark has been removed by the user.
|
||||
|
||||
Args:
|
||||
name: The name of the quickmark which has been removed.
|
||||
"""
|
||||
_remove_item(name, _quickmark_cat, _TEXT_COLUMN)
|
||||
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_bookmark_removed(urltext):
|
||||
"""Called when a bookmark has been removed by the user.
|
||||
|
||||
Args:
|
||||
urltext: The url of the bookmark which has been removed.
|
||||
"""
|
||||
_remove_item(urltext, _bookmark_cat, _URL_COLUMN)
|
||||
|
||||
|
||||
def _fmt_atime(atime):
|
||||
"""Format an atime to a human-readable string."""
|
||||
fmt = config.get('completion', 'timestamp-format')
|
||||
if fmt is None:
|
||||
return ''
|
||||
try:
|
||||
dt = datetime.datetime.fromtimestamp(atime)
|
||||
except (ValueError, OSError, OverflowError):
|
||||
# Different errors which can occur for too large values...
|
||||
log.misc.error("Got invalid timestamp {}!".format(atime))
|
||||
return '(invalid)'
|
||||
else:
|
||||
return dt.strftime(fmt)
|
||||
|
||||
|
||||
def _init():
|
||||
global _model, _quickmark_cat, _bookmark_cat, _history_cat
|
||||
_model = base.CompletionModel(column_widths=(40, 50, 10),
|
||||
dumb_sort=Qt.DescendingOrder,
|
||||
delete_cur_item=_delete_url,
|
||||
columns_to_filter=[_URL_COLUMN,
|
||||
_TEXT_COLUMN])
|
||||
_quickmark_cat = _model.new_category("Quickmarks")
|
||||
_bookmark_cat = _model.new_category("Bookmarks")
|
||||
_history_cat = _model.new_category("History")
|
||||
|
||||
quickmark_manager = objreg.get('quickmark-manager')
|
||||
quickmarks = quickmark_manager.marks.items()
|
||||
for qm_name, qm_url in quickmarks:
|
||||
_model.new_item(_quickmark_cat, qm_url, qm_name)
|
||||
quickmark_manager.added.connect(
|
||||
lambda name, url: _model.new_item(_quickmark_cat, url, name))
|
||||
quickmark_manager.removed.connect(_on_quickmark_removed)
|
||||
|
||||
bookmark_manager = objreg.get('bookmark-manager')
|
||||
bookmarks = bookmark_manager.marks.items()
|
||||
for bm_url, bm_title in bookmarks:
|
||||
_model.new_item(_bookmark_cat, bm_url, bm_title)
|
||||
bookmark_manager.added.connect(
|
||||
lambda name, url: _model.new_item(_bookmark_cat, url, name))
|
||||
bookmark_manager.removed.connect(_on_bookmark_removed)
|
||||
|
||||
history = objreg.get('web-history')
|
||||
max_history = config.get('completion', 'web-history-max-items')
|
||||
for entry in utils.newest_slice(history, max_history):
|
||||
if not entry.redirect:
|
||||
_add_history_entry(entry)
|
||||
history.add_completion_item.connect(_on_history_item_added)
|
||||
history.cleared.connect(_on_history_cleared)
|
||||
|
||||
objreg.get('config').changed.connect(_reformat_timestamps)
|
||||
|
||||
from qutebrowser.completion.models import sqlmodel
|
||||
|
||||
def url():
|
||||
"""A _model which combines bookmarks, quickmarks and web history URLs.
|
||||
"""A model which combines bookmarks, quickmarks and web history URLs.
|
||||
|
||||
Used for the `open` command.
|
||||
"""
|
||||
if not _model:
|
||||
_init()
|
||||
return _model
|
||||
urlcol = 0
|
||||
textcol = 1
|
||||
|
||||
model = sqlmodel.SqlCompletionModel(column_widths=(40, 50, 10),
|
||||
columns_to_filter=[urlcol, textcol])
|
||||
model.new_category('History')
|
||||
model.new_category('Quickmarks')
|
||||
model.new_category('Bookmarks')
|
||||
return model
|
||||
|
@ -27,7 +27,7 @@ from hypothesis import strategies
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from qutebrowser.browser import history
|
||||
from qutebrowser.utils import objreg, urlutils
|
||||
from qutebrowser.utils import objreg, urlutils, usertypes
|
||||
from qutebrowser.misc import sql
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user