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
|
- `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
|
- `:hint` has a new `--add-history` argument to add the URL to the history for
|
||||||
yank/spawn targets.
|
yank/spawn targets.
|
||||||
|
- `:set` now has a `--cycle` flag which lets you cycle through multiple options.
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
@ -772,13 +772,13 @@ class ConfigManager(QObject):
|
|||||||
raise cmdexc.CommandError("set: {} - {}".format(
|
raise cmdexc.CommandError("set: {} - {}".format(
|
||||||
e.__class__.__name__, e))
|
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('section_', completion=Completion.section)
|
||||||
@cmdutils.argument('option', completion=Completion.option)
|
@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)
|
@cmdutils.argument('win_id', win_id=True)
|
||||||
def set_command(self, win_id, section_=None, option=None, value=None,
|
def set_command(self, win_id, section_=None, option=None, *values,
|
||||||
temp=False, print_=False):
|
temp=False, print_=False, cycle=False):
|
||||||
"""Set an option.
|
"""Set an option.
|
||||||
|
|
||||||
If the option name ends with '?', the value of the option is shown
|
If the option name ends with '?', the value of the option is shown
|
||||||
@ -793,9 +793,10 @@ class ConfigManager(QObject):
|
|||||||
Args:
|
Args:
|
||||||
section_: The section where the option is in.
|
section_: The section where the option is in.
|
||||||
option: The name of the option.
|
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.
|
temp: Set value temporarily.
|
||||||
print_: Print the value after setting.
|
print_: Print the value after setting.
|
||||||
|
cycle: Cycle through multiple provided values.
|
||||||
"""
|
"""
|
||||||
if section_ is not None and option is None:
|
if section_ is not None and option is None:
|
||||||
raise cmdexc.CommandError(
|
raise cmdexc.CommandError(
|
||||||
@ -812,27 +813,48 @@ class ConfigManager(QObject):
|
|||||||
print_ = True
|
print_ = True
|
||||||
else:
|
else:
|
||||||
with self._handle_config_error():
|
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]
|
option = option[:-1]
|
||||||
val = self.get(section_, option)
|
val = self.get(section_, option)
|
||||||
layer = 'temp' if temp else 'conf'
|
|
||||||
if isinstance(val, bool):
|
if isinstance(val, bool):
|
||||||
self.set(layer, section_, option, str(not val).lower())
|
values = ['false', 'true']
|
||||||
else:
|
else:
|
||||||
raise cmdexc.CommandError(
|
raise cmdexc.CommandError(
|
||||||
"set: Attempted inversion of non-boolean value.")
|
"set: Attempted inversion of non-boolean value.")
|
||||||
elif value is not None:
|
elif not values:
|
||||||
layer = 'temp' if temp else 'conf'
|
|
||||||
self.set(layer, section_, option, value)
|
|
||||||
else:
|
|
||||||
raise cmdexc.CommandError("set: The following arguments "
|
raise cmdexc.CommandError("set: The following arguments "
|
||||||
"are required: value")
|
"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_:
|
if print_:
|
||||||
with self._handle_config_error():
|
with self._handle_config_error():
|
||||||
val = self.get(section_, option, transformed=False)
|
val = self.get(section_, option, transformed=False)
|
||||||
message.info("{} {} = {}".format(section_, option, val))
|
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):
|
def set(self, layer, sectname, optname, value, validate=True):
|
||||||
"""Set an option.
|
"""Set an option.
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ Feature: Setting settings.
|
|||||||
When I run :set colors statusbar.bg
|
When I run :set colors statusbar.bg
|
||||||
Then the error "set: The following arguments are required: value" should be shown
|
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
|
Scenario: Invalid section
|
||||||
When I run :set blah blub foo
|
When I run :set blah blub foo
|
||||||
Then the error "set: Section 'blah' does not exist!" should be shown
|
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!
|
When I run :set colors statusbar.bg!
|
||||||
Then the error "set: Attempted inversion of non-boolean value." should be shown
|
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
|
Scenario: Getting an option
|
||||||
When I run :set colors statusbar.bg magenta
|
When I run :set colors statusbar.bg magenta
|
||||||
And I run :set colors statusbar.bg?
|
And I run :set colors statusbar.bg?
|
||||||
|
Loading…
Reference in New Issue
Block a user