New config: More powerful :config- commands: add

Adds the config-add command.

Modifies #2794
This commit is contained in:
Milo Gertjejansen 2018-10-01 22:22:39 -05:00
parent 4060fcc1c6
commit 876a2bdaa1
2 changed files with 81 additions and 0 deletions

View File

@ -47,6 +47,21 @@ def customized_option(*, info):
return model
def structure_option(*, info):
"""A CompletionModel filled with set settings of structures.
Gets lists and dicts and their descriptions.
"""
model = completionmodel.CompletionModel(column_widths=(20, 70, 10))
options = ((opt.name, opt.description, info.config.get_str(opt.name))
for opt in configdata.DATA.values()
if isinstance(info.config.get_obj(opt.name), (list, dict)))
model.add_category(
listcategory.ListCategory("Structure options", options)
)
return model
def value(optname, *values, info):
"""A CompletionModel filled with setting values.

View File

@ -250,6 +250,72 @@ class ConfigCommands:
with self._handle_config_error():
self._config.unset(option, save_yaml=not temp)
@cmdutils.register(instance='config-commands')
@cmdutils.argument('option', completion=configmodel.structure_option)
def config_add(
self, option, key=None, value=None, temp=False, replace=False
):
"""Adds an option.
This adds an element to a dictionary or list. --replace is needed
to override existing values.
Args:
option: The name of the option.
value: The value to place in either the list or the dictionary.
key: The key to set if it's a dictionary.
temp: Don't touch autoconfig.yml.
replace: Whether or not we should replace, default is not.
"""
with self._handle_config_error():
option_value = self._config.get_obj(option)
# Attempt to replace if it's there.
if isinstance(option_value, list):
if value is None:
# In this case our key is teh "value", since we are just
# adding to the list.
option_value.append(key)
if value and replace:
# In this case we are trying to replace something at an
# index.
try:
index = int(key)
if index >= len(option_value):
option_value.append(value)
else:
option_value[int(key)] = value
except:
raise cmdexc.CommandError("The index must be a number")
else:
raise cmdexc.CommandError(
"Use --replace to replace a value at an index")
elif isinstance(option_value, dict):
# Here we are trying to add something to a dictionary.
if value is None and not replace:
raise cmdexc.CommandError((
"{value} should not be empty unless --replace is"
"provided (in which case a 'destroy' will happen)!"
).format(value=value))
if not replace and key in option_value:
raise cmdexc.CommandError((
"{key} already existed in {option} - use --replace"
"to overwrite!"
).format(key=key, option=option))
# If we made it this far with a None value, we should destroy
# the option in the dictionary, otherwise we should insert it.
if value is None:
option_value.pop(key, None)
else:
option_value[key] = value
# Set the option in the config.
self._config.set_obj(option, option_value, pattern=None,
save_yaml=not temp)
@cmdutils.register(instance='config-commands')
def config_clear(self, save=False):
"""Set all settings back to their default.