diff --git a/TODO b/TODO index 0651d5586..105678b4f 100644 --- a/TODO +++ b/TODO @@ -56,7 +56,6 @@ Improvements / minor features - Zoom with ctrl + mousewheel - search highlighting - max height for completion (be smaller if possible) -- tab should directly insert word and space if there's only one option - vertical tabbar - reload config command - config changed signals for sections (optimization) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 92a27f676..b1f905f20 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -266,6 +266,10 @@ DATA = OrderedDict([ "How many commands to save in the history. 0: no history / -1: " "unlimited"), + ('quick-complete', + SettingValue(types.Bool(), 'true'), + "Whether to move on to the next part when there's only one possible " + "completion left."), )), ('input', sect.KeyValue( diff --git a/qutebrowser/widgets/_completion.py b/qutebrowser/widgets/_completion.py index fd4741936..0b2f6db84 100644 --- a/qutebrowser/widgets/_completion.py +++ b/qutebrowser/widgets/_completion.py @@ -65,7 +65,10 @@ class CompletionView(QTreeView): Signals: change_completed_part: Text which should be substituted for the word we're currently completing. - arg: The text to change to. + arg 0: The text to change to. + arg 1: True if the text should be set + immediately, without continuing + completing the current field. """ STYLESHEET = """ @@ -100,7 +103,7 @@ class CompletionView(QTreeView): # FIXME style scrollbar - change_completed_part = pyqtSignal(str) + change_completed_part = pyqtSignal(str, bool) def __init__(self, parent=None): super().__init__(parent) @@ -367,9 +370,15 @@ class CompletionView(QTreeView): if indexes: data = self._model.data(indexes[0]) if data is not None: - self._ignore_change = True - self.change_completed_part.emit(data) - self._ignore_change = False + if (self._model.rowCount(indexes[0].parent()) == 1 and + config.get('completion', 'quick-complete')): + # If we only have one item, we want to apply it immediately + # and go on to the next part. + self.change_completed_part.emit(data, True) + else: + self._ignore_change = True + self.change_completed_part.emit(data, False) + self._ignore_change = False super().selectionChanged(selected, deselected) def resizeEvent(self, e): diff --git a/qutebrowser/widgets/statusbar/_command.py b/qutebrowser/widgets/statusbar/_command.py index 8b567ed37..5e8e60766 100644 --- a/qutebrowser/widgets/statusbar/_command.py +++ b/qutebrowser/widgets/statusbar/_command.py @@ -140,19 +140,32 @@ class Command(MinimalLineEdit): self.setFocus() self.show_cmd.emit() - @pyqtSlot(str) - def on_change_completed_part(self, newtext): + @pyqtSlot(str, bool) + def on_change_completed_part(self, newtext, immediate): """Change the part we're currently completing in the commandline. Args: text: The text to set (string). + immediate: True if the text should be completed immediately + including a trailing space and we shouldn't continue + completing the current item. """ parts = self.parts[:] logger.debug("parts: {}, changing {} to '{}'".format( parts, self.cursor_part, newtext)) parts[self.cursor_part] = newtext + # We want to place the cursor directly after the part we just changed. cursor_str = self.prefix + ' '.join(parts[:self.cursor_part + 1]) - self.setText(self.prefix + ' '.join(parts)) + if immediate: + # If we should complete immediately, we want to move the cursor by + # one more char, to get to the next field. + cursor_str += ' ' + text = self.prefix + ' '.join(parts) + if immediate and self.cursor_part == len(parts) - 1: + # If we should complete immediately and we're completing the last + # part in the commandline, we automatically add a space. + text += ' ' + self.setText(text) logger.debug("Placing cursor after '{}'".format(cursor_str)) self.setCursorPosition(len(cursor_str)) self.setFocus()