Repository: qutebrowser/qutebrowser

Issue:
"AttributeError: 'NoneType' object has no attribute 'desc'" when doing :bind the second time
`:bind ,x message-info foo` the first time works fine. When typing `:bind ,x ` (with a trailing space) the second time, this happens:

```
13:01:17 DEBUG    completion completer:schedule_completion_update:192 Scheduling completion update.
13:01:17 DEBUG    completion completer:schedule_completion_update:189 Ignoring update because there were no changes.
13:01:17 DEBUG    completion completer:_partition:132 partitioning ['bind', ' ,x', ' '] around position 8
13:01:17 DEBUG    completion completer:_partition:144 partitioned: ['bind', ',x'] '' []
13:01:17 DEBUG    completion completer:_update_completion:220 Updating completion: ['bind', ',x']  []
13:01:17 DEBUG    completion completer:_get_new_completion:80 Before removing flags: ['bind', ',x']
13:01:17 DEBUG    completion completer:_get_new_completion:82 After removing flags: ['bind', ',x']
13:01:17 DEBUG    completion debug:__exit__:264 Starting bind completion took 0.000124 seconds.
13:01:17 ERROR    misc       crashsignal:exception_hook:210 Uncaught exception
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py", line 236, in _update_completion
    model = func(*args)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/miscmodels.py", line 133, in bind
    data = [(cmd_name, cmd.desc, key)]
AttributeError: 'NoneType' object has no attribute 'desc'
```

cc @rcorre 


Discussion:

Resolving patch:
diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py
--- a/qutebrowser/completion/models/miscmodels.py
+++ b/qutebrowser/completion/models/miscmodels.py
@@ -126,11 +126,12 @@ def bind(key):
         key: the key being bound.
     """
     model = completionmodel.CompletionModel(column_widths=(20, 60, 20))
-    cmd_name = objreg.get('key-config').get_bindings_for('normal').get(key)
+    cmd_text = objreg.get('key-config').get_bindings_for('normal').get(key)
 
-    if cmd_name:
+    if cmd_text:
+        cmd_name = cmd_text.split(' ')[0]
         cmd = cmdutils.cmd_dict.get(cmd_name)
-        data = [(cmd_name, cmd.desc, key)]
+        data = [(cmd_text, cmd.desc, key)]
         model.add_category(listcategory.ListCategory("Current", data))
 
     cmdlist = _get_cmd_completions(include_hidden=True, include_aliases=True)


Test patch:
diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py
--- a/tests/unit/completion/test_models.py
+++ b/tests/unit/completion/test_models.py
@@ -583,7 +583,7 @@ def test_bind_completion(qtmodeltester, monkeypatch, stubs, config_stub,
     _patch_cmdutils(monkeypatch, stubs,
                     'qutebrowser.completion.models.miscmodels.cmdutils')
     config_stub.data['aliases'] = {'rock': 'roll'}
-    key_config_stub.set_bindings_for('normal', {'s': 'stop',
+    key_config_stub.set_bindings_for('normal', {'s': 'stop now',
                                                 'rr': 'roll',
                                                 'ro': 'rock'})
     model = miscmodels.bind('s')
@@ -593,14 +593,14 @@ def test_bind_completion(qtmodeltester, monkeypatch, stubs, config_stub,
 
     _check_completions(model, {
         "Current": [
-            ('stop', 'stop qutebrowser', 's'),
+            ('stop now', 'stop qutebrowser', 's'),
         ],
         "Commands": [
             ('drop', 'drop all user data', ''),
             ('hide', '', ''),
             ('rock', "Alias for 'roll'", 'ro'),
             ('roll', 'never gonna give you up', 'rr'),
-            ('stop', 'stop qutebrowser', 's'),
+            ('stop', 'stop qutebrowser', ''),
         ]
     })