Use {} for none-dicts and fix keybindings

This commit is contained in:
Florian Bruhin 2017-06-30 18:54:17 +02:00
parent 0115285a84
commit 9cbacf3264
6 changed files with 56 additions and 35 deletions

View File

@ -37,10 +37,8 @@ def custom_headers():
headers[b'DNT'] = dnt
headers[b'X-Do-Not-Track'] = dnt
config_headers = config.val.content.custom_headers
if config_headers is not None:
for header, value in config_headers.items():
headers[header.encode('ascii')] = value.encode('ascii')
for header, value in config.val.content.custom_headers.items():
headers[header.encode('ascii')] = value.encode('ascii')
accept_language = config.val.content.accept_language
if accept_language is not None:

View File

@ -104,9 +104,6 @@ class CommandParser:
The new command string if an alias was found. Default value
otherwise.
"""
if config.val.aliases is None:
return default
parts = text.strip().split(maxsplit=1)
try:
alias = config.val.aliases[parts[0]]

View File

@ -133,12 +133,12 @@ class KeyConfig:
def get_bindings_for(self, mode):
"""Get the combined bindings for the given mode."""
if val.bindings.default:
bindings = dict(val.bindings.default[mode])
else:
bindings = {}
if val.bindings.commands:
bindings.update(val.bindings.default[mode])
bindings = dict(val.bindings.default[mode])
for key, binding in val.bindings.commands[mode].items():
if binding is None:
del bindings[key]
else:
bindings[key] = binding
return bindings
def get_reverse_bindings_for(self, mode):
@ -188,20 +188,22 @@ class KeyConfig:
if key in self.get_bindings_for(mode) and not force:
raise configexc.DuplicateKeyError(key)
val.bindings.commands[mode][key] = command
bindings = self._config.get_obj('bindings.commands')
bindings[mode][key] = command
self._config.update_mutables(save_yaml=save_yaml)
def unbind(self, key, *, mode='normal', save_yaml=False):
"""Unbind the given key in the given mode."""
key = self._prepare(key, mode)
if val.bindings.commands[mode] and key in val.bindings.commands[mode]:
bindings_commands = self._config.get_obj('bindings.commands')
if key in bindings_commands:
# In custom bindings -> remove it
del val.bindings.commands[mode][key]
elif val.bindings.default[mode] and key in val.bindings.default[mode]:
# In default bindings -> shadow it with <unbound>
# FIXME:conf what value to use here?
val.bindings.commands[mode][key] = '<unbound>'
del bindings_commands[mode][key]
elif key in val.bindings.default[mode]:
# In default bindings -> shadow it with None
bindings_commands[mode][key] = None
else:
raise configexc.KeybindingError("Can't find binding '{}' in section '{}'!"
.format(key, mode))

View File

@ -2088,14 +2088,6 @@ bindings.default:
bindings.commands:
default: {}
# normal: {}
# insert: {}
# hint: {}
# passthrough: {}
# command: {}
# prompt: {}
# caret: {}
# register: {}
type:
name: Dict
none_ok: true
@ -2105,7 +2097,9 @@ bindings.commands:
valtype:
name: Dict
keytype: Key
valtype: Command
valtype:
name: Command
none_ok: true
desc: >-
Keybindings mapping keys to commands in different modes.
@ -2132,7 +2126,9 @@ bindings.commands:
with Shift. For special keys (with `<>`-signs), you need to explicitly add
`Shift-` to match a key pressed with shift.
To completely unbind a default binding, bind it to the `nop` command.
If you want a binding to do nothing, bind it to the `nop` command.
If you want a default binding to be passed through to the website, bind it
to null.
Note that some commands which are only useful for bindings (but not used
interactively) are hidden from the command completion. See `:help` for a

View File

@ -729,7 +729,7 @@ class Command(BaseType):
def to_py(self, value):
self._basic_py_validation(value, str)
if not value:
return
return None
# FIXME:conf is it okay to import runners.py here?
from qutebrowser.commands import runners, cmdexc
@ -1034,10 +1034,31 @@ class Dict(BaseType):
raise configexc.ValidationError(
value, "Expected keys {}".format(self.fixed_keys))
def _none_value(self, value=None):
"""Return the value to be used when the setting is None.
Args:
value: An existing value to be mutated when given.
"""
if self.fixed_keys is None:
if value is None:
return {}
else:
assert value == {}, value
return value
else:
if value is None:
return {key: {} for key in self.fixed_keys}
else:
assert value == {}, value
for key in self.fixed_keys:
value[key] = {}
return value
def from_str(self, value):
self._basic_str_validation(value)
if not value:
return None
return self._none_value()
try:
yaml_val = utils.yaml_load(value)
@ -1052,7 +1073,7 @@ class Dict(BaseType):
def to_py(self, value):
self._basic_py_validation(value, dict)
if not value:
return None
return self._none_value(value)
self._validate_keys(value)
@ -1280,6 +1301,9 @@ class Padding(Dict):
fixed_keys=['top', 'bottom', 'left', 'right'],
none_ok=none_ok)
def _none_value(self, _value=None):
return None
def to_py(self, value):
d = super().to_py(value)
if not d:

View File

@ -252,8 +252,12 @@ class TestAll:
def test_none_ok_true(self, klass):
"""Test None and empty string values with none_ok=True."""
typ = klass(none_ok=True)
assert typ.from_str('') is None
assert typ.to_py(None) is None
if isinstance(typ, configtypes.Dict):
expected = typ._none_value()
else:
expected = None
assert typ.from_str('') == expected
assert typ.to_py(None) == expected
assert typ.to_str(None) == ''
@pytest.mark.parametrize('method, value', [