mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-11 14:45:31 +03:00
Use the new get_options() function
Nicer than carrying around opts objects everywhere
This commit is contained in:
parent
253b219d67
commit
c827a29a7b
@ -317,7 +317,8 @@ def handle_action(action: str, cli_opts: RemoteFileCLIOptions) -> Result:
|
||||
@result_handler()
|
||||
def handle_result(args: List[str], data: Result, target_window_id: int, boss: BossType) -> None:
|
||||
if data:
|
||||
cmd = command_for_open(boss.opts.open_url_with)
|
||||
from kitty.fast_data_types import get_options
|
||||
cmd = command_for_open(get_options().open_url_with)
|
||||
open_cmd(cmd, data)
|
||||
|
||||
|
||||
|
@ -7,10 +7,9 @@
|
||||
from typing import Sequence, Tuple
|
||||
|
||||
from .fast_data_types import (
|
||||
BORDERS_PROGRAM, add_borders_rect, compile_program, init_borders_program,
|
||||
os_window_has_background_image
|
||||
BORDERS_PROGRAM, add_borders_rect, compile_program, get_options,
|
||||
init_borders_program, os_window_has_background_image
|
||||
)
|
||||
from .options_stub import Options
|
||||
from .typing import LayoutType
|
||||
from .utils import load_shaders
|
||||
from .window_list import WindowGroup, WindowList
|
||||
@ -65,11 +64,9 @@ def load_borders_program() -> None:
|
||||
|
||||
class Borders:
|
||||
|
||||
def __init__(self, os_window_id: int, tab_id: int, opts: Options):
|
||||
def __init__(self, os_window_id: int, tab_id: int):
|
||||
self.os_window_id = os_window_id
|
||||
self.tab_id = tab_id
|
||||
self.draw_active_borders = opts.active_border_color is not None
|
||||
self.draw_minimal_borders = opts.draw_minimal_borders and max(opts.window_margin_width) < 1
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
@ -78,6 +75,9 @@ def __call__(
|
||||
extra_blank_rects: Sequence[Tuple[int, int, int, int]],
|
||||
draw_window_borders: bool = True,
|
||||
) -> None:
|
||||
opts = get_options()
|
||||
draw_active_borders = opts.active_border_color is not None
|
||||
draw_minimal_borders = opts.draw_minimal_borders and max(opts.window_margin_width) < 1
|
||||
add_borders_rect(self.os_window_id, self.tab_id, 0, 0, 0, 0, BorderColor.default_bg)
|
||||
has_background_image = os_window_has_background_image(self.os_window_id)
|
||||
if not has_background_image:
|
||||
@ -94,9 +94,9 @@ def __call__(
|
||||
for i, wg in enumerate(groups):
|
||||
window_bg = wg.default_bg
|
||||
window_bg = (window_bg << 8) | BorderColor.window_bg
|
||||
if draw_borders and not self.draw_minimal_borders:
|
||||
if draw_borders and not draw_minimal_borders:
|
||||
# Draw the border rectangles
|
||||
if wg is active_group and self.draw_active_borders:
|
||||
if wg is active_group and draw_active_borders:
|
||||
color = BorderColor.active
|
||||
else:
|
||||
color = BorderColor.bell if wg.needs_attention else BorderColor.inactive
|
||||
@ -106,7 +106,7 @@ def __call__(
|
||||
colors = window_bg, window_bg, window_bg, window_bg
|
||||
draw_edges(self.os_window_id, self.tab_id, colors, wg)
|
||||
|
||||
if self.draw_minimal_borders:
|
||||
if draw_minimal_borders:
|
||||
for border_line in current_layout.get_minimal_borders(all_windows):
|
||||
left, top, right, bottom = border_line.edges
|
||||
add_borders_rect(self.os_window_id, self.tab_id, left, top, right, bottom, border_line.color)
|
||||
|
@ -32,7 +32,7 @@
|
||||
ChildMonitor, KeyEvent, add_timer, background_opacity_of,
|
||||
change_background_opacity, change_os_window_state, cocoa_set_menubar_title,
|
||||
create_os_window, current_application_quit_request, current_os_window,
|
||||
destroy_global_data, focus_os_window, get_clipboard_string,
|
||||
destroy_global_data, focus_os_window, get_clipboard_string, get_options,
|
||||
global_font_size, mark_os_window_for_close, os_window_font_size,
|
||||
patch_global_colors, safe_pipe, set_application_quit_request,
|
||||
set_background_image, set_boss, set_clipboard_string, set_in_sequence_mode,
|
||||
@ -167,8 +167,8 @@ def __init__(
|
||||
talk_fd, listen_fd
|
||||
)
|
||||
set_boss(self)
|
||||
self.opts, self.args = opts, args
|
||||
self.keymap = self.opts.keymap.copy()
|
||||
self.args = args
|
||||
self.keymap = get_options().keymap.copy()
|
||||
self.global_shortcuts_map = {v: KeyAction(k) for k, v in global_shortcuts.items()}
|
||||
for sc in global_shortcuts.values():
|
||||
self.keymap.pop(sc, None)
|
||||
@ -179,7 +179,7 @@ def __init__(
|
||||
cocoa_set_notification_activated_callback(notification_activated)
|
||||
|
||||
def startup_first_child(self, os_window_id: Optional[int]) -> None:
|
||||
startup_sessions = create_sessions(self.opts, self.args, default_session=self.opts.startup_session)
|
||||
startup_sessions = create_sessions(get_options(), self.args, default_session=get_options().startup_session)
|
||||
for startup_session in startup_sessions:
|
||||
self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
os_window_id = None
|
||||
@ -199,7 +199,7 @@ def add_os_window(
|
||||
startup_id: Optional[str] = None
|
||||
) -> int:
|
||||
if os_window_id is None:
|
||||
size_data = get_os_window_sizing_data(opts_for_size or self.opts, startup_session)
|
||||
size_data = get_os_window_sizing_data(opts_for_size or get_options(), startup_session)
|
||||
wclass = wclass or getattr(startup_session, 'os_window_class', None) or self.args.cls or appname
|
||||
wname = wname or self.args.name or wclass
|
||||
with startup_notification_handler(do_notify=startup_id is not None, startup_id=startup_id) as pre_show_callback:
|
||||
@ -210,7 +210,7 @@ def add_os_window(
|
||||
else:
|
||||
wname = self.args.name or self.args.cls or appname
|
||||
wclass = self.args.cls or appname
|
||||
tm = TabManager(os_window_id, self.opts, self.args, wclass, wname, startup_session)
|
||||
tm = TabManager(os_window_id, self.args, wclass, wname, startup_session)
|
||||
self.os_window_map[os_window_id] = tm
|
||||
return os_window_id
|
||||
|
||||
@ -317,7 +317,7 @@ def _new_os_window(self, args: Union[SpecialWindowInstance, Iterable[str]], cwd_
|
||||
sw: Optional[SpecialWindowInstance] = args
|
||||
else:
|
||||
sw = self.args_to_special_window(args, cwd_from) if args else None
|
||||
startup_session = next(create_sessions(self.opts, special_window=sw, cwd_from=cwd_from))
|
||||
startup_session = next(create_sessions(get_options(), special_window=sw, cwd_from=cwd_from))
|
||||
return self.add_os_window(startup_session)
|
||||
|
||||
def new_os_window(self, *args: str) -> None:
|
||||
@ -347,7 +347,7 @@ def _handle_remote_command(self, cmd: str, window: Optional[Window] = None, from
|
||||
from .remote_control import handle_cmd
|
||||
response = None
|
||||
window = window or None
|
||||
if self.opts.allow_remote_control == 'y' or from_peer or getattr(window, 'allow_remote_control', False):
|
||||
if get_options().allow_remote_control == 'y' or from_peer or getattr(window, 'allow_remote_control', False):
|
||||
try:
|
||||
response = handle_cmd(self, window, cmd)
|
||||
except Exception as err:
|
||||
@ -411,7 +411,7 @@ def peer_message_received(self, msg_bytes: bytes) -> Optional[bytes]:
|
||||
args.directory = os.path.join(data['cwd'], args.directory)
|
||||
for session in create_sessions(opts, args, respect_cwd=True):
|
||||
os_window_id = self.add_os_window(session, wclass=args.cls, wname=args.name, opts_for_size=opts, startup_id=startup_id)
|
||||
if opts.background_opacity != self.opts.background_opacity:
|
||||
if opts.background_opacity != get_options().background_opacity:
|
||||
self._set_os_window_background_opacity(os_window_id, opts.background_opacity)
|
||||
if data.get('notify_on_os_window_death'):
|
||||
self.os_window_death_actions[os_window_id] = partial(self.notify_on_os_window_death, data['notify_on_os_window_death'])
|
||||
@ -484,7 +484,7 @@ def close_tab(self, tab: Optional[Tab] = None) -> None:
|
||||
|
||||
def confirm_tab_close(self, tab: Tab) -> None:
|
||||
windows = tuple(tab)
|
||||
needs_confirmation = self.opts.confirm_os_window_close > 0 and len(windows) >= self.opts.confirm_os_window_close
|
||||
needs_confirmation = get_options().confirm_os_window_close > 0 and len(windows) >= get_options().confirm_os_window_close
|
||||
if not needs_confirmation:
|
||||
self.close_tab_no_confirm(tab)
|
||||
return
|
||||
@ -521,9 +521,9 @@ def start(self, first_os_window_id: int) -> None:
|
||||
self.io_thread_started = True
|
||||
self.startup_first_child(first_os_window_id)
|
||||
|
||||
if self.opts.update_check_interval > 0 and not hasattr(self, 'update_check_started'):
|
||||
if get_options().update_check_interval > 0 and not hasattr(self, 'update_check_started'):
|
||||
from .update_check import run_update_check
|
||||
run_update_check(self.opts.update_check_interval * 60 * 60)
|
||||
run_update_check(get_options().update_check_interval * 60 * 60)
|
||||
self.update_check_started = True
|
||||
|
||||
def activate_tab_at(self, os_window_id: int, x: int, is_double: bool = False) -> int:
|
||||
@ -561,14 +561,14 @@ def clear_terminal(self, action: str, only_active: bool) -> None:
|
||||
|
||||
def increase_font_size(self) -> None: # legacy
|
||||
cfs = global_font_size()
|
||||
self.set_font_size(min(self.opts.font_size * 5, cfs + 2.0))
|
||||
self.set_font_size(min(get_options().font_size * 5, cfs + 2.0))
|
||||
|
||||
def decrease_font_size(self) -> None: # legacy
|
||||
cfs = global_font_size()
|
||||
self.set_font_size(max(MINIMUM_FONT_SIZE, cfs - 2.0))
|
||||
|
||||
def restore_font_size(self) -> None: # legacy
|
||||
self.set_font_size(self.opts.font_size)
|
||||
self.set_font_size(get_options().font_size)
|
||||
|
||||
def set_font_size(self, new_size: float) -> None: # legacy
|
||||
self.change_font_size(True, None, new_size)
|
||||
@ -577,13 +577,13 @@ def change_font_size(self, all_windows: bool, increment_operation: Optional[str]
|
||||
def calc_new_size(old_size: float) -> float:
|
||||
new_size = old_size
|
||||
if amt == 0:
|
||||
new_size = self.opts.font_size
|
||||
new_size = get_options().font_size
|
||||
else:
|
||||
if increment_operation:
|
||||
new_size += (1 if increment_operation == '+' else -1) * amt
|
||||
else:
|
||||
new_size = amt
|
||||
new_size = max(MINIMUM_FONT_SIZE, min(new_size, self.opts.font_size * 5))
|
||||
new_size = max(MINIMUM_FONT_SIZE, min(new_size, get_options().font_size * 5))
|
||||
return new_size
|
||||
|
||||
if all_windows:
|
||||
@ -633,7 +633,7 @@ def set_background_opacity(self, opacity: str) -> None:
|
||||
window = self.active_window
|
||||
if window is None or not opacity:
|
||||
return
|
||||
if not self.opts.dynamic_background_opacity:
|
||||
if not get_options().dynamic_background_opacity:
|
||||
self.show_error(
|
||||
_('Cannot change background opacity'),
|
||||
_('You must set the dynamic_background_opacity option in kitty.conf to be able to change background opacity'))
|
||||
@ -645,7 +645,7 @@ def set_background_opacity(self, opacity: str) -> None:
|
||||
return
|
||||
fin_opacity = old_opacity + float(opacity)
|
||||
elif opacity == 'default':
|
||||
fin_opacity = self.opts.background_opacity
|
||||
fin_opacity = get_options().background_opacity
|
||||
else:
|
||||
fin_opacity = float(opacity)
|
||||
self._set_os_window_background_opacity(os_window_id, fin_opacity)
|
||||
@ -672,7 +672,7 @@ def dispatch_possible_special_key(self, ev: KeyEvent) -> bool:
|
||||
# Handles shortcuts, return True if the key was consumed
|
||||
key_action = get_shortcut(self.keymap, ev)
|
||||
if key_action is None:
|
||||
sequences = get_shortcut(self.opts.sequence_map, ev)
|
||||
sequences = get_shortcut(get_options().sequence_map, ev)
|
||||
if sequences and not isinstance(sequences, KeyAction):
|
||||
self.pending_sequences = sequences
|
||||
set_in_sequence_mode(True)
|
||||
@ -710,8 +710,8 @@ def start_resizing_window(self) -> None:
|
||||
if w is None:
|
||||
return
|
||||
overlay_window = self._run_kitten('resize_window', args=[
|
||||
'--horizontal-increment={}'.format(self.opts.window_resize_step_cells),
|
||||
'--vertical-increment={}'.format(self.opts.window_resize_step_lines)
|
||||
'--horizontal-increment={}'.format(get_options().window_resize_step_cells),
|
||||
'--vertical-increment={}'.format(get_options().window_resize_step_lines)
|
||||
])
|
||||
if overlay_window is not None:
|
||||
overlay_window.allow_remote_control = True
|
||||
@ -813,7 +813,7 @@ def close_os_window(self) -> None:
|
||||
|
||||
def confirm_os_window_close(self, os_window_id: int) -> None:
|
||||
tm = self.os_window_map.get(os_window_id)
|
||||
needs_confirmation = tm is not None and self.opts.confirm_os_window_close > 0 and tm.number_of_windows >= self.opts.confirm_os_window_close
|
||||
needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and tm.number_of_windows >= get_options().confirm_os_window_close
|
||||
if not needs_confirmation:
|
||||
mark_os_window_for_close(os_window_id)
|
||||
return
|
||||
@ -850,7 +850,7 @@ def quit(self, *args: Any) -> None:
|
||||
num = 0
|
||||
for q in self.os_window_map.values():
|
||||
num += q.number_of_windows
|
||||
needs_confirmation = tm is not None and self.opts.confirm_os_window_close > 0 and num >= self.opts.confirm_os_window_close
|
||||
needs_confirmation = tm is not None and get_options().confirm_os_window_close > 0 and num >= get_options().confirm_os_window_close
|
||||
if not needs_confirmation:
|
||||
set_application_quit_request(IMPERATIVE_CLOSE_REQUESTED)
|
||||
return
|
||||
@ -889,7 +889,7 @@ def edit_config_file(self, *a: Any) -> None:
|
||||
confpath = prepare_config_file_for_editing()
|
||||
# On macOS vim fails to handle SIGWINCH if it occurs early, so add a
|
||||
# small delay.
|
||||
cmd = [kitty_exe(), '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + get_editor(self.opts) + [confpath]
|
||||
cmd = [kitty_exe(), '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + get_editor(get_options()) + [confpath]
|
||||
self.new_os_window(*cmd)
|
||||
|
||||
def get_output(self, source_window: Window, num_lines: Optional[int] = 1) -> str:
|
||||
@ -941,7 +941,7 @@ def _run_kitten(
|
||||
raise ValueError('Unknown type_of_input: {}'.format(type_of_input))
|
||||
else:
|
||||
data = input_data if isinstance(input_data, bytes) else input_data.encode('utf-8')
|
||||
copts = common_opts_as_dict(self.opts)
|
||||
copts = common_opts_as_dict(get_options())
|
||||
final_args: List[str] = []
|
||||
for x in args:
|
||||
if x == '@selection':
|
||||
@ -1081,7 +1081,7 @@ def open_url(self, url: str, program: Optional[Union[str, List[str]]] = None, cw
|
||||
if actions:
|
||||
self.drain_actions(actions)
|
||||
if not found_action:
|
||||
open_url(url, program or self.opts.open_url_with, cwd=cwd)
|
||||
open_url(url, program or get_options().open_url_with, cwd=cwd)
|
||||
|
||||
def drain_actions(self, actions: List) -> None:
|
||||
|
||||
@ -1128,8 +1128,8 @@ def set_primary_selection(self) -> None:
|
||||
text = w.text_for_selection()
|
||||
if text:
|
||||
set_primary_selection(text)
|
||||
if self.opts.copy_on_select:
|
||||
self.copy_to_buffer(self.opts.copy_on_select)
|
||||
if get_options().copy_on_select:
|
||||
self.copy_to_buffer(get_options().copy_on_select)
|
||||
|
||||
def copy_to_buffer(self, buffer_name: str) -> None:
|
||||
w = self.active_window
|
||||
@ -1401,14 +1401,15 @@ def disable_ligatures_in(self, where: Union[str, Iterable[Window]], strategy: in
|
||||
window.refresh()
|
||||
|
||||
def patch_colors(self, spec: Dict[str, int], cursor_text_color: Union[bool, int, Color], configured: bool = False) -> None:
|
||||
opts = get_options()
|
||||
if configured:
|
||||
for k, v in spec.items():
|
||||
if hasattr(self.opts, k):
|
||||
setattr(self.opts, k, color_from_int(v))
|
||||
if hasattr(opts, k):
|
||||
setattr(opts, k, color_from_int(v))
|
||||
if cursor_text_color is not False:
|
||||
if isinstance(cursor_text_color, int):
|
||||
cursor_text_color = color_from_int(cursor_text_color)
|
||||
self.opts.cursor_text_color = cursor_text_color
|
||||
opts.cursor_text_color = cursor_text_color
|
||||
for tm in self.all_tab_managers:
|
||||
tm.tab_bar.patch_colors(spec)
|
||||
patch_global_colors(spec, configured)
|
||||
|
@ -14,7 +14,6 @@
|
||||
import kitty.fast_data_types as fast_data_types
|
||||
|
||||
from .constants import is_macos, shell_path, terminfo_dir
|
||||
from .options_stub import Options
|
||||
|
||||
try:
|
||||
from typing import TypedDict
|
||||
@ -187,7 +186,6 @@ def __init__(
|
||||
self,
|
||||
argv: Sequence[str],
|
||||
cwd: str,
|
||||
opts: Options,
|
||||
stdin: Optional[bytes] = None,
|
||||
env: Optional[Dict[str, str]] = None,
|
||||
cwd_from: Optional[int] = None,
|
||||
@ -204,7 +202,6 @@ def __init__(
|
||||
else:
|
||||
cwd = os.path.expandvars(os.path.expanduser(cwd or os.getcwd()))
|
||||
self.cwd = os.path.abspath(cwd)
|
||||
self.opts = opts
|
||||
self.stdin = stdin
|
||||
self.env = env or {}
|
||||
|
||||
@ -217,7 +214,7 @@ def final_env(self) -> Dict[str, str]:
|
||||
'lc_ctype_before_python') and not getattr(default_env, 'lc_ctype_set_by_user', False):
|
||||
del env['LC_CTYPE']
|
||||
env.update(self.env)
|
||||
env['TERM'] = self.opts.term
|
||||
env['TERM'] = fast_data_types.get_options().term
|
||||
env['COLORTERM'] = 'truecolor'
|
||||
if self.cwd:
|
||||
# needed in case cwd is a symlink, in which case shells
|
||||
|
@ -10,7 +10,9 @@
|
||||
from .cli import WATCHER_DEFINITION, parse_args
|
||||
from .cli_stub import LaunchCLIOptions
|
||||
from .constants import resolve_custom_file
|
||||
from .fast_data_types import patch_color_profiles, set_clipboard_string
|
||||
from .fast_data_types import (
|
||||
get_options, patch_color_profiles, set_clipboard_string
|
||||
)
|
||||
from .tabs import Tab
|
||||
from .types import run_once
|
||||
from .utils import find_exe, read_shell_environment, set_primary_selection
|
||||
@ -330,7 +332,7 @@ def launch(
|
||||
final_cmd.append(x)
|
||||
exe = find_exe(final_cmd[0])
|
||||
if not exe:
|
||||
env = read_shell_environment(boss.opts)
|
||||
env = read_shell_environment(get_options())
|
||||
if 'PATH' in env:
|
||||
import shutil
|
||||
exe = shutil.which(final_cmd[0], path=env['PATH'])
|
||||
|
@ -40,7 +40,9 @@ def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: Arg
|
||||
return {'configured': opts.configured, 'match': opts.match}
|
||||
|
||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||
ans = {k: getattr(boss.opts, k) for k in boss.opts if isinstance(getattr(boss.opts, k), Color)}
|
||||
from kitty.fast_data_types import get_options
|
||||
opts = get_options()
|
||||
ans = {k: getattr(opts, k) for k in opts if isinstance(getattr(opts, k), Color)}
|
||||
if not payload_get('configured'):
|
||||
windows = self.windows_for_match_payload(boss, window, payload_get)
|
||||
ans.update({k: color_from_int(v) for k, v in windows[0].current_colors.items()})
|
||||
|
@ -48,7 +48,8 @@ def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: Arg
|
||||
}
|
||||
|
||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||
if not boss.opts.dynamic_background_opacity:
|
||||
from kitty.fast_data_types import get_options
|
||||
if not get_options().dynamic_background_opacity:
|
||||
raise OpacityError('You must turn on the dynamic_background_opacity option in kitty.conf to be able to set background opacity')
|
||||
windows = self.windows_for_payload(boss, window, payload_get)
|
||||
for os_window_id in {w.os_window_id for w in windows}:
|
||||
|
@ -108,8 +108,9 @@ def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get:
|
||||
windows = self.windows_for_payload(boss, window, payload_get)
|
||||
settings: Dict[str, Optional[float]] = payload_get('settings')
|
||||
dirtied_tabs = {}
|
||||
from kitty.fast_data_types import get_options
|
||||
if payload_get('configured'):
|
||||
patch_configured_edges(boss.opts, settings)
|
||||
patch_configured_edges(get_options(), settings)
|
||||
|
||||
for w in windows:
|
||||
patch_window_edges(w, settings)
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
from .config import build_ansi_color_table
|
||||
from .fast_data_types import (
|
||||
DECAWM, Screen, cell_size_for_window, pt_to_px, set_tab_bar_render_data,
|
||||
viewport_for_window
|
||||
DECAWM, Screen, cell_size_for_window, get_options, pt_to_px,
|
||||
set_tab_bar_render_data, viewport_for_window
|
||||
)
|
||||
from .layout.base import Rect
|
||||
from .options_stub import Options
|
||||
from .rgb import Color, alpha_blend, color_as_sgr, color_from_int, to_color
|
||||
from .types import WindowGeometry
|
||||
from .typing import PowerlineStyle
|
||||
@ -245,11 +244,11 @@ def draw_tab_with_powerline(draw_data: DrawData, screen: Screen, tab: TabBarData
|
||||
|
||||
class TabBar:
|
||||
|
||||
def __init__(self, os_window_id: int, opts: Options):
|
||||
def __init__(self, os_window_id: int):
|
||||
self.os_window_id = os_window_id
|
||||
self.opts = opts
|
||||
self.num_tabs = 1
|
||||
self.margin_width = pt_to_px(self.opts.tab_bar_margin_width, self.os_window_id)
|
||||
opts = get_options()
|
||||
self.margin_width = pt_to_px(opts.tab_bar_margin_width, self.os_window_id)
|
||||
self.cell_width, cell_height = cell_size_for_window(self.os_window_id)
|
||||
self.data_buffer_size = 0
|
||||
self.laid_out_once = False
|
||||
@ -277,17 +276,17 @@ def __init__(self, os_window_id: int, opts: Options):
|
||||
self.active_fg = as_rgb(color_as_int(opts.active_tab_foreground))
|
||||
self.bell_fg = as_rgb(0xff0000)
|
||||
self.draw_data = DrawData(
|
||||
self.leading_spaces, self.sep, self.trailing_spaces, self.opts.bell_on_tab, self.bell_fg,
|
||||
self.opts.tab_fade, self.opts.active_tab_foreground, self.opts.active_tab_background,
|
||||
self.opts.inactive_tab_foreground, self.opts.inactive_tab_background,
|
||||
self.opts.tab_bar_background or self.opts.background, self.opts.tab_title_template,
|
||||
self.opts.active_tab_title_template,
|
||||
self.opts.tab_activity_symbol,
|
||||
self.opts.tab_powerline_style
|
||||
self.leading_spaces, self.sep, self.trailing_spaces, opts.bell_on_tab, self.bell_fg,
|
||||
opts.tab_fade, opts.active_tab_foreground, opts.active_tab_background,
|
||||
opts.inactive_tab_foreground, opts.inactive_tab_background,
|
||||
opts.tab_bar_background or opts.background, opts.tab_title_template,
|
||||
opts.active_tab_title_template,
|
||||
opts.tab_activity_symbol,
|
||||
opts.tab_powerline_style
|
||||
)
|
||||
if self.opts.tab_bar_style == 'separator':
|
||||
if opts.tab_bar_style == 'separator':
|
||||
self.draw_func = draw_tab_with_separator
|
||||
elif self.opts.tab_bar_style == 'powerline':
|
||||
elif opts.tab_bar_style == 'powerline':
|
||||
self.draw_func = draw_tab_with_powerline
|
||||
else:
|
||||
self.draw_func = draw_tab_with_fade
|
||||
@ -303,12 +302,13 @@ def patch_colors(self, spec: Dict[str, Any]) -> None:
|
||||
self.draw_data = self.draw_data._replace(inactive_bg=color_from_int(spec['inactive_tab_background']))
|
||||
if 'tab_bar_background' in spec:
|
||||
self.draw_data = self.draw_data._replace(default_bg=color_from_int(spec['tab_bar_background']))
|
||||
fg = spec.get('inactive_tab_foreground', color_as_int(self.opts.inactive_tab_foreground))
|
||||
opts = get_options()
|
||||
fg = spec.get('inactive_tab_foreground', color_as_int(opts.inactive_tab_foreground))
|
||||
bg = spec.get('tab_bar_background', False)
|
||||
if bg is None:
|
||||
bg = color_as_int(self.opts.background)
|
||||
bg = color_as_int(opts.background)
|
||||
elif bg is False:
|
||||
bg = color_as_int(self.opts.tab_bar_background or self.opts.background)
|
||||
bg = color_as_int(opts.tab_bar_background or opts.background)
|
||||
self.screen.color_profile.set_configured_colors(fg, bg)
|
||||
|
||||
def layout(self) -> None:
|
||||
|
@ -19,13 +19,12 @@
|
||||
from .cli_stub import CLIOptions
|
||||
from .constants import appname, kitty_exe
|
||||
from .fast_data_types import (
|
||||
add_tab, attach_window, detach_window, get_boss, mark_tab_bar_dirty,
|
||||
next_window_id, remove_tab, remove_window, ring_bell, set_active_tab,
|
||||
set_active_window, swap_tabs, sync_os_window_title
|
||||
add_tab, attach_window, detach_window, get_boss, get_options,
|
||||
mark_tab_bar_dirty, next_window_id, remove_tab, remove_window, ring_bell,
|
||||
set_active_tab, set_active_window, swap_tabs, sync_os_window_title
|
||||
)
|
||||
from .layout.base import Layout, Rect
|
||||
from .layout.interface import create_layout_object_for, evict_cached_layouts
|
||||
from .options_stub import Options
|
||||
from .tab_bar import TabBar, TabBarData
|
||||
from .typing import EdgeLiteral, SessionTab, SessionType, TypedDict
|
||||
from .utils import log_error, platform_window_id, resolved_shell
|
||||
@ -90,10 +89,10 @@ def __init__(
|
||||
self.id: int = add_tab(self.os_window_id)
|
||||
if not self.id:
|
||||
raise Exception('No OS window with id {} found, or tab counter has wrapped'.format(self.os_window_id))
|
||||
self.opts, self.args = tab_manager.opts, tab_manager.args
|
||||
self.args = tab_manager.args
|
||||
self.name = getattr(session_tab, 'name', '')
|
||||
self.enabled_layouts = [x.lower() for x in getattr(session_tab, 'enabled_layouts', None) or self.opts.enabled_layouts]
|
||||
self.borders = Borders(self.os_window_id, self.id, self.opts)
|
||||
self.enabled_layouts = [x.lower() for x in getattr(session_tab, 'enabled_layouts', None) or get_options().enabled_layouts]
|
||||
self.borders = Borders(self.os_window_id, self.id)
|
||||
self.windows = WindowList(self)
|
||||
for i, which in enumerate('first second third fourth fifth sixth seventh eighth ninth tenth'.split()):
|
||||
setattr(self, which + '_window', partial(self.nth_window, num=i))
|
||||
@ -283,15 +282,15 @@ def launch_child(
|
||||
check_for_suitability = True
|
||||
if cmd is None:
|
||||
if use_shell:
|
||||
cmd = resolved_shell(self.opts)
|
||||
cmd = resolved_shell(get_options())
|
||||
check_for_suitability = False
|
||||
else:
|
||||
if self.args.args:
|
||||
cmd = list(self.args.args)
|
||||
else:
|
||||
cmd = resolved_shell(self.opts)
|
||||
cmd = resolved_shell(get_options())
|
||||
check_for_suitability = False
|
||||
cmd = self.args.args or resolved_shell(self.opts)
|
||||
cmd = self.args.args or resolved_shell(get_options())
|
||||
if check_for_suitability:
|
||||
old_exe = cmd[0]
|
||||
if not os.path.isabs(old_exe):
|
||||
@ -310,7 +309,7 @@ def launch_child(
|
||||
else:
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
cwd = old_exe
|
||||
cmd = resolved_shell(self.opts)
|
||||
cmd = resolved_shell(get_options())
|
||||
elif not is_executable:
|
||||
import shlex
|
||||
with suppress(OSError):
|
||||
@ -320,7 +319,7 @@ def launch_child(
|
||||
line = f.read(4096).splitlines()[0]
|
||||
cmd += shlex.split(line) + [old_exe]
|
||||
else:
|
||||
cmd += [resolved_shell(self.opts)[0], cmd[0]]
|
||||
cmd += [resolved_shell(get_options())[0], cmd[0]]
|
||||
fenv: Dict[str, str] = {}
|
||||
if env:
|
||||
fenv.update(env)
|
||||
@ -328,7 +327,7 @@ def launch_child(
|
||||
pwid = platform_window_id(self.os_window_id)
|
||||
if pwid is not None:
|
||||
fenv['WINDOWID'] = str(pwid)
|
||||
ans = Child(cmd, cwd or self.cwd, self.opts, stdin, fenv, cwd_from, allow_remote_control=allow_remote_control)
|
||||
ans = Child(cmd, cwd or self.cwd, stdin, fenv, cwd_from, allow_remote_control=allow_remote_control)
|
||||
ans.fork()
|
||||
return ans
|
||||
|
||||
@ -356,7 +355,7 @@ def new_window(
|
||||
child = self.launch_child(
|
||||
use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from, cwd=cwd, env=env, allow_remote_control=allow_remote_control)
|
||||
window = Window(
|
||||
self, child, self.opts, self.args, override_title=override_title,
|
||||
self, child, self.args, override_title=override_title,
|
||||
copy_colors_from=copy_colors_from, watchers=watchers
|
||||
)
|
||||
# Must add child before laying out so that resize_pty succeeds
|
||||
@ -530,16 +529,16 @@ def make_active(self) -> None:
|
||||
|
||||
class TabManager: # {{{
|
||||
|
||||
def __init__(self, os_window_id: int, opts: Options, args: CLIOptions, wm_class: str, wm_name: str, startup_session: Optional[SessionType] = None):
|
||||
def __init__(self, os_window_id: int, args: CLIOptions, wm_class: str, wm_name: str, startup_session: Optional[SessionType] = None):
|
||||
self.os_window_id = os_window_id
|
||||
self.wm_class = wm_class
|
||||
self.wm_name = wm_name
|
||||
self.last_active_tab_id = None
|
||||
self.opts, self.args = opts, args
|
||||
self.tab_bar_hidden = self.opts.tab_bar_style == 'hidden'
|
||||
self.args = args
|
||||
self.tab_bar_hidden = get_options().tab_bar_style == 'hidden'
|
||||
self.tabs: List[Tab] = []
|
||||
self.active_tab_history: Deque[int] = deque()
|
||||
self.tab_bar = TabBar(self.os_window_id, opts)
|
||||
self.tab_bar = TabBar(self.os_window_id)
|
||||
self._active_tab_idx = 0
|
||||
|
||||
if startup_session is not None:
|
||||
@ -581,7 +580,7 @@ def refresh_sprite_positions(self) -> None:
|
||||
|
||||
@property
|
||||
def tab_bar_should_be_visible(self) -> bool:
|
||||
return len(self.tabs) >= self.opts.tab_bar_min_tabs
|
||||
return len(self.tabs) >= get_options().tab_bar_min_tabs
|
||||
|
||||
def _add_tab(self, tab: Tab) -> None:
|
||||
visible_before = self.tab_bar_should_be_visible
|
||||
@ -765,16 +764,16 @@ def remove(self, tab: Tab) -> None:
|
||||
|
||||
if active_tab_needs_to_change:
|
||||
next_active_tab = -1
|
||||
if self.opts.tab_switch_strategy == 'previous':
|
||||
if get_options().tab_switch_strategy == 'previous':
|
||||
while self.active_tab_history and next_active_tab < 0:
|
||||
tab_id = self.active_tab_history.pop()
|
||||
for idx, qtab in enumerate(self.tabs):
|
||||
if qtab.id == tab_id:
|
||||
next_active_tab = idx
|
||||
break
|
||||
elif self.opts.tab_switch_strategy == 'left':
|
||||
elif get_options().tab_switch_strategy == 'left':
|
||||
next_active_tab = max(0, self.active_tab_idx - 1)
|
||||
elif self.opts.tab_switch_strategy == 'right':
|
||||
elif get_options().tab_switch_strategy == 'right':
|
||||
next_active_tab = min(self.active_tab_idx, len(self.tabs) - 1)
|
||||
|
||||
if next_active_tab < 0:
|
||||
|
@ -28,10 +28,10 @@
|
||||
MARK, MARK_MASK, NO_CURSOR_SHAPE, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE,
|
||||
SCROLL_PAGE, STRIKETHROUGH, TINT_PROGRAM, KeyEvent, Screen, add_timer,
|
||||
add_window, cell_size_for_window, click_mouse_url, compile_program,
|
||||
encode_key_for_tty, get_boss, get_clipboard_string, init_cell_program,
|
||||
mouse_selection, pt_to_px, set_clipboard_string, set_titlebar_color,
|
||||
set_window_padding, set_window_render_data, update_window_title,
|
||||
update_window_visibility, viewport_for_window
|
||||
encode_key_for_tty, get_boss, get_clipboard_string, get_options,
|
||||
init_cell_program, mouse_selection, pt_to_px, set_clipboard_string,
|
||||
set_titlebar_color, set_window_padding, set_window_render_data,
|
||||
update_window_title, update_window_visibility, viewport_for_window
|
||||
)
|
||||
from .keys import keyboard_mode_name
|
||||
from .notify import NotificationCommand, handle_notification_cmd
|
||||
@ -311,7 +311,6 @@ def __init__(
|
||||
self,
|
||||
tab: TabType,
|
||||
child: ChildType,
|
||||
opts: Options,
|
||||
args: CLIOptions,
|
||||
override_title: Optional[str] = None,
|
||||
copy_colors_from: Optional['Window'] = None,
|
||||
@ -344,8 +343,9 @@ def __init__(
|
||||
self.geometry: WindowGeometry = WindowGeometry(0, 0, 0, 0, 0, 0)
|
||||
self.needs_layout = True
|
||||
self.is_visible_in_layout: bool = True
|
||||
self.child, self.opts = child, opts
|
||||
self.child = child
|
||||
cell_width, cell_height = cell_size_for_window(self.os_window_id)
|
||||
opts = get_options()
|
||||
self.screen: Screen = Screen(self, 24, 80, opts.scrollback_lines, cell_width, cell_height, self.id)
|
||||
if copy_colors_from is not None:
|
||||
self.screen.copy_colors_from(copy_colors_from.screen)
|
||||
@ -364,18 +364,19 @@ def effective_margin(self, edge: EdgeLiteral, is_single_window: bool = False) ->
|
||||
q = getattr(self.margin, edge)
|
||||
if q is not None:
|
||||
return pt_to_px(q, self.os_window_id)
|
||||
opts = get_options()
|
||||
if is_single_window:
|
||||
q = getattr(self.opts.single_window_margin_width, edge)
|
||||
q = getattr(opts.single_window_margin_width, edge)
|
||||
if q > -0.1:
|
||||
return pt_to_px(q, self.os_window_id)
|
||||
q = getattr(self.opts.window_margin_width, edge)
|
||||
q = getattr(opts.window_margin_width, edge)
|
||||
return pt_to_px(q, self.os_window_id)
|
||||
|
||||
def effective_padding(self, edge: EdgeLiteral) -> int:
|
||||
q = getattr(self.padding, edge)
|
||||
if q is not None:
|
||||
return pt_to_px(q, self.os_window_id)
|
||||
q = getattr(self.opts.window_padding_width, edge)
|
||||
q = getattr(get_options().window_padding_width, edge)
|
||||
return pt_to_px(q, self.os_window_id)
|
||||
|
||||
def update_effective_padding(self) -> None:
|
||||
@ -391,7 +392,7 @@ def patch_edge_width(self, which: str, edge: EdgeLiteral, val: Optional[float])
|
||||
self.update_effective_padding()
|
||||
|
||||
def effective_border(self) -> int:
|
||||
val, unit = self.opts.window_border_width
|
||||
val, unit = get_options().window_border_width
|
||||
if unit == 'pt':
|
||||
val = max(1 if val > 0 else 0, pt_to_px(val, self.os_window_id))
|
||||
else:
|
||||
@ -556,14 +557,15 @@ def use_utf8(self, on: bool) -> None:
|
||||
def on_mouse_event(self, event: Dict[str, Any]) -> bool:
|
||||
ev = MouseEvent(**event)
|
||||
self.current_mouse_event_button = ev.button
|
||||
action = self.opts.mousemap.get(ev)
|
||||
action = get_options().mousemap.get(ev)
|
||||
if action is None:
|
||||
return False
|
||||
return get_boss().dispatch_action(action, window_for_dispatch=self, dispatch_type='MouseEvent')
|
||||
|
||||
def open_url(self, url: str, hyperlink_id: int, cwd: Optional[str] = None) -> None:
|
||||
opts = get_options()
|
||||
if hyperlink_id:
|
||||
if not self.opts.allow_hyperlinks:
|
||||
if not opts.allow_hyperlinks:
|
||||
return
|
||||
from urllib.parse import unquote, urlparse, urlunparse
|
||||
try:
|
||||
@ -582,7 +584,7 @@ def open_url(self, url: str, hyperlink_id: int, cwd: Optional[str] = None) -> No
|
||||
self.handle_remote_file(purl.netloc, unquote(purl.path))
|
||||
return
|
||||
url = urlunparse(purl._replace(netloc=''))
|
||||
if self.opts.allow_hyperlinks & 0b10:
|
||||
if opts.allow_hyperlinks & 0b10:
|
||||
from kittens.tui.operations import styled
|
||||
get_boss()._run_kitten('ask', ['--type=choices', '--message', _(
|
||||
'What would you like to do with this URL:\n') +
|
||||
@ -644,16 +646,17 @@ def has_activity_since_last_focus(self) -> bool:
|
||||
return self.screen.has_activity_since_last_focus()
|
||||
|
||||
def on_activity_since_last_focus(self) -> None:
|
||||
if self.opts.tab_activity_symbol:
|
||||
if get_options().tab_activity_symbol:
|
||||
get_boss().on_activity_since_last_focus(self)
|
||||
|
||||
def on_bell(self) -> None:
|
||||
if self.opts.command_on_bell and self.opts.command_on_bell != ['none']:
|
||||
cb = get_options().command_on_bell
|
||||
if cb and cb != ['none']:
|
||||
import shlex
|
||||
import subprocess
|
||||
env = self.child.final_env
|
||||
env['KITTY_CHILD_CMDLINE'] = ' '.join(map(shlex.quote, self.child.cmdline))
|
||||
subprocess.Popen(self.opts.command_on_bell, env=env, cwd=self.child.foreground_cwd)
|
||||
subprocess.Popen(cb, env=env, cwd=self.child.foreground_cwd)
|
||||
if not self.is_active:
|
||||
changed = not self.needs_attention
|
||||
self.needs_attention = True
|
||||
@ -664,7 +667,8 @@ def on_bell(self) -> None:
|
||||
tab.on_bell(self)
|
||||
|
||||
def change_titlebar_color(self) -> None:
|
||||
val = self.opts.macos_titlebar_color if is_macos else self.opts.wayland_titlebar_color
|
||||
opts = get_options()
|
||||
val = opts.macos_titlebar_color if is_macos else opts.wayland_titlebar_color
|
||||
if val:
|
||||
if (val & 0xff) == 1:
|
||||
val = self.screen.color_profile.default_bg
|
||||
@ -748,7 +752,7 @@ def set_color_table_color(self, code: int, value: str) -> None:
|
||||
self.refresh()
|
||||
|
||||
def request_capabilities(self, q: str) -> None:
|
||||
for result in get_capabilities(q, self.opts):
|
||||
for result in get_capabilities(q, get_options()):
|
||||
self.screen.send_escape_code_to_child(DCS, result)
|
||||
|
||||
def handle_remote_cmd(self, cmd: str) -> None:
|
||||
@ -767,13 +771,14 @@ def clipboard_control(self, data: str) -> None:
|
||||
where, text = data.partition(';')[::2]
|
||||
if not where:
|
||||
where = 's0'
|
||||
cc = get_options().clipboard_control
|
||||
if text == '?':
|
||||
response = None
|
||||
if 's' in where or 'c' in where:
|
||||
response = get_clipboard_string() if 'read-clipboard' in self.opts.clipboard_control else ''
|
||||
response = get_clipboard_string() if 'read-clipboard' in cc else ''
|
||||
loc = 'c'
|
||||
elif 'p' in where:
|
||||
response = get_primary_selection() if 'read-primary' in self.opts.clipboard_control else ''
|
||||
response = get_primary_selection() if 'read-primary' in cc else ''
|
||||
loc = 'p'
|
||||
response = response or ''
|
||||
from base64 import standard_b64encode
|
||||
@ -789,7 +794,7 @@ def clipboard_control(self, data: str) -> None:
|
||||
|
||||
def write(key: str, func: Callable[[str], None]) -> None:
|
||||
if text:
|
||||
if ('no-append' in self.opts.clipboard_control or
|
||||
if ('no-append' in cc or
|
||||
len(self.clipboard_control_buffers[key]) > 1024*1024):
|
||||
self.clipboard_control_buffers[key] = ''
|
||||
self.clipboard_control_buffers[key] += text
|
||||
@ -798,13 +803,13 @@ def write(key: str, func: Callable[[str], None]) -> None:
|
||||
func(self.clipboard_control_buffers[key])
|
||||
|
||||
if 's' in where or 'c' in where:
|
||||
if 'write-clipboard' in self.opts.clipboard_control:
|
||||
if 'write-clipboard' in cc:
|
||||
write('c', set_clipboard_string)
|
||||
if 'p' in where:
|
||||
if self.opts.copy_on_select == 'clipboard':
|
||||
if 'write-clipboard' in self.opts.clipboard_control:
|
||||
if cc == 'clipboard':
|
||||
if 'write-clipboard' in cc:
|
||||
write('c', set_clipboard_string)
|
||||
if 'write-primary' in self.opts.clipboard_control:
|
||||
if 'write-primary' in cc:
|
||||
write('p', set_primary_selection)
|
||||
|
||||
def manipulate_title_stack(self, pop: bool, title: str, icon: Any) -> None:
|
||||
@ -842,8 +847,9 @@ def paste_selection_or_clipboard(self) -> None:
|
||||
|
||||
def text_for_selection(self) -> str:
|
||||
lines = self.screen.text_for_selection()
|
||||
if self.opts.strip_trailing_spaces == 'always' or (
|
||||
self.opts.strip_trailing_spaces == 'smart' and not self.screen.is_rectangle_select()):
|
||||
sts = get_options().strip_trailing_spaces
|
||||
if sts == 'always' or (
|
||||
sts == 'smart' and not self.screen.is_rectangle_select()):
|
||||
return ''.join((ln.rstrip() or '\n') for ln in lines)
|
||||
return ''.join(lines)
|
||||
|
||||
@ -906,12 +912,12 @@ def prepare_arg(x: str) -> str:
|
||||
x = x.replace('CURSOR_COLUMN', str(data['cursor_x']))
|
||||
return x
|
||||
|
||||
cmd = list(map(prepare_arg, self.opts.scrollback_pager))
|
||||
cmd = list(map(prepare_arg, get_options().scrollback_pager))
|
||||
if not os.path.isabs(cmd[0]):
|
||||
import shutil
|
||||
exe = shutil.which(cmd[0])
|
||||
if not exe:
|
||||
env = read_shell_environment(self.opts)
|
||||
env = read_shell_environment(get_options())
|
||||
if env and 'PATH' in env:
|
||||
exe = shutil.which(cmd[0], path=env['PATH'])
|
||||
if exe:
|
||||
|
Loading…
Reference in New Issue
Block a user