mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 01:38:02 +02:00
Fix #8998
This commit is contained in:
@@ -45,8 +45,11 @@ def panel_kitten_options_spec() -> str:
|
|||||||
ans: str = getattr(panel_kitten_options_spec, 'ans')
|
ans: str = getattr(panel_kitten_options_spec, 'ans')
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def parse_panel_args(args: list[str]) -> tuple[PanelCLIOptions, list[str]]:
|
|
||||||
return parse_args(args, panel_kitten_options_spec, usage, help_text, 'kitty +kitten panel', result_class=PanelCLIOptions)
|
def parse_panel_args(args: list[str], track_seen_options: set[str] | None = None) -> tuple[PanelCLIOptions, list[str]]:
|
||||||
|
return parse_args(
|
||||||
|
args, panel_kitten_options_spec, usage, help_text, 'kitty +kitten panel',
|
||||||
|
result_class=PanelCLIOptions, track_seen_options=track_seen_options)
|
||||||
|
|
||||||
|
|
||||||
def dual_distance(spec: str, min_cell_value_if_no_pixels: int = 0) -> tuple[int, int]:
|
def dual_distance(spec: str, min_cell_value_if_no_pixels: int = 0) -> tuple[int, int]:
|
||||||
|
|||||||
22
kitty/cli.py
22
kitty/cli.py
@@ -591,28 +591,37 @@ class Options:
|
|||||||
PreparsedCLIFlags = tuple[dict[str, tuple[Any, bool]], list[str]]
|
PreparsedCLIFlags = tuple[dict[str, tuple[Any, bool]], list[str]]
|
||||||
|
|
||||||
|
|
||||||
def apply_preparsed_cli_flags(preparsed_from_c: PreparsedCLIFlags, ans: Any, create_oc: Callable[[], Options]) -> list[str]:
|
def apply_preparsed_cli_flags(
|
||||||
|
preparsed_from_c: PreparsedCLIFlags, ans: Any, create_oc: Callable[[], Options],
|
||||||
|
track_seen_options: set[str] | None = None
|
||||||
|
) -> list[str]:
|
||||||
for key, (val, is_seen) in preparsed_from_c[0].items():
|
for key, (val, is_seen) in preparsed_from_c[0].items():
|
||||||
if key == 'help' and is_seen and val:
|
if key == 'help' and is_seen and val:
|
||||||
create_oc().handle_help()
|
create_oc().handle_help()
|
||||||
elif key == 'version' and is_seen and val:
|
elif key == 'version' and is_seen and val:
|
||||||
create_oc().handle_version()
|
create_oc().handle_version()
|
||||||
|
if is_seen and track_seen_options is not None:
|
||||||
|
track_seen_options.add(key)
|
||||||
setattr(ans, key, val)
|
setattr(ans, key, val)
|
||||||
return preparsed_from_c[1]
|
return preparsed_from_c[1]
|
||||||
|
|
||||||
|
|
||||||
def parse_cmdline_inner(
|
def parse_cmdline_inner(
|
||||||
args: list[str], oc: Options, disabled: OptionSpecSeq, names_map: dict[str, OptionDict], values_map: dict[str, OptionDict], ans: Any
|
args: list[str], oc: Options, disabled: OptionSpecSeq, names_map: dict[str, OptionDict],
|
||||||
|
values_map: dict[str, OptionDict], ans: Any, track_seen_options: set[str] | None = None
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
preparsed = parse_cli_from_spec(args, names_map, values_map)
|
preparsed = parse_cli_from_spec(args, names_map, values_map)
|
||||||
leftover_args = apply_preparsed_cli_flags(preparsed, ans, lambda: oc)
|
leftover_args = apply_preparsed_cli_flags(preparsed, ans, lambda: oc, track_seen_options)
|
||||||
for opt in disabled:
|
for opt in disabled:
|
||||||
if not isinstance(opt, str):
|
if not isinstance(opt, str):
|
||||||
setattr(ans, opt['dest'], defval_for_opt(opt))
|
setattr(ans, opt['dest'], defval_for_opt(opt))
|
||||||
return leftover_args
|
return leftover_args
|
||||||
|
|
||||||
|
|
||||||
def parse_cmdline(oc: Options, disabled: OptionSpecSeq, ans: Any, args: list[str] | None = None) -> list[str]:
|
def parse_cmdline(
|
||||||
|
oc: Options, disabled: OptionSpecSeq, ans: Any, args: list[str] | None = None,
|
||||||
|
track_seen_options: set[str] | None = None
|
||||||
|
) -> list[str]:
|
||||||
names_map = oc.names_map.copy()
|
names_map = oc.names_map.copy()
|
||||||
values_map = oc.values_map.copy()
|
values_map = oc.values_map.copy()
|
||||||
if 'help' not in names_map:
|
if 'help' not in names_map:
|
||||||
@@ -622,7 +631,7 @@ def parse_cmdline(oc: Options, disabled: OptionSpecSeq, ans: Any, args: list[str
|
|||||||
names_map['version'] = {'type': 'bool-set', 'aliases': ('--version', '-v')} # type: ignore
|
names_map['version'] = {'type': 'bool-set', 'aliases': ('--version', '-v')} # type: ignore
|
||||||
values_map['version'] = False
|
values_map['version'] = False
|
||||||
try:
|
try:
|
||||||
return parse_cmdline_inner(sys.argv[1:] if args is None else args, oc, disabled, names_map, values_map, ans)
|
return parse_cmdline_inner(sys.argv[1:] if args is None else args, oc, disabled, names_map, values_map, ans, track_seen_options)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise SystemExit(str(e))
|
raise SystemExit(str(e))
|
||||||
|
|
||||||
@@ -668,6 +677,7 @@ def parse_args(
|
|||||||
appname: str | None = None,
|
appname: str | None = None,
|
||||||
result_class: type[T] | None = None,
|
result_class: type[T] | None = None,
|
||||||
preparsed_from_c: PreparsedCLIFlags | None = None,
|
preparsed_from_c: PreparsedCLIFlags | None = None,
|
||||||
|
track_seen_options: set[str] | None = None,
|
||||||
) -> tuple[T, list[str]]:
|
) -> tuple[T, list[str]]:
|
||||||
if result_class is not None:
|
if result_class is not None:
|
||||||
ans = result_class()
|
ans = result_class()
|
||||||
@@ -685,7 +695,7 @@ def parse_args(
|
|||||||
options = parse_option_spec(ospec())
|
options = parse_option_spec(ospec())
|
||||||
seq, disabled = options
|
seq, disabled = options
|
||||||
oc = Options(seq, usage, message, appname)
|
oc = Options(seq, usage, message, appname)
|
||||||
return ans, parse_cmdline(oc, disabled, ans, args=args)
|
return ans, parse_cmdline(oc, disabled, ans, args=args, track_seen_options=track_seen_options)
|
||||||
|
|
||||||
|
|
||||||
SYSTEM_CONF = f'/etc/xdg/{appname}/{appname}.conf'
|
SYSTEM_CONF = f'/etc/xdg/{appname}/{appname}.conf'
|
||||||
|
|||||||
@@ -443,11 +443,11 @@ def get_env(opts: LaunchCLIOptions, active_child: Child | None = None, base_env:
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
def layer_shell_config_from_panel_opts(panel_opts: Iterable[str]) -> LayerShellConfig:
|
def layer_shell_config_from_panel_opts(panel_opts: Iterable[str], track_seen_options: set[str] | None = None) -> LayerShellConfig:
|
||||||
from kittens.panel.main import layer_shell_config, parse_panel_args
|
from kittens.panel.main import layer_shell_config, parse_panel_args
|
||||||
args = [('' if x.startswith('--') else '--') + x for x in panel_opts]
|
args = [('' if x.startswith('--') else '--') + x for x in panel_opts]
|
||||||
try:
|
try:
|
||||||
opts, _ = parse_panel_args(args)
|
opts, _ = parse_panel_args(args, track_seen_options=track_seen_options)
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
raise ValueError(str(e))
|
raise ValueError(str(e))
|
||||||
return layer_shell_config(opts)
|
return layer_shell_config(opts)
|
||||||
|
|||||||
@@ -119,22 +119,22 @@ using this option means that you will not be notified of failures.
|
|||||||
if not panels:
|
if not panels:
|
||||||
raise RemoteControlErrorWithoutTraceback('Must specify at least one panel setting')
|
raise RemoteControlErrorWithoutTraceback('Must specify at least one panel setting')
|
||||||
from kitty.launch import layer_shell_config_from_panel_opts
|
from kitty.launch import layer_shell_config_from_panel_opts
|
||||||
|
seen_options: set[str] = set()
|
||||||
try:
|
try:
|
||||||
lsc = layer_shell_config_from_panel_opts(panels)
|
lsc = layer_shell_config_from_panel_opts(panels, track_seen_options=seen_options)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RemoteControlErrorWithoutTraceback(
|
raise RemoteControlErrorWithoutTraceback(
|
||||||
f'Invalid panel options specified: {e}')
|
f'Invalid panel options specified: {e}')
|
||||||
if payload_get('incremental'):
|
if payload_get('incremental'):
|
||||||
defaults = layer_shell_config_from_panel_opts(())
|
|
||||||
changed_fields = {f for f in lsc._fields if getattr(lsc, f) != getattr(defaults, f)}
|
|
||||||
existing = layer_shell_config_for_os_window(os_window_id)
|
existing = layer_shell_config_for_os_window(os_window_id)
|
||||||
if existing is None:
|
if existing is None:
|
||||||
raise RemoteControlErrorWithoutTraceback(
|
raise RemoteControlErrorWithoutTraceback(
|
||||||
f'The OS Window {os_window_id} has no panel configuration')
|
f'The OS Window {os_window_id} has no panel configuration')
|
||||||
|
defaults = layer_shell_config_from_panel_opts(())
|
||||||
replacements = {}
|
replacements = {}
|
||||||
for x in lsc._fields:
|
for x in lsc._fields:
|
||||||
if x not in changed_fields:
|
if x not in seen_options:
|
||||||
replacements[x] = existing[x]
|
replacements[x] = getattr(defaults, x)
|
||||||
lsc = lsc._replace(**replacements)
|
lsc = lsc._replace(**replacements)
|
||||||
if not set_layer_shell_config(os_window_id, lsc):
|
if not set_layer_shell_config(os_window_id, lsc):
|
||||||
raise RemoteControlErrorWithoutTraceback(f'Failed to change panel configuration for OS Window {os_window_id}')
|
raise RemoteControlErrorWithoutTraceback(f'Failed to change panel configuration for OS Window {os_window_id}')
|
||||||
|
|||||||
Reference in New Issue
Block a user