Error on mode/command mismatch with :bind.

Resolves #1964 (:bind should error for mode/command mismatch)
This commit is contained in:
Ryan Roden-Corrent 2016-09-22 12:17:25 -04:00
parent 6fdd007dbb
commit 14f8ec8754
2 changed files with 24 additions and 7 deletions

View File

@ -177,12 +177,13 @@ class KeyConfigParser(QObject):
mode)) mode))
return return
mode = self._normalize_sectname(mode) modenames = self._normalize_sectname(mode).split(',')
for m in mode.split(','): for m in modenames:
if m not in configdata.KEY_DATA: if m not in configdata.KEY_DATA:
raise cmdexc.CommandError("Invalid mode {}!".format(m)) raise cmdexc.CommandError("Invalid mode {}!".format(m))
try: try:
self._validate_command(command) modes = [usertypes.KeyMode[m] for m in modenames]
self._validate_command(command, modes)
except KeyConfigError as e: except KeyConfigError as e:
raise cmdexc.CommandError(str(e)) raise cmdexc.CommandError(str(e))
try: try:
@ -192,7 +193,7 @@ class KeyConfigParser(QObject):
"override!".format(str(e.keychain))) "override!".format(str(e.keychain)))
except KeyConfigError as e: except KeyConfigError as e:
raise cmdexc.CommandError(e) raise cmdexc.CommandError(e)
for m in mode.split(','): for m in modenames:
self.changed.emit(m) self.changed.emit(m)
self._mark_config_dirty() self._mark_config_dirty()
@ -331,8 +332,13 @@ class KeyConfigParser(QObject):
self.is_dirty = True self.is_dirty = True
self.config_dirty.emit() self.config_dirty.emit()
def _validate_command(self, line): def _validate_command(self, line, modes=None):
"""Check if a given command is valid.""" """Check if a given command is valid.
Args:
line: The commandline to validate.
modes: A list of modes to validate the commands for, or None.
"""
from qutebrowser.config import config from qutebrowser.config import config
if line == self.UNBOUND_COMMAND: if line == self.UNBOUND_COMMAND:
return return
@ -352,8 +358,15 @@ class KeyConfigParser(QObject):
commands = [c.split(maxsplit=1)[0].strip() for c in commands] commands = [c.split(maxsplit=1)[0].strip() for c in commands]
for cmd in commands: for cmd in commands:
aliases = config.section('aliases') aliases = config.section('aliases')
if cmd not in cmdutils.cmd_dict and cmd not in aliases: if cmd in cmdutils.cmd_dict:
cmdname = cmd
elif cmd in aliases:
cmdname = aliases[cmd].split(maxsplit=1)[0].strip()
else:
raise KeyConfigError("Invalid command '{}'!".format(cmd)) raise KeyConfigError("Invalid command '{}'!".format(cmd))
cmd_obj = cmdutils.cmd_dict[cmdname]
for m in modes or []:
cmd_obj.validate_mode(m)
def _read_command(self, line): def _read_command(self, line):
"""Read a command from a line.""" """Read a command from a line."""

View File

@ -73,6 +73,10 @@ Feature: Keyboard input
And I run :bind <test26> And I run :bind <test26>
Then the message "<test26> is bound to 'mib' in normal mode" should be shown Then the message "<test26> is bound to 'mib' in normal mode" should be shown
Scenario: Binding with an unsupported mode
When I run :bind --mode=caret test27 rl-unix-filename-rubout
Then the error "rl-unix-filename-rubout: This command is only allowed in command/prompt mode, not caret." should be shown
# :unbind # :unbind
Scenario: Binding and unbinding a keychain Scenario: Binding and unbinding a keychain