Handle parts/prefix in statusbar.command widget

This commit is contained in:
Florian Bruhin 2014-05-28 07:50:41 +02:00
parent dc655dd40b
commit 962a83b592
2 changed files with 54 additions and 42 deletions

View File

@ -30,7 +30,6 @@ import qutebrowser.config.configdata as configdata
from qutebrowser.widgets._completiondelegate import CompletionItemDelegate from qutebrowser.widgets._completiondelegate import CompletionItemDelegate
from qutebrowser.models.basecompletion import NoCompletionsError from qutebrowser.models.basecompletion import NoCompletionsError
from qutebrowser.config.style import set_register_stylesheet from qutebrowser.config.style import set_register_stylesheet
from qutebrowser.commands.managers import split_cmdline
from qutebrowser.models.completionfilter import CompletionFilterModel as CFM from qutebrowser.models.completionfilter import CompletionFilterModel as CFM
from qutebrowser.models.completion import ( from qutebrowser.models.completion import (
CommandCompletionModel, SettingSectionCompletionModel, CommandCompletionModel, SettingSectionCompletionModel,
@ -283,8 +282,8 @@ class CompletionView(QTreeView):
elif section == 'aliases': elif section == 'aliases':
self._init_command_completion() self._init_command_completion()
@pyqtSlot(str, int) @pyqtSlot(str, list, int)
def on_update_completion(self, text, cursor_part): def on_update_completion(self, prefix, parts, cursor_part):
"""Check if completions are available and activate them. """Check if completions are available and activate them.
Slot for the textChanged signal of the statusbar command widget. Slot for the textChanged signal of the statusbar command widget.
@ -293,7 +292,7 @@ class CompletionView(QTreeView):
text: The new text text: The new text
cursor_part: The part the cursor is currently over. cursor_part: The part the cursor is currently over.
""" """
if not text.startswith(':'): if prefix != ':':
# This is a search or gibberish, so we don't need to complete # This is a search or gibberish, so we don't need to complete
# anything (yet) # anything (yet)
# FIXME complete searchs # FIXME complete searchs
@ -301,9 +300,6 @@ class CompletionView(QTreeView):
self._completing = False self._completing = False
return return
text = text.lstrip(':')
parts = split_cmdline(text)
model = self._get_new_completion(parts, cursor_part) model = self._get_new_completion(parts, cursor_part)
if model is None: if model is None:
logger.debug("No completion model for {}.".format(parts)) logger.debug("No completion model for {}.".format(parts))

View File

@ -37,6 +37,9 @@ class Command(MinimalLineEdit):
Attributes: Attributes:
history: The command history object. history: The command history object.
cursor_part: The part the cursor is currently over.
parts: A list of strings with the split commandline
prefix: The prefix currently entered.
_validator: The current command validator. _validator: The current command validator.
Signals: Signals:
@ -50,8 +53,11 @@ class Command(MinimalLineEdit):
hidden. hidden.
hide_completion: Emitted when the completion widget should be hidden. hide_completion: Emitted when the completion widget should be hidden.
update_completion: Emitted when the completion should be shown/updated. update_completion: Emitted when the completion should be shown/updated.
arg 0: The new text which was set. arg 0: The prefix used.
arg 1: The part the cursor is currently in. arg 1: A list of strings (commandline separated into
parts)
arg 2: The part the cursor is currently in.
cursor_part_changed: The command part where the cursor is over changed.
show_cmd: Emitted when command input should be shown. show_cmd: Emitted when command input should be shown.
hide_cmd: Emitted when command input can be hidden. hide_cmd: Emitted when command input can be hidden.
""" """
@ -61,7 +67,8 @@ class Command(MinimalLineEdit):
got_search_rev = pyqtSignal(str) got_search_rev = pyqtSignal(str)
clear_completion_selection = pyqtSignal() clear_completion_selection = pyqtSignal()
hide_completion = pyqtSignal() hide_completion = pyqtSignal()
update_completion = pyqtSignal(str, int) update_completion = pyqtSignal(str, list, int)
cursor_part_changed = pyqtSignal(int)
show_cmd = pyqtSignal() show_cmd = pyqtSignal()
hide_cmd = pyqtSignal() hide_cmd = pyqtSignal()
@ -71,37 +78,52 @@ class Command(MinimalLineEdit):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.cursor_part = 0
self.history = History() self.history = History()
self._validator = _CommandValidator(self) self._validator = _CommandValidator(self)
self.setValidator(self._validator) self.setValidator(self._validator)
self.textEdited.connect(self.on_text_edited) self.textEdited.connect(self.on_text_edited)
self.cursorPositionChanged.connect(self.on_cursor_position_changed) self.cursorPositionChanged.connect(self._update_cursor_part)
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
def _cursor_part(self): @property
def prefix(self):
text = self.text()
if not text:
return ''
elif text[0] in STARTCHARS:
return text[0]
else:
return ''
@property
def parts(self):
text = self.text()
if not text:
return []
text = text[len(self.prefix):]
return split_cmdline(text)
@pyqtSlot()
def _update_cursor_part(self):
"""Get the part index of the commandline where the cursor is over.""" """Get the part index of the commandline where the cursor is over."""
prefix, parts = self._split() old_cursor_part = self.cursor_part
cursor_pos = self.cursorPosition() cursor_pos = self.cursorPosition()
cursor_pos -= len(prefix) cursor_pos -= len(self.prefix)
for i, part in enumerate(parts): for i, part in enumerate(self.parts):
logger.debug("part {}, len {}, pos {}".format(i, len(part), logger.debug("part {}, len {}, pos {}".format(i, len(part),
cursor_pos)) cursor_pos))
if cursor_pos <= len(part): if cursor_pos <= len(part):
# foo| bar # foo| bar
return i self.cursor_part = i
if old_cursor_part != i:
self.cursor_part_changed.emit(i)
# FIXME do we really want to emit this here?
self.update_completion.emit(self.prefix, self.parts,
self.cursor_part)
return
cursor_pos -= (len(part) + 1) # FIXME are spaces always 1 char? cursor_pos -= (len(part) + 1) # FIXME are spaces always 1 char?
return None
def _split(self):
text = self.text()
if not text:
return '', []
if text[0] in STARTCHARS:
prefix = text[0]
text = text[1:]
else:
prefix = ''
parts = split_cmdline(text)
return prefix, parts
@pyqtSlot(str) @pyqtSlot(str)
def set_cmd_text(self, text): def set_cmd_text(self, text):
@ -117,7 +139,8 @@ class Command(MinimalLineEdit):
self.setText(text) self.setText(text)
if old_text != text: if old_text != text:
# We want the completion to pop out here. # We want the completion to pop out here.
self.update_completion.emit(text, self._cursor_part()) self.update_completion.emit(self.prefix, self.parts,
self.cursor_part)
self.setFocus() self.setFocus()
self.show_cmd.emit() self.show_cmd.emit()
@ -128,14 +151,11 @@ class Command(MinimalLineEdit):
Args: Args:
text: The text to set (string). text: The text to set (string).
""" """
prefix, parts = self._split() parts = self.parts[:]
cursor_part = self._cursor_part()
logger.debug("parts: {}, changing {} to '{}'".format( logger.debug("parts: {}, changing {} to '{}'".format(
parts, cursor_part, newtext)) parts, self.cursor_part, newtext))
parts[cursor_part] = newtext parts[self.cursor_part] = newtext
self.blockSignals(True) self.setText(self.prefix + ' '.join(parts))
self.setText(prefix + ' '.join(parts))
self.blockSignals(False)
self.setFocus() self.setFocus()
self.show_cmd.emit() self.show_cmd.emit()
@ -191,12 +211,8 @@ class Command(MinimalLineEdit):
def on_text_edited(self, text): def on_text_edited(self, text):
"""Slot for textEdited. Stop history and update completion.""" """Slot for textEdited. Stop history and update completion."""
self.history.stop() self.history.stop()
self.update_completion.emit(text, self._cursor_part()) self.update_completion.emit(self.prefix, self.parts,
self.cursor_part)
@pyqtSlot(int, int)
def on_cursor_position_changed(self, _old, _new):
"""Slot for cursorPositionChanged to update completion."""
self.update_completion.emit(self.text(), self._cursor_part())
def on_mode_left(self, mode): def on_mode_left(self, mode):
"""Clear up when ommand mode was left. """Clear up when ommand mode was left.