Repository: qutebrowser/qutebrowser

Issue:
:enter-mode is buggy with some modes
- `:enter-mode command;;command-accept`:

```
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 198, in _process_args
    process_pos_args(args.command)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 263, in process_pos_args
    commandrunner.run_safely_init(cmd[1:])
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/runners.py", line 266, in run_safely_init
    self.run(text, count)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/runners.py", line 249, in run
    result.cmd.run(self._win_id, args)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/command.py", line 505, in run
    self.handler(*posargs, **kwargs)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/mainwindow/statusbar/command.py", line 179, in command_accept
    self.got_cmd.emit(prefixes[text[0]] + text[1:])
IndexError: string index out of range
```
- `:enter-mode hint`, `<Escape>`:

```
Traceback (most recent call last):
  File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeparsers.py", line 220, in on_keystring_updated
    hintmanager.handle_partial_key(keystr)
  File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/hints.py", line 840, in handle_partial_key
    for (string, elems) in self._context.elems.items():
AttributeError: 'NoneType' object has no attribute 'elems'
```
- `:enter-mode prompt` and some keypresses:

```
Traceback (most recent call last):
  File "/home/john/dev/qutebrowser/qutebrowser/app.py", line 863, in eventFilter
    return handler(event)
  File "/home/john/dev/qutebrowser/qutebrowser/app.py", line 823, in _handle_key_event
    return man.eventFilter(event)
  File "/home/john/dev/qutebrowser/qutebrowser/keyinput/modeman.py", line 318, in eventFilter
    return self._eventFilter_keypress(event)
  File "/home/john/dev/qutebrowser/qutebrowser/keyinput/modeman.py", line 170, in _eventFilter_keypress
    handled = parser.handle(event)
  File "/home/john/dev/qutebrowser/qutebrowser/keyinput/basekeyparser.py", line 305, in handle
    handled = self._handle_special_key(e)
  File "/home/john/dev/qutebrowser/qutebrowser/keyinput/basekeyparser.py", line 134, in _handle_special_key
    self.execute(cmdstr, self.Type.special)
  File "/home/john/dev/qutebrowser/qutebrowser/keyinput/keyparser.py", line 44, in execute
    self._commandrunner.run(cmdstr, count)
  File "/home/john/dev/qutebrowser/qutebrowser/commands/runners.py", line 291, in run
    result.cmd.run(self._win_id, args)
  File "/home/john/dev/qutebrowser/qutebrowser/commands/command.py", line 524, in run
    self.handler(*posargs, **kwargs)
  File "/home/john/dev/qutebrowser/qutebrowser/mainwindow/statusbar/prompter.py", line 248, in prompt_accept
    if (self._question.mode == usertypes.PromptMode.user_pwd and
AttributeError: 'NoneType' object has no attribute 'mode'
```

I guess `:enter-mode` should simply be disallowed for non-"dumb" modes like `insert`, `passthrough`, `caret`, `normal`



Discussion:

Resolving patch:
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -265,6 +265,10 @@ def enter_mode(self, mode):
             m = usertypes.KeyMode[mode]
         except KeyError:
             raise cmdexc.CommandError("Mode {} does not exist!".format(mode))
+        if m in [usertypes.KeyMode.hint, usertypes.KeyMode.command,
+                 usertypes.KeyMode.yesno, usertypes.KeyMode.prompt]:
+            raise cmdexc.CommandError(
+                "Mode {} can't be entered manually!".format(mode))
         self.enter(m, 'command')
 
     @pyqtSlot(usertypes.KeyMode, str, bool)


Test patch:
diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature
--- a/tests/end2end/features/misc.feature
+++ b/tests/end2end/features/misc.feature
@@ -642,3 +642,9 @@ Feature: Various utility commands.
         And I run :command-accept
         And I set general -> private-browsing to false
         Then the message "blah" should be shown
+
+    ## Modes blacklisted for :enter-mode
+
+    Scenario: Trying to enter command mode with :enter-mode
+        When I run :enter-mode command
+        Then the error "Mode command can't be entered manually!" should be shown