kitty @ set-enabled-layouts

Fixes #4129
This commit is contained in:
Kovid Goyal 2021-10-17 18:30:34 +05:30
parent 16365f2014
commit 716ff187f9
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 86 additions and 9 deletions

View File

@ -34,6 +34,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- A new mappable action ``swap_with_window`` to swap the current window with another window in the tab, visually
- A new :program:`remote control command <kitty @ set-enabled-layouts>` to change
the enabled layouts in a tab (:iss:`4129`)
- A new option :opt:`bell_path` to specify the path to a sound file
to use as the bell sound

View File

@ -518,11 +518,11 @@ def window_size(val: str) -> Tuple[int, str]:
return positive_int(val.rstrip('c')), unit
def to_layout_names(raw: str) -> List[str]:
def parse_layout_names(parts: Iterable[str]) -> List[str]:
from kitty.layout.interface import all_layouts
parts = [x.strip().lower() for x in raw.split(',')]
ans: List[str] = []
ans = []
for p in parts:
p = p.lower()
if p in ('*', 'all'):
ans.extend(sorted(all_layouts))
continue
@ -533,6 +533,10 @@ def to_layout_names(raw: str) -> List[str]:
return uniq(ans)
def to_layout_names(raw: str) -> List[str]:
return parse_layout_names((x.strip() for x in raw.split(',')))
def window_border_width(x: Union[str, int, float]) -> Tuple[float, str]:
unit = 'pt'
if isinstance(x, str):

View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
from typing import TYPE_CHECKING, Iterable, Optional
from kitty.fast_data_types import get_options
from kitty.options.utils import parse_layout_names
from .base import (
MATCH_TAB_OPTION, ArgsType, Boss, PayloadGetType, PayloadType, RCOptions,
RemoteCommand, ResponseType, Window
)
if TYPE_CHECKING:
from kitty.cli_stub import SetEnabledLayoutsRCOptions as CLIOptions
def layout_names() -> Iterable[str]:
from kitty.layout.interface import all_layouts
return all_layouts.keys()
class SetEnabledLayouts(RemoteCommand):
'''
layouts+: The list of layout names
match: Which tab to change the layout of
configured: Boolean indicating whether to change the configured value
'''
short_desc = 'Set the enabled layouts in a tab'
desc = (
'Set the enabled layouts in the specified tab (or the active tab if not specified).'
' You can use special match value :italic:`all` to set the layout in all tabs. If the'
' current layout of the tab is not included in the enabled layouts its layout is changed'
' to the first enabled layout.'
)
options_spec = MATCH_TAB_OPTION + '''\n\n
--configured
type=bool-set
Change the default enabled layout value so that the new value takes effect for all newly created tabs
as well.
'''
argspec = 'LAYOUTS'
args_completion = {'names': ('Layouts', layout_names)}
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
if len(args) < 1:
self.fatal('At least one layout must be specified')
try:
layouts = parse_layout_names(args)
except ValueError as err:
self.fatal(str(err))
return {'layouts': layouts, 'match': opts.match}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
tabs = self.tabs_for_match_payload(boss, window, payload_get)
layouts = parse_layout_names(payload_get('layouts'))
if payload_get('configured'):
get_options().enabled_layouts = list(layouts)
for tab in tabs:
if tab:
tab.set_enabled_layouts(layouts)
set_enabled_layouts = SetEnabledLayouts()

View File

@ -10,8 +10,8 @@ from contextlib import suppress
from functools import partial
from operator import attrgetter
from typing import (
Any, Deque, Dict, Generator, Iterator, List, NamedTuple, Optional, Pattern,
Sequence, Tuple, Union, cast
Any, Deque, Dict, Generator, Iterable, Iterator, List, NamedTuple,
Optional, Pattern, Sequence, Tuple, Union, cast
)
from .borders import Border, Borders
@ -121,14 +121,17 @@ class Tab: # {{{
self._set_current_layout(l0)
self.startup(session_tab)
def apply_options(self) -> None:
for window in self:
window.apply_options()
self.enabled_layouts = [x.lower() for x in get_options().enabled_layouts] or ['tall']
def set_enabled_layouts(self, val: Iterable[str]) -> None:
self.enabled_layouts = [x.lower() for x in val] or ['tall']
if self.current_layout.name not in self.enabled_layouts:
self._set_current_layout(self.enabled_layouts[0])
self.relayout()
def apply_options(self) -> None:
for window in self:
window.apply_options()
self.set_enabled_layouts(get_options().enabled_layouts)
def take_over_from(self, other_tab: 'Tab') -> None:
self.name, self.cwd = other_tab.name, other_tab.cwd
self.enabled_layouts = list(other_tab.enabled_layouts)