Merge branch 'rcorre-show_binding2'

This commit is contained in:
Florian Bruhin 2016-05-10 23:48:30 +02:00
commit 62d35db16a
6 changed files with 73 additions and 33 deletions

View File

@ -149,8 +149,8 @@ Contributors, sorted by the number of commits in descending order:
* Felix Van der Jeugt
* Martin Tournoij
* Raphael Pierzina
* Joel Torstensson
* Ryan Roden-Corrent
* Joel Torstensson
* Patric Schmitz
* Claude
* Corentin Julé

View File

@ -94,13 +94,14 @@ How many pages to go back.
[[bind]]
=== bind
Syntax: +:bind [*--mode* 'MODE'] [*--force*] 'key' 'command'+
Syntax: +:bind [*--mode* 'MODE'] [*--force*] 'key' ['command']+
Bind a key to a command.
==== positional arguments
* +'key'+: The keychain or special key (inside `<...>`) to bind.
* +'command'+: The command to execute, with optional args.
* +'command'+: The command to execute, with optional args, or not given to print the current binding.
==== optional arguments
* +*-m*+, +*--mode*+: A comma-separated list of modes to bind the key in (default: `normal`).

View File

@ -29,7 +29,8 @@ import functools
from PyQt5.QtCore import pyqtSlot
from qutebrowser.completion.models import miscmodels, urlmodel, configmodel
from qutebrowser.completion.models import (miscmodels, urlmodel, configmodel,
base)
from qutebrowser.utils import objreg, usertypes, log, debug
from qutebrowser.config import configdata
@ -119,6 +120,13 @@ def init_session_completion():
_instances[usertypes.Completion.sessions] = model
def _init_empty_completion():
"""Initialize empty completion model."""
log.completion.debug("Initializing empty completion.")
if usertypes.Completion.empty not in _instances:
_instances[usertypes.Completion.empty] = base.BaseCompletionModel()
INITIALIZERS = {
usertypes.Completion.command: _init_command_completion,
usertypes.Completion.helptopic: _init_helptopic_completion,
@ -130,6 +138,7 @@ INITIALIZERS = {
usertypes.Completion.quickmark_by_name: init_quickmark_completions,
usertypes.Completion.bookmark_by_url: init_bookmark_completions,
usertypes.Completion.sessions: init_session_completion,
usertypes.Completion.empty: _init_empty_completion,
}

View File

@ -27,7 +27,7 @@ from PyQt5.QtCore import pyqtSignal, QObject
from qutebrowser.config import configdata, textwrapper
from qutebrowser.commands import cmdutils, cmdexc
from qutebrowser.utils import log, utils, qtutils
from qutebrowser.utils import log, utils, qtutils, message, usertypes
class KeyConfigError(Exception):
@ -150,19 +150,34 @@ class KeyConfigParser(QObject):
data = str(self)
f.write(data)
@cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True)
def bind(self, key, command, *, mode=None, force=False):
@cmdutils.register(instance='key-config', maxsplit=1, no_cmd_split=True,
win_id='win_id',
completion=[usertypes.Completion.empty,
usertypes.Completion.command])
def bind(self, key, win_id, command=None, *, mode=None, force=False):
"""Bind a key to a command.
Args:
key: The keychain or special key (inside `<...>`) to bind.
command: The command to execute, with optional args.
command: The command to execute, with optional args, or None to
print the current binding.
mode: A comma-separated list of modes to bind the key in
(default: `normal`).
force: Rebind the key if it is already bound.
"""
if mode is None:
mode = 'normal'
if command is None:
cmd = self.get_bindings_for(mode).get(key, None)
if cmd is None:
message.info(win_id, "{} is unbound in {} mode".format(
key, mode))
else:
message.info(win_id, "{} is bound to '{}' in {} mode".format(
key, cmd, mode))
return
mode = self._normalize_sectname(mode)
for m in mode.split(','):
if m not in configdata.KEY_DATA:

View File

@ -238,7 +238,8 @@ KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt',
# Available command completions
Completion = enum('Completion', ['command', 'section', 'option', 'value',
'helptopic', 'quickmark_by_name',
'bookmark_by_url', 'url', 'tab', 'sessions'])
'bookmark_by_url', 'url', 'tab', 'sessions',
'empty'])
# Exit statuses for errors. Needs to be an int for sys.exit.

View File

@ -6,46 +6,60 @@ Feature: Keyboard input
# :bind
Scenario: Binding a keychain
When I run :bind test1 message-info test1
And I press the keys "test1"
Then the message "test1" should be shown
When I run :bind test01 message-info test01
And I press the keys "test01"
Then the message "test01" should be shown
Scenario: Binding an invalid command
When I run :bind test2 abcd
When I run :bind test02 abcd
Then the error "Invalid command 'abcd'!" should be shown
Scenario: Binding with invalid mode.
When I run :bind --mode abcd test3 message-info test3
When I run :bind --mode abcd test03 message-info test03
Then the error "Invalid mode abcd!" should be shown
Scenario: Double-binding a key
When I run :bind test4 message-info test4
And I run :bind test4 message-info test4-2
And I press the keys "test4"
Then the error "Duplicate keychain test4 - use --force to override!" should be shown
And the message "test4" should be shown
When I run :bind test04 message-info test04
And I run :bind test04 message-info test04-2
And I press the keys "test04"
Then the error "Duplicate keychain test04 - use --force to override!" should be shown
And the message "test04" should be shown
Scenario: Double-binding with --force
When I run :bind test5 message-info test5
And I run :bind --force test5 message-info test5-2
And I press the keys "test5"
Then the message "test5-2" should be shown
When I run :bind test05 message-info test05
And I run :bind --force test05 message-info test05-2
And I press the keys "test05"
Then the message "test05-2" should be shown
Scenario: Printing an unbound key
When I run :bind test06
Then the message "test06 is unbound in normal mode" should be shown
Scenario: Printing a bound key
When I run :bind test07 message-info foo
And I run :bind test07
Then the message "test07 is bound to 'message-info foo' in normal mode" should be shown
Scenario: Printing a bound key in a given mode
When I run :bind --mode=caret test08 message-info bar
And I run :bind --mode=caret test08
Then the message "test08 is bound to 'message-info bar' in caret mode" should be shown
# :unbind
Scenario: Binding and unbinding a keychain
When I run :bind test6 message-error test6
And I run :unbind test6
And I press the keys "test6"
Then "test6" should not be logged
When I run :bind test09 message-error test09
And I run :unbind test09
And I press the keys "test09"
Then "test09" should not be logged
Scenario: Unbinding with invalid mode.
When I run :unbind test7 abcd
When I run :unbind test10 abcd
Then the error "Invalid mode abcd!" should be shown
Scenario: Unbinding with invalid keychain.
When I run :unbind test8
Then the error "Can't find binding 'test8' in section 'normal'!" should be shown
When I run :unbind test11
Then the error "Can't find binding 'test11' in section 'normal'!" should be shown
Scenario: Unbinding a built-in binding
When I run :unbind o
@ -56,12 +70,12 @@ Feature: Keyboard input
# :clear-keychain
Scenario: Clearing the keychain
When I run :bind foo message-error test9
And I run :bind bar message-info test9-2
When I run :bind foo message-error test12
And I run :bind bar message-info test12-2
And I press the keys "fo"
And I run :clear-keychain
And I press the keys "bar"
Then the message "test9-2" should be shown
Then the message "test12-2" should be shown
# input -> forward-unbound-keys