mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-08-04 14:46:03 +00:00
Add option for custom shaders
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
This commit is contained in:
parent
e6d3b8d7dc
commit
aa864ea348
6 changed files with 791 additions and 1750 deletions
|
|
@ -3457,6 +3457,10 @@ class Boss:
|
|||
|
||||
clear_caches()
|
||||
|
||||
from .shaders.slang import custom_shader
|
||||
|
||||
custom_shader.cache_clear()
|
||||
|
||||
def safe_delete_temp_file(self, path: str) -> None:
|
||||
if is_path_in_temp_dir(path):
|
||||
with suppress(FileNotFoundError):
|
||||
|
|
|
|||
|
|
@ -2858,6 +2858,24 @@ they will override any variables set by other :opt:`env` directives.
|
|||
""",
|
||||
)
|
||||
|
||||
opt(
|
||||
'+custom_shader',
|
||||
'',
|
||||
option_type='custom_shader',
|
||||
add_to_default=False,
|
||||
long_text="""
|
||||
Specify custom shaders to modify rendering. The syntax is::
|
||||
|
||||
SLOT shader_name shader_name ...
|
||||
|
||||
Can be specified multiple times. Here SLOT is a position in the redering pipeline, such as :code:`after-window-background`,
|
||||
or :code:`window-end`. Shader names are shader filenames or paths without
|
||||
the trailing :file:`.slang` suffix. They are looked for in the shaders directory inside the
|
||||
kitty config directory and if not found there, they are loaded from the builtin
|
||||
kitty custom shaders.
|
||||
""",
|
||||
)
|
||||
|
||||
opt(
|
||||
'+filter_notification',
|
||||
'',
|
||||
|
|
|
|||
282
kitty/options/parse.py
generated
282
kitty/options/parse.py
generated
|
|
@ -4,99 +4,35 @@
|
|||
import typing
|
||||
import collections.abc # noqa: F401, RUF100
|
||||
from kitty.conf.utils import (
|
||||
merge_dicts,
|
||||
positive_float,
|
||||
positive_int,
|
||||
python_string,
|
||||
signed_unit_float,
|
||||
to_bool,
|
||||
to_cmdline,
|
||||
to_color,
|
||||
to_color_or_none,
|
||||
unit_float,
|
||||
merge_dicts, positive_float, positive_int, python_string, signed_unit_float, to_bool, to_cmdline,
|
||||
to_color, to_color_or_none, unit_float
|
||||
)
|
||||
from kitty.options.utils import (
|
||||
action_alias,
|
||||
active_tab_title_template,
|
||||
allow_hyperlinks,
|
||||
background_images,
|
||||
bell_on_tab,
|
||||
box_drawing_scale,
|
||||
clear_all_mouse_actions,
|
||||
clear_all_shortcuts,
|
||||
clipboard_control,
|
||||
clone_source_strategies,
|
||||
config_or_absolute_path,
|
||||
confirm_close,
|
||||
copy_on_select,
|
||||
cursor_blink_interval,
|
||||
cursor_text_color,
|
||||
cursor_trail_decay,
|
||||
cursor_trail_start_threshold,
|
||||
deprecated_adjust_line_height,
|
||||
deprecated_hide_window_decorations_aliases,
|
||||
deprecated_macos_show_window_title_in_menubar_alias,
|
||||
deprecated_scrollback_indicator_opacity,
|
||||
deprecated_send_text,
|
||||
disable_ligatures,
|
||||
edge_width,
|
||||
env,
|
||||
filter_notification,
|
||||
font_features,
|
||||
hide_window_decorations,
|
||||
macos_option_as_alt,
|
||||
macos_titlebar_color,
|
||||
menu_map,
|
||||
modify_font,
|
||||
mouse_hide_wait,
|
||||
narrow_symbols,
|
||||
notify_on_cmd_finish,
|
||||
optional_edge_width,
|
||||
parse_font_spec,
|
||||
parse_map,
|
||||
parse_mouse_map,
|
||||
paste_actions,
|
||||
pointer_shape_when_dragging,
|
||||
remote_control_password,
|
||||
resize_debounce_time,
|
||||
scrollback_lines,
|
||||
scrollback_pager_history_size,
|
||||
scrollbar_color,
|
||||
shell_integration,
|
||||
show_hyperlink_targets,
|
||||
store_multiple,
|
||||
symbol_map,
|
||||
tab_activity_symbol,
|
||||
tab_bar_edge,
|
||||
tab_bar_margin_height,
|
||||
tab_bar_min_tabs,
|
||||
tab_fade,
|
||||
tab_font_style,
|
||||
tab_separator,
|
||||
tab_title_template,
|
||||
text_fg_override_threshold,
|
||||
titlebar_color,
|
||||
to_cursor_shape,
|
||||
to_cursor_unfocused_shape,
|
||||
to_font_size,
|
||||
to_layout_names,
|
||||
to_modifiers,
|
||||
transparent_background_colors,
|
||||
underline_exclusion,
|
||||
url_prefixes,
|
||||
url_style,
|
||||
visual_bell_duration,
|
||||
visual_window_select_characters,
|
||||
window_border_width,
|
||||
window_logo_scale,
|
||||
window_size,
|
||||
action_alias, active_tab_title_template, allow_hyperlinks, background_images, bell_on_tab,
|
||||
box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts, clipboard_control,
|
||||
clone_source_strategies, config_or_absolute_path, confirm_close, copy_on_select,
|
||||
cursor_blink_interval, cursor_text_color, cursor_trail_decay, cursor_trail_start_threshold,
|
||||
custom_shader, deprecated_adjust_line_height, deprecated_hide_window_decorations_aliases,
|
||||
deprecated_macos_show_window_title_in_menubar_alias, deprecated_scrollback_indicator_opacity,
|
||||
deprecated_send_text, disable_ligatures, edge_width, env, filter_notification, font_features,
|
||||
hide_window_decorations, macos_option_as_alt, macos_titlebar_color, menu_map, modify_font,
|
||||
mouse_hide_wait, narrow_symbols, notify_on_cmd_finish, optional_edge_width, parse_font_spec,
|
||||
parse_map, parse_mouse_map, paste_actions, pointer_shape_when_dragging, remote_control_password,
|
||||
resize_debounce_time, scrollback_lines, scrollback_pager_history_size, scrollbar_color,
|
||||
shell_integration, show_hyperlink_targets, store_multiple, symbol_map, tab_activity_symbol,
|
||||
tab_bar_edge, tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator,
|
||||
tab_title_template, text_fg_override_threshold, titlebar_color, to_cursor_shape,
|
||||
to_cursor_unfocused_shape, to_font_size, to_layout_names, to_modifiers,
|
||||
transparent_background_colors, underline_exclusion, url_prefixes, url_style, visual_bell_duration,
|
||||
visual_window_select_characters, window_border_width, window_logo_scale, window_size
|
||||
)
|
||||
|
||||
|
||||
class Parser:
|
||||
|
||||
def action_alias(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in action_alias(val):
|
||||
ans['action_alias'][k] = v
|
||||
ans["action_alias"][k] = v
|
||||
|
||||
def active_border_color(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['active_border_color'] = to_color_or_none(val)
|
||||
|
|
@ -119,8 +55,8 @@ class Parser:
|
|||
def allow_cloning(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_allow_cloning:
|
||||
raise ValueError(f'The value {val} is not a valid choice for allow_cloning')
|
||||
ans['allow_cloning'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for allow_cloning")
|
||||
ans["allow_cloning"] = val
|
||||
|
||||
choices_for_allow_cloning = frozenset(('yes', 'y', 'true', 'no', 'n', 'false', 'ask'))
|
||||
|
||||
|
|
@ -130,8 +66,8 @@ class Parser:
|
|||
def allow_remote_control(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_allow_remote_control:
|
||||
raise ValueError(f'The value {val} is not a valid choice for allow_remote_control')
|
||||
ans['allow_remote_control'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for allow_remote_control")
|
||||
ans["allow_remote_control"] = val
|
||||
|
||||
choices_for_allow_remote_control = frozenset(('password', 'socket-only', 'socket', 'no', 'n', 'false', 'yes', 'y', 'true'))
|
||||
|
||||
|
|
@ -150,8 +86,8 @@ class Parser:
|
|||
def background_image_layout(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_background_image_layout:
|
||||
raise ValueError(f'The value {val} is not a valid choice for background_image_layout')
|
||||
ans['background_image_layout'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for background_image_layout")
|
||||
ans["background_image_layout"] = val
|
||||
|
||||
choices_for_background_image_layout = frozenset(('mirror-tiled', 'scaled', 'tiled', 'clamped', 'centered', 'cscaled'))
|
||||
|
||||
|
|
@ -1022,48 +958,17 @@ class Parser:
|
|||
def cursor_underline_thickness(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['cursor_underline_thickness'] = positive_float(val)
|
||||
|
||||
def custom_shader(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in custom_shader(val, ans["custom_shader"]):
|
||||
ans["custom_shader"][k] = v
|
||||
|
||||
def default_pointer_shape(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_default_pointer_shape:
|
||||
raise ValueError(f'The value {val} is not a valid choice for default_pointer_shape')
|
||||
ans['default_pointer_shape'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for default_pointer_shape")
|
||||
ans["default_pointer_shape"] = val
|
||||
|
||||
choices_for_default_pointer_shape = frozenset(
|
||||
(
|
||||
'arrow',
|
||||
'beam',
|
||||
'text',
|
||||
'pointer',
|
||||
'hand',
|
||||
'help',
|
||||
'wait',
|
||||
'progress',
|
||||
'crosshair',
|
||||
'cell',
|
||||
'vertical-text',
|
||||
'move',
|
||||
'e-resize',
|
||||
'ne-resize',
|
||||
'nw-resize',
|
||||
'n-resize',
|
||||
'se-resize',
|
||||
'sw-resize',
|
||||
's-resize',
|
||||
'w-resize',
|
||||
'ew-resize',
|
||||
'ns-resize',
|
||||
'nesw-resize',
|
||||
'nwse-resize',
|
||||
'zoom-in',
|
||||
'zoom-out',
|
||||
'alias',
|
||||
'copy',
|
||||
'not-allowed',
|
||||
'no-drop',
|
||||
'grab',
|
||||
'grabbing',
|
||||
)
|
||||
)
|
||||
choices_for_default_pointer_shape = frozenset(('arrow', 'beam', 'text', 'pointer', 'hand', 'help', 'wait', 'progress', 'crosshair', 'cell', 'vertical-text', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', 'alias', 'copy', 'not-allowed', 'no-drop', 'grab', 'grabbing'))
|
||||
|
||||
def detect_urls(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['detect_urls'] = to_bool(val)
|
||||
|
|
@ -1096,25 +1001,25 @@ class Parser:
|
|||
ans['enabled_layouts'] = to_layout_names(val)
|
||||
|
||||
def env(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in env(val, ans['env']):
|
||||
ans['env'][k] = v
|
||||
for k, v in env(val, ans["env"]):
|
||||
ans["env"][k] = v
|
||||
|
||||
def exe_search_path(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in store_multiple(val, ans['exe_search_path']):
|
||||
ans['exe_search_path'][k] = v
|
||||
for k, v in store_multiple(val, ans["exe_search_path"]):
|
||||
ans["exe_search_path"][k] = v
|
||||
|
||||
def file_transfer_confirmation_bypass(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['file_transfer_confirmation_bypass'] = str(val)
|
||||
|
||||
def filter_notification(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in filter_notification(val, ans['filter_notification']):
|
||||
ans['filter_notification'][k] = v
|
||||
for k, v in filter_notification(val, ans["filter_notification"]):
|
||||
ans["filter_notification"][k] = v
|
||||
|
||||
def focus_follows_mouse(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_focus_follows_mouse:
|
||||
raise ValueError(f'The value {val} is not a valid choice for focus_follows_mouse')
|
||||
ans['focus_follows_mouse'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for focus_follows_mouse")
|
||||
ans["focus_follows_mouse"] = val
|
||||
|
||||
choices_for_focus_follows_mouse = frozenset(('no', 'n', 'false', 'y', 'yes', 'true', 'drop'))
|
||||
|
||||
|
|
@ -1123,7 +1028,7 @@ class Parser:
|
|||
|
||||
def font_features(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in font_features(val):
|
||||
ans['font_features'][k] = v
|
||||
ans["font_features"][k] = v
|
||||
|
||||
def font_size(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['font_size'] = to_font_size(val)
|
||||
|
|
@ -1169,7 +1074,7 @@ class Parser:
|
|||
|
||||
def kitten_alias(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in action_alias(val):
|
||||
ans['kitten_alias'][k] = v
|
||||
ans["kitten_alias"][k] = v
|
||||
|
||||
def kitty_mod(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['kitty_mod'] = to_modifiers(val)
|
||||
|
|
@ -1180,8 +1085,8 @@ class Parser:
|
|||
def linux_display_server(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_linux_display_server:
|
||||
raise ValueError(f'The value {val} is not a valid choice for linux_display_server')
|
||||
ans['linux_display_server'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for linux_display_server")
|
||||
ans["linux_display_server"] = val
|
||||
|
||||
choices_for_linux_display_server = frozenset(('auto', 'wayland', 'x11'))
|
||||
|
||||
|
|
@ -1191,8 +1096,8 @@ class Parser:
|
|||
def macos_colorspace(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_macos_colorspace:
|
||||
raise ValueError(f'The value {val} is not a valid choice for macos_colorspace')
|
||||
ans['macos_colorspace'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for macos_colorspace")
|
||||
ans["macos_colorspace"] = val
|
||||
|
||||
choices_for_macos_colorspace = frozenset(('srgb', 'default', 'displayp3'))
|
||||
|
||||
|
|
@ -1223,8 +1128,8 @@ class Parser:
|
|||
def macos_show_window_title_in(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_macos_show_window_title_in:
|
||||
raise ValueError(f'The value {val} is not a valid choice for macos_show_window_title_in')
|
||||
ans['macos_show_window_title_in'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for macos_show_window_title_in")
|
||||
ans["macos_show_window_title_in"] = val
|
||||
|
||||
choices_for_macos_show_window_title_in = frozenset(('all', 'menubar', 'none', 'window'))
|
||||
|
||||
|
|
@ -1265,12 +1170,12 @@ class Parser:
|
|||
ans['mark3_foreground'] = to_color(val)
|
||||
|
||||
def menu_map(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in menu_map(val, ans['menu_map']):
|
||||
ans['menu_map'][k] = v
|
||||
for k, v in menu_map(val, ans["menu_map"]):
|
||||
ans["menu_map"][k] = v
|
||||
|
||||
def modify_font(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in modify_font(val):
|
||||
ans['modify_font'][k] = v
|
||||
ans["modify_font"][k] = v
|
||||
|
||||
def momentum_scroll(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['momentum_scroll'] = unit_float(val)
|
||||
|
|
@ -1280,7 +1185,7 @@ class Parser:
|
|||
|
||||
def narrow_symbols(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in narrow_symbols(val):
|
||||
ans['narrow_symbols'][k] = v
|
||||
ans["narrow_symbols"][k] = v
|
||||
|
||||
def notify_on_cmd_finish(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['notify_on_cmd_finish'] = notify_on_cmd_finish(val)
|
||||
|
|
@ -1291,16 +1196,16 @@ class Parser:
|
|||
def padding_fill_strategy(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_padding_fill_strategy:
|
||||
raise ValueError(f'The value {val} is not a valid choice for padding_fill_strategy')
|
||||
ans['padding_fill_strategy'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for padding_fill_strategy")
|
||||
ans["padding_fill_strategy"] = val
|
||||
|
||||
choices_for_padding_fill_strategy = frozenset(('background', 'neighboring_cell'))
|
||||
|
||||
def palette_generate(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_palette_generate:
|
||||
raise ValueError(f'The value {val} is not a valid choice for palette_generate')
|
||||
ans['palette_generate'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for palette_generate")
|
||||
ans["palette_generate"] = val
|
||||
|
||||
choices_for_palette_generate = frozenset(('fixed', 'semantic', 'legacy'))
|
||||
|
||||
|
|
@ -1313,8 +1218,8 @@ class Parser:
|
|||
def placement_strategy(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_placement_strategy:
|
||||
raise ValueError(f'The value {val} is not a valid choice for placement_strategy')
|
||||
ans['placement_strategy'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for placement_strategy")
|
||||
ans["placement_strategy"] = val
|
||||
|
||||
choices_for_placement_strategy = frozenset(('top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'))
|
||||
|
||||
|
|
@ -1324,16 +1229,16 @@ class Parser:
|
|||
def pointer_shape_when_grabbed(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_pointer_shape_when_grabbed:
|
||||
raise ValueError(f'The value {val} is not a valid choice for pointer_shape_when_grabbed')
|
||||
ans['pointer_shape_when_grabbed'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for pointer_shape_when_grabbed")
|
||||
ans["pointer_shape_when_grabbed"] = val
|
||||
|
||||
choices_for_pointer_shape_when_grabbed = choices_for_default_pointer_shape
|
||||
|
||||
def progress_bar(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_progress_bar:
|
||||
raise ValueError(f'The value {val} is not a valid choice for progress_bar')
|
||||
ans['progress_bar'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for progress_bar")
|
||||
ans["progress_bar"] = val
|
||||
|
||||
choices_for_progress_bar = frozenset(('left', 'right', 'top', 'bottom', 'hidden'))
|
||||
|
||||
|
|
@ -1344,8 +1249,8 @@ class Parser:
|
|||
ans['remember_window_size'] = to_bool(val)
|
||||
|
||||
def remote_control_password(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in remote_control_password(val, ans['remote_control_password']):
|
||||
ans['remote_control_password'][k] = v
|
||||
for k, v in remote_control_password(val, ans["remote_control_password"]):
|
||||
ans["remote_control_password"][k] = v
|
||||
|
||||
def repaint_delay(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['repaint_delay'] = positive_int(val)
|
||||
|
|
@ -1371,8 +1276,8 @@ class Parser:
|
|||
def scrollbar(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_scrollbar:
|
||||
raise ValueError(f'The value {val} is not a valid choice for scrollbar')
|
||||
ans['scrollbar'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for scrollbar")
|
||||
ans["scrollbar"] = val
|
||||
|
||||
choices_for_scrollbar = frozenset(('scrolled', 'always', 'never', 'hovered', 'scrolled-and-hovered'))
|
||||
|
||||
|
|
@ -1448,14 +1353,14 @@ class Parser:
|
|||
def strip_trailing_spaces(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_strip_trailing_spaces:
|
||||
raise ValueError(f'The value {val} is not a valid choice for strip_trailing_spaces')
|
||||
ans['strip_trailing_spaces'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for strip_trailing_spaces")
|
||||
ans["strip_trailing_spaces"] = val
|
||||
|
||||
choices_for_strip_trailing_spaces = frozenset(('always', 'never', 'smart'))
|
||||
|
||||
def symbol_map(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in symbol_map(val):
|
||||
ans['symbol_map'][k] = v
|
||||
ans["symbol_map"][k] = v
|
||||
|
||||
def sync_to_monitor(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['sync_to_monitor'] = to_bool(val)
|
||||
|
|
@ -1466,8 +1371,8 @@ class Parser:
|
|||
def tab_bar_align(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_tab_bar_align:
|
||||
raise ValueError(f'The value {val} is not a valid choice for tab_bar_align')
|
||||
ans['tab_bar_align'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for tab_bar_align")
|
||||
ans["tab_bar_align"] = val
|
||||
|
||||
choices_for_tab_bar_align = frozenset(('start', 'center', 'end', 'left', 'right'))
|
||||
|
||||
|
|
@ -1498,8 +1403,8 @@ class Parser:
|
|||
def tab_bar_style(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_tab_bar_style:
|
||||
raise ValueError(f'The value {val} is not a valid choice for tab_bar_style')
|
||||
ans['tab_bar_style'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for tab_bar_style")
|
||||
ans["tab_bar_style"] = val
|
||||
|
||||
choices_for_tab_bar_style = frozenset(('fade', 'hidden', 'powerline', 'separator', 'slant', 'custom'))
|
||||
|
||||
|
|
@ -1509,8 +1414,8 @@ class Parser:
|
|||
def tab_powerline_style(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_tab_powerline_style:
|
||||
raise ValueError(f'The value {val} is not a valid choice for tab_powerline_style')
|
||||
ans['tab_powerline_style'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for tab_powerline_style")
|
||||
ans["tab_powerline_style"] = val
|
||||
|
||||
choices_for_tab_powerline_style = frozenset(('angled', 'round', 'slanted'))
|
||||
|
||||
|
|
@ -1520,8 +1425,8 @@ class Parser:
|
|||
def tab_switch_strategy(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_tab_switch_strategy:
|
||||
raise ValueError(f'The value {val} is not a valid choice for tab_switch_strategy')
|
||||
ans['tab_switch_strategy'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for tab_switch_strategy")
|
||||
ans["tab_switch_strategy"] = val
|
||||
|
||||
choices_for_tab_switch_strategy = frozenset(('last', 'left', 'previous', 'right'))
|
||||
|
||||
|
|
@ -1537,8 +1442,8 @@ class Parser:
|
|||
def terminfo_type(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_terminfo_type:
|
||||
raise ValueError(f'The value {val} is not a valid choice for terminfo_type')
|
||||
ans['terminfo_type'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for terminfo_type")
|
||||
ans["terminfo_type"] = val
|
||||
|
||||
choices_for_terminfo_type = frozenset(('path', 'direct', 'none'))
|
||||
|
||||
|
|
@ -1557,8 +1462,8 @@ class Parser:
|
|||
def undercurl_style(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_undercurl_style:
|
||||
raise ValueError(f'The value {val} is not a valid choice for undercurl_style')
|
||||
ans['undercurl_style'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for undercurl_style")
|
||||
ans["undercurl_style"] = val
|
||||
|
||||
choices_for_undercurl_style = frozenset(('thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense'))
|
||||
|
||||
|
|
@ -1568,8 +1473,8 @@ class Parser:
|
|||
def underline_hyperlinks(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_underline_hyperlinks:
|
||||
raise ValueError(f'The value {val} is not a valid choice for underline_hyperlinks')
|
||||
ans['underline_hyperlinks'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for underline_hyperlinks")
|
||||
ans["underline_hyperlinks"] = val
|
||||
|
||||
choices_for_underline_hyperlinks = frozenset(('hover', 'always', 'never'))
|
||||
|
||||
|
|
@ -1598,8 +1503,8 @@ class Parser:
|
|||
ans['visual_window_select_characters'] = visual_window_select_characters(val)
|
||||
|
||||
def watcher(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
for k, v in store_multiple(val, ans['watcher']):
|
||||
ans['watcher'][k] = v
|
||||
for k, v in store_multiple(val, ans["watcher"]):
|
||||
ans["watcher"][k] = v
|
||||
|
||||
def wayland_enable_ime(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['wayland_enable_ime'] = to_bool(val)
|
||||
|
|
@ -1631,8 +1536,8 @@ class Parser:
|
|||
def window_logo_position(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_window_logo_position:
|
||||
raise ValueError(f'The value {val} is not a valid choice for window_logo_position')
|
||||
ans['window_logo_position'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for window_logo_position")
|
||||
ans["window_logo_position"] = val
|
||||
|
||||
choices_for_window_logo_position = choices_for_placement_strategy
|
||||
|
||||
|
|
@ -1654,8 +1559,8 @@ class Parser:
|
|||
def window_title_bar(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_window_title_bar:
|
||||
raise ValueError(f'The value {val} is not a valid choice for window_title_bar')
|
||||
ans['window_title_bar'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for window_title_bar")
|
||||
ans["window_title_bar"] = val
|
||||
|
||||
choices_for_window_title_bar = frozenset(('top', 'bottom'))
|
||||
|
||||
|
|
@ -1668,8 +1573,8 @@ class Parser:
|
|||
def window_title_bar_align(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_window_title_bar_align:
|
||||
raise ValueError(f'The value {val} is not a valid choice for window_title_bar_align')
|
||||
ans['window_title_bar_align'] = val
|
||||
raise ValueError(f"The value {val} is not a valid choice for window_title_bar_align")
|
||||
ans["window_title_bar_align"] = val
|
||||
|
||||
choices_for_window_title_bar_align = frozenset(('left', 'center', 'right'))
|
||||
|
||||
|
|
@ -1721,6 +1626,7 @@ class Parser:
|
|||
def create_result_dict() -> dict[str, typing.Any]:
|
||||
return {
|
||||
'action_alias': {},
|
||||
'custom_shader': {},
|
||||
'env': {},
|
||||
'exe_search_path': {},
|
||||
'filter_notification': {},
|
||||
|
|
|
|||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
|
|
@ -122,19 +122,6 @@ convert_from_opts_text_composition_strategy(PyObject *py_opts, Options *opts) {
|
|||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_text_fg_override_threshold(PyObject *val, Options *opts) {
|
||||
opts->text_fg_override_threshold = text_fg_override_threshold(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_text_fg_override_threshold(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "text_fg_override_threshold");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_text_fg_override_threshold(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_cursor_shape(PyObject *val, Options *opts) {
|
||||
opts->cursor_shape = PyLong_AsLong(val);
|
||||
|
|
@ -1572,8 +1559,6 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
|||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_text_composition_strategy(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_text_fg_override_threshold(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_cursor_shape(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_cursor_shape_unfocused(py_opts, opts);
|
||||
|
|
|
|||
2196
kitty/options/types.py
generated
2196
kitty/options/types.py
generated
File diff suppressed because it is too large
Load diff
|
|
@ -905,11 +905,11 @@ def background_images(x: str) -> tuple[str, ...]:
|
|||
return tuple(x for x in sorted(glob(x)) if x.rpartition('.')[-1].lower() in ('jpeg', 'jpg', 'png', 'webp', 'tif', 'tiff', 'bmp', 'gif')) or (x,)
|
||||
|
||||
|
||||
def filter_notification(val: str, current_val: dict[str, str]) -> Iterable[tuple[str, str]]:
|
||||
def filter_notification(val: str, current_val: dict[str, str]) -> Iterator[tuple[str, str]]:
|
||||
yield val, ''
|
||||
|
||||
|
||||
def remote_control_password(val: str, current_val: dict[str, str]) -> Iterable[tuple[str, Sequence[str]]]:
|
||||
def remote_control_password(val: str, current_val: dict[str, str]) -> Iterator[tuple[str, Sequence[str]]]:
|
||||
val = val.strip()
|
||||
if val:
|
||||
parts = to_cmdline(val, expand=False)
|
||||
|
|
@ -923,6 +923,28 @@ def remote_control_password(val: str, current_val: dict[str, str]) -> Iterable[t
|
|||
yield parts[0], tuple(parts[1:])
|
||||
|
||||
|
||||
CustomShaderSlots = Literal['after-window-background']
|
||||
all_custom_shader_slots = get_args(CustomShaderSlots)
|
||||
|
||||
|
||||
def custom_shader(val: str, current_val: dict[str, str]) -> Iterator[tuple[CustomShaderSlots, tuple[str, ...]]]:
|
||||
val = val.strip()
|
||||
if val:
|
||||
parts = tuple(shlex_split(val))
|
||||
if parts[0] not in all_custom_shader_slots:
|
||||
raise ValueError(f'The shader slot {parts[0]} is unknown')
|
||||
if len(parts) < 2:
|
||||
raise ValueError(f'No actual shaders specified for {parts[0]}')
|
||||
from kitty.shaders.slang import custom_shader
|
||||
|
||||
for x in parts[1:]:
|
||||
try:
|
||||
custom_shader(x)
|
||||
except Exception as e:
|
||||
raise ValueError(f'Custom shader {x} not found or not readable with error: {e}') from e
|
||||
yield cast(CustomShaderSlots, parts[0]), parts[1:]
|
||||
|
||||
|
||||
def clipboard_control(x: str) -> tuple[str, ...]:
|
||||
return tuple(x.lower().split())
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue