Add --cycle flag to :set
Chooses the next value from the provided list of values (string-wise comparison). Technically, the 'option!' syntax for toggling bools is now redundant, but a translation from 'option!' to '--cycle option false true' is kept for backwards compatibility. The '--cycle' flag could also be technically optionally, since the only thing that depends on it is preserving the error message for specifying multiple values. (But I think it's best to keep it explicit, as a principle-of-least-surprise thing) Note: The business logic of picking the next value and setting it was moved out to a separate function to avoid tripping pylint's too-many-branches detector. Fixes #47
This commit is contained in:
parent
c57ad91e04
commit
1b5664b72f
@ -149,6 +149,7 @@ Changed
|
||||
- `ui -> window-title-format` now has a new `{backend} ` replacement
|
||||
- `:hint` has a new `--add-history` argument to add the URL to the history for
|
||||
yank/spawn targets.
|
||||
- `:set` now has a `--cycle` flag which lets you cycle through multiple options.
|
||||
|
||||
Deprecated
|
||||
~~~~~~~~~~
|
||||
|
@ -772,13 +772,13 @@ class ConfigManager(QObject):
|
||||
raise cmdexc.CommandError("set: {} - {}".format(
|
||||
e.__class__.__name__, e))
|
||||
|
||||
@cmdutils.register(name='set', instance='config')
|
||||
@cmdutils.register(name='set', instance='config', star_args_optional=True)
|
||||
@cmdutils.argument('section_', completion=Completion.section)
|
||||
@cmdutils.argument('option', completion=Completion.option)
|
||||
@cmdutils.argument('value', completion=Completion.value)
|
||||
@cmdutils.argument('values', completion=Completion.value)
|
||||
@cmdutils.argument('win_id', win_id=True)
|
||||
def set_command(self, win_id, section_=None, option=None, value=None,
|
||||
temp=False, print_=False):
|
||||
def set_command(self, win_id, section_=None, option=None, *values,
|
||||
temp=False, print_=False, cycle=False):
|
||||
"""Set an option.
|
||||
|
||||
If the option name ends with '?', the value of the option is shown
|
||||
@ -793,9 +793,10 @@ class ConfigManager(QObject):
|
||||
Args:
|
||||
section_: The section where the option is in.
|
||||
option: The name of the option.
|
||||
value: The value to set.
|
||||
values: The value to set, or the values to cycle through.
|
||||
temp: Set value temporarily.
|
||||
print_: Print the value after setting.
|
||||
cycle: Cycle through multiple provided values.
|
||||
"""
|
||||
if section_ is not None and option is None:
|
||||
raise cmdexc.CommandError(
|
||||
@ -812,27 +813,48 @@ class ConfigManager(QObject):
|
||||
print_ = True
|
||||
else:
|
||||
with self._handle_config_error():
|
||||
if option.endswith('!') and option != '!' and value is None:
|
||||
if option.endswith('!') and option != '!' and not values:
|
||||
# Handle inversion as special cases of the cycle code path
|
||||
option = option[:-1]
|
||||
val = self.get(section_, option)
|
||||
layer = 'temp' if temp else 'conf'
|
||||
if isinstance(val, bool):
|
||||
self.set(layer, section_, option, str(not val).lower())
|
||||
values = ['false', 'true']
|
||||
else:
|
||||
raise cmdexc.CommandError(
|
||||
"set: Attempted inversion of non-boolean value.")
|
||||
elif value is not None:
|
||||
layer = 'temp' if temp else 'conf'
|
||||
self.set(layer, section_, option, value)
|
||||
else:
|
||||
elif not values:
|
||||
raise cmdexc.CommandError("set: The following arguments "
|
||||
"are required: value")
|
||||
elif not cycle and len(values) > 1:
|
||||
raise cmdexc.CommandError("set: Too many values provided")
|
||||
|
||||
layer = 'temp' if temp else 'conf'
|
||||
self._set_next(layer, section_, option, values)
|
||||
|
||||
if print_:
|
||||
with self._handle_config_error():
|
||||
val = self.get(section_, option, transformed=False)
|
||||
message.info("{} {} = {}".format(section_, option, val))
|
||||
|
||||
def _set_next(self, layer, section_, option, values):
|
||||
"""Set the next value out of a list of values."""
|
||||
if len(values) == 1:
|
||||
# If we have only one value, just set it directly (avoid
|
||||
# breaking stuff like aliases or other pseudo-settings)
|
||||
self.set(layer, section_, option, values[0])
|
||||
else:
|
||||
# Otherwise, use the next valid value from values, or the
|
||||
# first if the current value does not appear in the list
|
||||
assert len(values) > 1
|
||||
val = self.get(section_, option, transformed=False)
|
||||
try:
|
||||
idx = values.index(str(val))
|
||||
idx = (idx + 1) % len(values)
|
||||
value = values[idx]
|
||||
except ValueError:
|
||||
value = values[0]
|
||||
self.set(layer, section_, option, value)
|
||||
|
||||
def set(self, layer, sectname, optname, value, validate=True):
|
||||
"""Set an option.
|
||||
|
||||
|
@ -15,6 +15,10 @@ Feature: Setting settings.
|
||||
When I run :set colors statusbar.bg
|
||||
Then the error "set: The following arguments are required: value" should be shown
|
||||
|
||||
Scenario: With too many values
|
||||
When I run :set colors statusbar.bg green blue
|
||||
Then the error "set: Too many values provided" should be shown
|
||||
|
||||
Scenario: Invalid section
|
||||
When I run :set blah blub foo
|
||||
Then the error "set: Section 'blah' does not exist!" should be shown
|
||||
@ -32,6 +36,26 @@ Feature: Setting settings.
|
||||
When I run :set colors statusbar.bg!
|
||||
Then the error "set: Attempted inversion of non-boolean value." should be shown
|
||||
|
||||
Scenario: Cycling an option
|
||||
When I run :set colors statusbar.bg magenta
|
||||
And I run :set --cycle colors statusbar.bg green magenta blue yellow
|
||||
Then colors -> statusbar.bg should be blue
|
||||
|
||||
Scenario: Cycling an option through the end of the list
|
||||
When I run :set colors statusbar.bg yellow
|
||||
And I run :set --cycle colors statusbar.bg green magenta blue yellow
|
||||
Then colors -> statusbar.bg should be green
|
||||
|
||||
Scenario: Cycling an option that's not on the list
|
||||
When I run :set colors statusbar.bg red
|
||||
And I run :set --cycle colors statusbar.bg green magenta blue yellow
|
||||
Then colors -> statusbar.bg should be green
|
||||
|
||||
Scenario: Cycling through a single option
|
||||
When I run :set colors statusbar.bg red
|
||||
And I run :set --cycle colors statusbar.bg red
|
||||
Then colors -> statusbar.bg should be red
|
||||
|
||||
Scenario: Getting an option
|
||||
When I run :set colors statusbar.bg magenta
|
||||
And I run :set colors statusbar.bg?
|
||||
|
Loading…
Reference in New Issue
Block a user