diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 2e2e585b08e..71929d2aad4 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -120,7 +120,7 @@ How many pages to go back. [[bind]] === bind -Syntax: +:bind [*--mode* 'mode'] [*--force*] 'key' ['command']+ +Syntax: +:bind [*--mode* 'mode'] 'key' ['command']+ Bind a key to a command. @@ -133,7 +133,6 @@ Bind a key to a command. * +*-m*+, +*--mode*+: A comma-separated list of modes to bind the key in (default: `normal`). See `:help bindings.commands` for the available modes. -* +*-f*+, +*--force*+: Rebind the key if it is already bound. ==== note * This command does not split arguments after the last argument and handles quotes literally. diff --git a/doc/help/configuring.asciidoc b/doc/help/configuring.asciidoc index f195db2305b..e296eaac493 100644 --- a/doc/help/configuring.asciidoc +++ b/doc/help/configuring.asciidoc @@ -61,8 +61,6 @@ link:commands.html#unbind[`:unbind`] commands: - Binding the key chain `,v` to the `:spawn mpv {url}` command: `:bind ,v spawn mpv {url}` - Unbinding the same key chain: `:unbind ,v` -- Changing an existing binding: `bind --force ,v message-info foo`. Without - `--force`, qutebrowser will show an error because `,v` is already bound. Key chains starting with a comma are ideal for custom bindings, as the comma key will never be used in a default keybinding. @@ -179,13 +177,6 @@ To bind a key in a mode other than `'normal'`, add a `mode` argument: config.bind('', 'prompt-yes', mode='prompt') ---- -If the key is already bound, `force=True` needs to be given to rebind it: - -[source,python] ----- -config.bind('', 'message-info foo', force=True) ----- - To unbind a key (either a key which has been bound before, or a default binding): [source,python] @@ -339,10 +330,10 @@ to do so: [source,python] ---- -def bind_chained(key, *commands, force=False): - config.bind(key, ' ;; '.join(commands), force=force) +def bind_chained(key, *commands): + config.bind(key, ' ;; '.join(commands)) -bind_chained('', 'clear-keychain', 'search', force=True) +bind_chained('', 'clear-keychain', 'search') ---- Avoiding flake8 errors diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index 7f2d1ab41c1..d6dbd1e860e 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -168,13 +168,11 @@ def get_command(self, key, mode): bindings = self.get_bindings_for(mode) return bindings.get(key, None) - def bind(self, key, command, *, mode, force=False, save_yaml=False): + def bind(self, key, command, *, mode, save_yaml=False): """Add a new binding from key to command.""" key = self._prepare(key, mode) log.keyboard.vdebug("Adding binding {} -> {} in mode {}.".format( key, command, mode)) - if key in self.get_bindings_for(mode) and not force: - raise configexc.DuplicateKeyError(key) bindings = self._config.get_obj('bindings.commands') if mode not in bindings: diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py index 12611cd27f9..e496f693b88 100644 --- a/qutebrowser/config/configcommands.py +++ b/qutebrowser/config/configcommands.py @@ -92,7 +92,7 @@ def set(self, win_id, option=None, value=None, temp=False, print_=False): @cmdutils.register(instance='config-commands', maxsplit=1, no_cmd_split=True, no_replace_variables=True) @cmdutils.argument('command', completion=configmodel.bind) - def bind(self, key, command=None, *, mode='normal', force=False): + def bind(self, key, command=None, *, mode='normal'): """Bind a key to a command. Args: @@ -102,7 +102,6 @@ def bind(self, key, command=None, *, mode='normal', force=False): mode: A comma-separated list of modes to bind the key in (default: `normal`). See `:help bindings.commands` for the available modes. - force: Rebind the key if it is already bound. """ if command is None: if utils.is_special_key(key): @@ -118,11 +117,7 @@ def bind(self, key, command=None, *, mode='normal', force=False): return try: - self._keyconfig.bind(key, command, mode=mode, force=force, - save_yaml=True) - except configexc.DuplicateKeyError as e: - raise cmdexc.CommandError("bind: {} - use --force to override!" - .format(e)) + self._keyconfig.bind(key, command, mode=mode, save_yaml=True) except configexc.KeybindingError as e: raise cmdexc.CommandError("bind: {}".format(e)) diff --git a/qutebrowser/config/configexc.py b/qutebrowser/config/configexc.py index 0d20bb09d4a..7b2d0aa044a 100644 --- a/qutebrowser/config/configexc.py +++ b/qutebrowser/config/configexc.py @@ -59,14 +59,6 @@ class KeybindingError(Error): """Raised for issues with keybindings.""" -class DuplicateKeyError(KeybindingError): - - """Raised when there was a duplicate key.""" - - def __init__(self, key): - super().__init__("Duplicate key {}".format(key)) - - class NoOptionError(Error): """Raised when an option was not found.""" diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index 8409834804f..3a411f65886 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -236,13 +236,9 @@ def set(self, name, value): with self._handle_error('setting', name): self._config.set_obj(name, value) - def bind(self, key, command, mode='normal', *, force=False): + def bind(self, key, command, mode='normal'): with self._handle_error('binding', key): - try: - self._keyconfig.bind(key, command, mode=mode, force=force) - except configexc.DuplicateKeyError as e: - raise configexc.KeybindingError('{} - use force=True to ' - 'override!'.format(e)) + self._keyconfig.bind(key, command, mode=mode) def unbind(self, key, mode='normal'): with self._handle_error('unbinding', key): diff --git a/tests/end2end/features/hints.feature b/tests/end2end/features/hints.feature index 8552586fa34..07db63a5f30 100644 --- a/tests/end2end/features/hints.feature +++ b/tests/end2end/features/hints.feature @@ -246,7 +246,7 @@ Feature: Using hints Scenario: Ignoring key presses after auto-following hints When I set hints.auto_follow_timeout to 1000 And I set hints.mode to number - And I run :bind --force , message-error "This error message was triggered via a keybinding which should have been inhibited" + And I run :bind , message-error "This error message was triggered via a keybinding which should have been inhibited" And I open data/hints/html/simple.html And I hint with args "all" And I press the key "f" @@ -259,7 +259,7 @@ Feature: Using hints Scenario: Turning off auto_follow_timeout When I set hints.auto_follow_timeout to 0 And I set hints.mode to number - And I run :bind --force , message-info "Keypress worked!" + And I run :bind , message-info "Keypress worked!" And I open data/hints/html/simple.html And I hint with args "all" And I press the key "f" diff --git a/tests/unit/completion/test_completer.py b/tests/unit/completion/test_completer.py index 8914a956be2..8575cf02d58 100644 --- a/tests/unit/completion/test_completer.py +++ b/tests/unit/completion/test_completer.py @@ -120,7 +120,7 @@ def openurl(url=None, related=False, bg=False, tab=False, window=False, @cmdutils.argument('win_id', win_id=True) @cmdutils.argument('command', completion=miscmodels_patch.command) - def bind(key, win_id, command=None, *, mode='normal', force=False): + def bind(key, win_id, command=None, *, mode='normal'): """docstring.""" pass diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 03fa1dbaedb..a0877cc2304 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -172,19 +172,13 @@ def test_get_reverse_bindings_for(self, keyconf, config_stub, no_bindings, config_stub.val.bindings.commands = {'normal': bindings} assert keyconf.get_reverse_bindings_for('normal') == expected - @pytest.mark.parametrize('force', [True, False]) @pytest.mark.parametrize('key', ['a', '', 'b']) - def test_bind_duplicate(self, keyconf, config_stub, force, key): + def test_bind_duplicate(self, keyconf, config_stub, key): config_stub.val.bindings.default = {'normal': {'a': 'nop', '': 'nop'}} config_stub.val.bindings.commands = {'normal': {'b': 'nop'}} - if force: - keyconf.bind(key, 'message-info foo', mode='normal', force=True) - assert keyconf.get_command(key, 'normal') == 'message-info foo' - else: - with pytest.raises(configexc.DuplicateKeyError): - keyconf.bind(key, 'message-info foo', mode='normal') - assert keyconf.get_command(key, 'normal') == 'nop' + keyconf.bind(key, 'message-info foo', mode='normal') + assert keyconf.get_command(key, 'normal') == 'message-info foo' @pytest.mark.parametrize('mode', ['normal', 'caret']) @pytest.mark.parametrize('command', [ diff --git a/tests/unit/config/test_configcommands.py b/tests/unit/config/test_configcommands.py index b3836f634bd..0f12dd8439d 100644 --- a/tests/unit/config/test_configcommands.py +++ b/tests/unit/config/test_configcommands.py @@ -418,9 +418,8 @@ def test_bind_invalid_mode(self, commands): match='bind: Invalid mode wrongmode!'): commands.bind('a', 'nop', mode='wrongmode') - @pytest.mark.parametrize('force', [True, False]) @pytest.mark.parametrize('key', ['a', 'b', '']) - def test_bind_duplicate(self, commands, config_stub, keyconf, force, key): + def test_bind_duplicate(self, commands, config_stub, keyconf, key): """Run ':bind' with a key which already has been bound.'. Also tests for https://github.com/qutebrowser/qutebrowser/issues/1544 @@ -432,15 +431,8 @@ def test_bind_duplicate(self, commands, config_stub, keyconf, force, key): 'normal': {'b': 'nop'}, } - if force: - commands.bind(key, 'message-info foo', mode='normal', force=True) - assert keyconf.get_command(key, 'normal') == 'message-info foo' - else: - with pytest.raises(cmdexc.CommandError, - match="bind: Duplicate key .* - use --force to " - "override"): - commands.bind(key, 'message-info foo', mode='normal') - assert keyconf.get_command(key, 'normal') == 'nop' + commands.bind(key, 'message-info foo', mode='normal') + assert keyconf.get_command(key, 'normal') == 'message-info foo' def test_bind_none(self, commands, config_stub): config_stub.val.bindings.commands = None diff --git a/tests/unit/config/test_configexc.py b/tests/unit/config/test_configexc.py index 024bbb1d0bf..38a74bcef6c 100644 --- a/tests/unit/config/test_configexc.py +++ b/tests/unit/config/test_configexc.py @@ -43,12 +43,6 @@ def test_backend_error(): assert str(e) == "This setting is not available with the QtWebKit backend!" -def test_duplicate_key_error(): - e = configexc.DuplicateKeyError('asdf') - assert isinstance(e, configexc.KeybindingError) - assert str(e) == "Duplicate key asdf" - - def test_desc_with_text(): """Test ConfigErrorDesc.with_text.""" old = configexc.ConfigErrorDesc("Error text", Exception("Exception text")) diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index fad982dd6aa..99098f26ed5 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -403,12 +403,11 @@ def test_bind_freshly_defined_alias(self, confpy): confpy.read() def test_bind_duplicate_key(self, confpy): - """Make sure we get a nice error message on duplicate key bindings.""" + """Make sure overriding a keybinding works.""" confpy.write("config.bind('H', 'message-info back')") - error = confpy.read(error=True) - - expected = "Duplicate key H - use force=True to override!" - assert str(error.exception) == expected + confpy.read() + expected = {'normal': {'H': 'message-info back'}} + assert config.instance._values['bindings.commands'] == expected def test_bind_none(self, confpy): confpy.write("c.bindings.commands = None",