From 962a83b5920850b1ed421d45314144f1729f5246 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 28 May 2014 07:50:41 +0200 Subject: [PATCH] Handle parts/prefix in statusbar.command widget --- qutebrowser/widgets/_completion.py | 10 +-- qutebrowser/widgets/statusbar/_command.py | 86 ++++++++++++++--------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/qutebrowser/widgets/_completion.py b/qutebrowser/widgets/_completion.py index 3f2adf7bf..553f1b969 100644 --- a/qutebrowser/widgets/_completion.py +++ b/qutebrowser/widgets/_completion.py @@ -30,7 +30,6 @@ import qutebrowser.config.configdata as configdata from qutebrowser.widgets._completiondelegate import CompletionItemDelegate from qutebrowser.models.basecompletion import NoCompletionsError 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.completion import ( CommandCompletionModel, SettingSectionCompletionModel, @@ -283,8 +282,8 @@ class CompletionView(QTreeView): elif section == 'aliases': self._init_command_completion() - @pyqtSlot(str, int) - def on_update_completion(self, text, cursor_part): + @pyqtSlot(str, list, int) + def on_update_completion(self, prefix, parts, cursor_part): """Check if completions are available and activate them. Slot for the textChanged signal of the statusbar command widget. @@ -293,7 +292,7 @@ class CompletionView(QTreeView): text: The new text 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 # anything (yet) # FIXME complete searchs @@ -301,9 +300,6 @@ class CompletionView(QTreeView): self._completing = False return - text = text.lstrip(':') - parts = split_cmdline(text) - model = self._get_new_completion(parts, cursor_part) if model is None: logger.debug("No completion model for {}.".format(parts)) diff --git a/qutebrowser/widgets/statusbar/_command.py b/qutebrowser/widgets/statusbar/_command.py index 81c6364c2..d49d89aea 100644 --- a/qutebrowser/widgets/statusbar/_command.py +++ b/qutebrowser/widgets/statusbar/_command.py @@ -37,6 +37,9 @@ class Command(MinimalLineEdit): Attributes: 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. Signals: @@ -50,8 +53,11 @@ class Command(MinimalLineEdit): hidden. hide_completion: Emitted when the completion widget should be hidden. update_completion: Emitted when the completion should be shown/updated. - arg 0: The new text which was set. - arg 1: The part the cursor is currently in. + arg 0: The prefix used. + 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. hide_cmd: Emitted when command input can be hidden. """ @@ -61,7 +67,8 @@ class Command(MinimalLineEdit): got_search_rev = pyqtSignal(str) clear_completion_selection = pyqtSignal() hide_completion = pyqtSignal() - update_completion = pyqtSignal(str, int) + update_completion = pyqtSignal(str, list, int) + cursor_part_changed = pyqtSignal(int) show_cmd = pyqtSignal() hide_cmd = pyqtSignal() @@ -71,37 +78,52 @@ class Command(MinimalLineEdit): def __init__(self, parent=None): super().__init__(parent) + self.cursor_part = 0 self.history = History() self._validator = _CommandValidator(self) self.setValidator(self._validator) 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) - 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.""" - prefix, parts = self._split() + old_cursor_part = self.cursor_part cursor_pos = self.cursorPosition() - cursor_pos -= len(prefix) - for i, part in enumerate(parts): + cursor_pos -= len(self.prefix) + for i, part in enumerate(self.parts): logger.debug("part {}, len {}, pos {}".format(i, len(part), cursor_pos)) if cursor_pos <= len(part): # 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? - - 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 + return None @pyqtSlot(str) def set_cmd_text(self, text): @@ -117,7 +139,8 @@ class Command(MinimalLineEdit): self.setText(text) if old_text != text: # 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.show_cmd.emit() @@ -128,14 +151,11 @@ class Command(MinimalLineEdit): Args: text: The text to set (string). """ - prefix, parts = self._split() - cursor_part = self._cursor_part() + parts = self.parts[:] logger.debug("parts: {}, changing {} to '{}'".format( - parts, cursor_part, newtext)) - parts[cursor_part] = newtext - self.blockSignals(True) - self.setText(prefix + ' '.join(parts)) - self.blockSignals(False) + parts, self.cursor_part, newtext)) + parts[self.cursor_part] = newtext + self.setText(self.prefix + ' '.join(parts)) self.setFocus() self.show_cmd.emit() @@ -191,12 +211,8 @@ class Command(MinimalLineEdit): def on_text_edited(self, text): """Slot for textEdited. Stop history and update completion.""" self.history.stop() - self.update_completion.emit(text, 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()) + self.update_completion.emit(self.prefix, self.parts, + self.cursor_part) def on_mode_left(self, mode): """Clear up when ommand mode was left.