Allow specifying full layout specifications with options for goto_layout

Fixes #6163
This commit is contained in:
Kovid Goyal 2023-04-08 13:35:38 +05:30
parent d9d2e31318
commit 373c05943f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 38 additions and 9 deletions

View File

@ -25,12 +25,14 @@ class GotoLayout(RemoteCommand):
desc = ( desc = (
'Set the window layout in the specified tabs (or the active tab if not specified).' 'Set the window layout in the specified tabs (or the active tab if not specified).'
' You can use special match value :code:`all` to set the layout in all tabs.' ' You can use special match value :code:`all` to set the layout in all tabs.'
' In case there are multiple layouts with the same name but different options,'
' specify the full layout definition or a unique prefix of the full definition.'
) )
options_spec = MATCH_TAB_OPTION options_spec = MATCH_TAB_OPTION
args = RemoteCommand.Args( args = RemoteCommand.Args(
spec='LAYOUT_NAME', count=1, json_field='layout', spec='LAYOUT_NAME', count=1, json_field='layout',
completion=RemoteCommand.CompletionSpec.from_string('type:keyword group:"Layout" kwds:' + ','.join(layout_names())), completion=RemoteCommand.CompletionSpec.from_string('type:keyword group:"Layout" kwds:' + ','.join(layout_names())),
args_choices=layout_names) )
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
if len(args) != 1: if len(args) != 1:
@ -44,7 +46,7 @@ class GotoLayout(RemoteCommand):
try: try:
tab.goto_layout(payload_get('layout'), raise_exception=True) tab.goto_layout(payload_get('layout'), raise_exception=True)
except ValueError: except ValueError:
raise UnknownLayout('The layout {} is unknown or disabled'.format(payload_get('layout'))) raise UnknownLayout('The layout {} is unknown or disabled or the name is ambiguous'.format(payload_get('layout')))
return None return None

View File

@ -324,20 +324,47 @@ class Tab: # {{{
@ac('lay', ''' @ac('lay', '''
Switch to the named layout Switch to the named layout
In case there are multiple layouts with the same name and different options,
specify the full layout definition or a unique prefix of the full definition.
For example:: For example::
map f1 goto_layout tall map f1 goto_layout tall
map f2 goto_layout fat:bias=20
''') ''')
def goto_layout(self, layout_name: str, raise_exception: bool = False) -> None: def goto_layout(self, layout_name: str, raise_exception: bool = False) -> None:
layout_name = layout_name.lower() layout_name = layout_name.lower()
if layout_name not in self.enabled_layouts: q, has_colon, rest = layout_name.partition(':')
if raise_exception: matches = []
raise ValueError(layout_name) prefix_matches = []
log_error(f'Unknown or disabled layout: {layout_name}') matched_layout = ''
return for candidate in self.enabled_layouts:
self._set_current_layout(layout_name) x, _, _ = candidate.partition(':')
self.relayout() if x == q:
if candidate == layout_name:
matched_layout = candidate
break
if candidate.startswith(layout_name):
prefix_matches.append(candidate)
matches.append(x)
if not matched_layout:
if len(prefix_matches) == 1:
matched_layout = prefix_matches[0]
elif len(matches) == 1:
matched_layout = matches[0]
if matched_layout:
self._set_current_layout(matched_layout)
self.relayout()
else:
if len(matches) == 0:
if raise_exception:
raise ValueError(layout_name)
log_error(f'Unknown or disabled layout: {layout_name}')
elif len(matches) != 1:
if raise_exception:
raise ValueError(layout_name)
log_error(f'Multiple layouts match: {layout_name}')
@ac('lay', ''' @ac('lay', '''
Toggle the named layout Toggle the named layout