Repository: qutebrowser/qutebrowser

Issue:
Errors when `completion show` setting is false
Pressing up, down, or tab when there are completions available but the `completion show` setting is `false` crashes qutebrowser. The relevant error:

```
  ...
  File "/home/marshall/Github/qutebrowser/qutebrowser/completion/completionwidget.py", line 164, in _next_idx
    idx = self.selectionModel().currentIndex()
AttributeError: 'NoneType' object has no attribute 'currentIndex'
```

This appears after the recent completion fixes from @rcorre.

Generally, the completion `show` and `auto-open` options don't seem to make sense. Before the change, `show` would do what I expected `auto-open` to do (turning it off hides the completion window until the user asks for it with up, down, or tab). `auto-open` doesn't do anything (before or after the change), as far as I can tell.



Discussion:
I can reproduce this with `show` being `false` and `auto-open` being `false`.

I think the intention was for `auto-open` to open the completion when pressing tab, and then hiding it again when completing is done. It seems indeed like that broke at some point, but no idea when...

I remember this working at some point during my work on completions, so I'm guessing I broke it pretty recently and  missed it in testing somehow.


Resolving patch:
diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py
--- a/qutebrowser/completion/completionwidget.py
+++ b/qutebrowser/completion/completionwidget.py
@@ -192,10 +192,13 @@ def _next_prev_item(self, prev):
         Args:
             prev: True for prev item, False for next one.
         """
-        idx = self._next_idx(prev)
-        qtutils.ensure_valid(idx)
-        self.selectionModel().setCurrentIndex(
-            idx, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
+        # selmodel can be None if 'show' and 'auto-open' are set to False
+        # https://github.com/The-Compiler/qutebrowser/issues/1731
+        selmodel = self.selectionModel()
+        if (selmodel is not None):
+            idx = self._next_idx(prev)
+            selmodel.setCurrentIndex(idx,
+                QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
 
     def set_model(self, model):
         """Switch completion to a new model.


Test patch:
diff --git a/tests/unit/completion/test_completionwidget.py b/tests/unit/completion/test_completionwidget.py
--- a/tests/unit/completion/test_completionwidget.py
+++ b/tests/unit/completion/test_completionwidget.py
@@ -119,6 +119,8 @@ def test_maybe_resize_completion(completionview, config_stub, qtbot):
     ([['Aa'], []], -1, 'Aa'),
     ([['Aa'], [], []], 1, 'Aa'),
     ([['Aa'], [], []], -1, 'Aa'),
+    ([[]], 1, None),
+    ([[]], -1, None),
 ])
 def test_completion_item_next_prev(tree, count, expected, completionview):
     """Test that on_next_prev_item moves the selection properly.
@@ -146,3 +148,13 @@ def test_completion_item_next_prev(tree, count, expected, completionview):
             completionview.completion_item_next()
     idx = completionview.selectionModel().currentIndex()
     assert filtermodel.data(idx) == expected
+
+
+def test_completion_item_next_prev_no_model(completionview):
+    """Test that next/prev won't crash with no model set.
+
+    This can happen if completion.show and completion.auto-open are False.
+    Regression test for issue #1722.
+    """
+    completionview.completion_item_prev()
+    completionview.completion_item_next()