Merge branch 'completion-auto-open'

This commit is contained in:
Florian Bruhin 2015-06-27 19:56:42 +02:00
commit 8d3a8f9eda
3 changed files with 89 additions and 18 deletions

View File

@ -19,7 +19,7 @@
"""Completer attached to a CompletionView."""
from PyQt5.QtCore import pyqtSlot, QObject, QTimer
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer
from qutebrowser.config import config
from qutebrowser.commands import cmdutils, runners
@ -40,14 +40,22 @@ class Completer(QObject):
_last_cursor_pos: The old cursor position so we avoid double completion
updates.
_last_text: The old command text so we avoid double completion updates.
_signals_connected: Whether the signals are connected to update the
completion when the command widget requests that.
Signals:
next_prev_item: Emitted to select the next/previous item in the
completion.
arg0: True for the previous item, False for the next.
"""
next_prev_item = pyqtSignal(bool)
def __init__(self, cmd, win_id, parent=None):
super().__init__(parent)
self._win_id = win_id
self._cmd = cmd
self._cmd.update_completion.connect(self.schedule_completion_update)
self._cmd.textEdited.connect(self.on_text_edited)
self._signals_connected = False
self._ignore_change = False
self._empty_item_idx = None
self._timer = QTimer()
@ -58,9 +66,63 @@ class Completer(QObject):
self._last_cursor_pos = None
self._last_text = None
objreg.get('config').changed.connect(self.on_auto_open_changed)
self.handle_signal_connections()
self._cmd.clear_completion_selection.connect(
self.handle_signal_connections)
def __repr__(self):
return utils.get_repr(self)
@config.change_filter('completion', 'auto-open')
def on_auto_open_changed(self):
self.handle_signal_connections()
@pyqtSlot()
def handle_signal_connections(self):
self._connect_signals(config.get('completion', 'auto-open'))
def _connect_signals(self, connect=True):
"""Connect or disconnect the completion signals.
Args:
connect: Whether to connect (True) or disconnect (False) the
signals.
Return:
True if the signals were connected (connect=True and aren't
connected yet) - otherwise False.
"""
connections = [
(self._cmd.update_completion, self.schedule_completion_update),
(self._cmd.textChanged, self.on_text_edited),
]
if connect and not self._signals_connected:
for sender, receiver in connections:
sender.connect(receiver)
self._signals_connected = True
return True
elif not connect:
for sender, receiver in connections:
try:
sender.disconnect(receiver)
except TypeError:
# Don't fail if not connected
pass
self._signals_connected = False
return False
def _open_completion_if_needed(self):
"""If auto-open is false, temporarily connect signals.
Also opens the completion.
"""
if not config.get('completion', 'auto-open'):
connected = self._connect_signals(True)
if connected:
self.update_completion()
def _model(self):
"""Convienience method to get the current completion model."""
completion = objreg.get('completion', scope='window',
@ -405,3 +467,17 @@ class Completer(QObject):
# We also want to update the cursor part and emit update_completion
# here, but that's already done for us by cursorPositionChanged
# anyways, so we don't need to do it twice.
@cmdutils.register(instance='completer', hide=True,
modes=[usertypes.KeyMode.command], scope='window')
def completion_item_prev(self):
"""Select the previous completion item."""
self._open_completion_if_needed()
self.next_prev_item.emit(True)
@cmdutils.register(instance='completer', hide=True,
modes=[usertypes.KeyMode.command], scope='window')
def completion_item_next(self):
"""Select the next completion item."""
self._open_completion_if_needed()
self.next_prev_item.emit(False)

View File

@ -26,10 +26,9 @@ subclasses to provide completions.
from PyQt5.QtWidgets import QStyle, QTreeView, QSizePolicy
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel
from qutebrowser.commands import cmdutils
from qutebrowser.config import config, style
from qutebrowser.completion import completiondelegate, completer
from qutebrowser.utils import usertypes, qtutils, objreg, utils
from qutebrowser.utils import qtutils, objreg, utils
class CompletionView(QTreeView):
@ -96,6 +95,7 @@ class CompletionView(QTreeView):
objreg.register('completion', self, scope='window', window=win_id)
cmd = objreg.get('status-command', scope='window', window=win_id)
completer_obj = completer.Completer(cmd, win_id, self)
completer_obj.next_prev_item.connect(self.on_next_prev_item)
objreg.register('completer', completer_obj, scope='window',
window=win_id)
self.enabled = config.get('completion', 'show')
@ -168,12 +168,15 @@ class CompletionView(QTreeView):
# Item is a real item, not a category header -> success
return idx
def _next_prev_item(self, prev):
@pyqtSlot(bool)
def on_next_prev_item(self, prev):
"""Handle a tab press for the CompletionView.
Select the previous/next item and write the new text to the
statusbar.
Called from the Completer's next_prev_item signal.
Args:
prev: True for prev item, False for next one.
"""
@ -233,18 +236,6 @@ class CompletionView(QTreeView):
selmod.clearSelection()
selmod.clearCurrentIndex()
@cmdutils.register(instance='completion', hide=True,
modes=[usertypes.KeyMode.command], scope='window')
def completion_item_prev(self):
"""Select the previous completion item."""
self._next_prev_item(prev=True)
@cmdutils.register(instance='completion', hide=True,
modes=[usertypes.KeyMode.command], scope='window')
def completion_item_next(self):
"""Select the next completion item."""
self._next_prev_item(prev=False)
def selectionChanged(self, selected, deselected):
"""Extend selectionChanged to call completers selection_changed."""
super().selectionChanged(selected, deselected)

View File

@ -352,6 +352,10 @@ def data(readonly=False):
)),
('completion', sect.KeyValue(
('auto-open',
SettingValue(typ.Bool(), 'true'),
"Automatically open completion when typing."),
('download-path-suggestion',
SettingValue(typ.DownloadPathSuggestion(), 'path'),
"What to display in the download filename input."),