New config: More powerful :config- commands: remove

- `:config-remove-list` command to remove items from a list.
- `:config-remove-dict` command to remove items from a dict.
- Test coverage.

Continues #2794
This commit is contained in:
Milo Gertjejansen 2018-10-10 20:23:44 -05:00
parent 3e07c4ce0f
commit 9fd57b9be0
2 changed files with 108 additions and 0 deletions

View File

@ -300,6 +300,59 @@ class ConfigCommands:
option_value[key] = value
self._config.update_mutables(save_yaml=not temp)
@cmdutils.register(instance='config-commands')
@cmdutils.argument('option', completion=configmodel.list_option)
def config_remove_list(self, option, value, temp=False):
"""Remove a value from a list.
Args:
option: The name of the option.
value: The value to remove from the list.
temp: Set value temporarily until qutebrowser is closed.
"""
opt = self._config.get_opt(option)
valid_list_types = (configtypes.List, configtypes.ListOrValue)
if not isinstance(opt.typ, valid_list_types):
raise cmdexc.CommandError(":config-remove-list can only be used "
"for lists")
with self._handle_config_error():
option_value = self._config.get_mutable_obj(option)
if value not in option_value:
raise cmdexc.CommandError("{} is not in {}!".format(value,
option))
option_value.remove(value)
self._config.update_mutables(save_yaml=not temp)
@cmdutils.register(instance='config-commands')
@cmdutils.argument('option', completion=configmodel.dict_option)
def config_remove_dict(self, option, key, temp=False):
"""Remove a key from a dict.
Args:
option: The name of the option.
key: The key to remove from the dict.
temp: Set value temporarily until qutebrowser is closed.
"""
opt = self._config.get_opt(option)
if not isinstance(opt.typ, configtypes.Dict):
raise cmdexc.CommandError(":config-remove-dict can only be used "
"for dicts")
with self._handle_config_error():
option_value = self._config.get_mutable_obj(option)
if key not in option_value:
raise cmdexc.CommandError("{} is not in {}!".format(key,
option))
del option_value[key]
self._config.update_mutables(save_yaml=not temp)
@cmdutils.register(instance='config-commands')
def config_clear(self, save=False):
"""Set all settings back to their default.

View File

@ -355,6 +355,61 @@ class TestAdd:
commands.config_add_dict('aliases', 'missingkey', value)
class TestRemove:
"""Test :config-add-list and :config-add-dict."""
@pytest.mark.parametrize('value', ['25%', '50%'])
@pytest.mark.parametrize('temp', [True, False])
def test_remove_list(self, commands, config_stub, yaml_value, value, temp):
name = 'zoom.levels'
commands.config_remove_list(name, value, temp=temp)
assert value not in config_stub.get(name)
if temp:
assert yaml_value(name) == configutils.UNSET
else:
assert value not in yaml_value(name)
def test_remove_list_non_list(self, commands):
with pytest.raises(
cmdexc.CommandError,
match=":config-remove-list can only be used for lists"):
commands.config_remove_list('content.javascript.enabled',
'never')
def test_remove_list_no_value(self, commands):
with pytest.raises(
cmdexc.CommandError,
match="never is not in colors.completion.fg!"):
commands.config_remove_list('colors.completion.fg', 'never')
@pytest.mark.parametrize('key', ['w', 'q'])
@pytest.mark.parametrize('temp', [True, False])
def test_remove_dict(self, commands, config_stub, yaml_value, key, temp):
name = 'aliases'
commands.config_remove_dict(name, key, temp=temp)
assert key not in config_stub.get(name)
if temp:
assert yaml_value(name) == configutils.UNSET
else:
assert key not in yaml_value(name)
def test_remove_dict_non_dict(self, commands):
with pytest.raises(
cmdexc.CommandError,
match=":config-remove-dict can only be used for dicts"):
commands.config_remove_dict('content.javascript.enabled',
'never')
def test_remove_dict_no_value(self, commands):
with pytest.raises(
cmdexc.CommandError,
match="never is not in aliases!"):
commands.config_remove_dict('aliases', 'never')
class TestUnsetAndClear:
"""Test :config-unset and :config-clear."""