DRYer: Use window matching function in remote commands

This commit is contained in:
pagedown 2022-05-01 23:04:50 +08:00
parent bb7e4039e8
commit 0719c7f8bb
No known key found for this signature in database
GPG Key ID: E921CF18AC8FF6EB
18 changed files with 59 additions and 73 deletions

View File

@ -46,7 +46,8 @@ Apply marker to the window this command is run in, rather than the active window
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
args = payload_get('marker_spec') args = payload_get('marker_spec')
for window in self.windows_for_match_payload(boss, window, payload_get): for window in self.windows_for_match_payload(boss, window, payload_get):
window.set_marker(args) if window:
window.set_marker(args)
return None return None

View File

@ -36,27 +36,18 @@ Detach the tab this command is run in, rather than the active tab.
return {'match': opts.match, 'target_tab': opts.target_tab, 'self': opts.self} return {'match': opts.match, 'target_tab': opts.target_tab, 'self': opts.self}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
match = payload_get('match')
if match:
tabs = list(boss.match_tabs(match))
if not tabs:
raise MatchError(match)
else:
if payload_get('self') and window:
tab = window.tabref() or boss.active_tab
else:
tab = boss.active_tab
tabs = [tab] if tab else []
match = payload_get('target_tab') match = payload_get('target_tab')
kwargs = {} kwargs = {}
if match: if match:
targets = tuple(boss.match_tabs(match)) targets = tuple(boss.match_tabs(match))
if not targets: if not targets:
raise MatchError(match, 'tabs') raise MatchError(match, 'tabs')
kwargs['target_os_window_id'] = targets[0].os_window_id if targets[0]:
kwargs['target_os_window_id'] = targets[0].os_window_id
for tab in tabs: for tab in self.tabs_for_match_payload(boss, window, payload_get):
boss._move_tab_to(tab=tab, **kwargs) if tab:
boss._move_tab_to(tab=tab, **kwargs)
return None return None

View File

@ -54,7 +54,8 @@ Detach the window this command is run in, rather than the active window.
target_tab_id = tabs[0].id target_tab_id = tabs[0].id
kwargs = {'target_os_window_id': newval} if target_tab_id is None else {'target_tab_id': target_tab_id} kwargs = {'target_os_window_id': newval} if target_tab_id is None else {'target_tab_id': target_tab_id}
for window in windows: for window in windows:
boss._move_window_to(window=window, **kwargs) if window:
boss._move_window_to(window=window, **kwargs)
return None return None

View File

@ -45,11 +45,12 @@ configured colors.
ans = {k: getattr(opts, k) for k in opts if isinstance(getattr(opts, k), Color)} ans = {k: getattr(opts, k) for k in opts if isinstance(getattr(opts, k), Color)}
if not payload_get('configured'): if not payload_get('configured'):
windows = self.windows_for_match_payload(boss, window, payload_get) windows = self.windows_for_match_payload(boss, window, payload_get)
for k, v in windows[0].current_colors.items(): if windows and windows[0]:
if v is None: for k, v in windows[0].current_colors.items():
ans.pop(k, None) if v is None:
else: ans.pop(k, None)
ans[k] = color_from_int(v) else:
ans[k] = color_from_int(v)
all_keys = natsort_ints(ans) all_keys = natsort_ints(ans)
maxlen = max(map(len, all_keys)) maxlen = max(map(len, all_keys))
return '\n'.join(('{:%ds} {}' % maxlen).format(key, color_as_sharp(ans[key])) for key in all_keys) return '\n'.join(('{:%ds} {}' % maxlen).format(key, color_as_sharp(ans[key])) for key in all_keys)

View File

@ -80,7 +80,11 @@ Get text from the window this command is run in, rather than the active window.
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
from kitty.window import CommandOutput from kitty.window import CommandOutput
window = self.windows_for_match_payload(boss, window, payload_get)[0] windows = self.windows_for_match_payload(boss, window, payload_get)
if windows and windows[0]:
window = windows[0]
else:
return None
if payload_get('extent') == 'selection': if payload_get('extent') == 'selection':
ans = window.text_for_selection(as_ansi=payload_get('ansi')) ans = window.text_for_selection(as_ansi=payload_get('ansi'))
elif payload_get('extent') == 'first_cmd_output_on_screen': elif payload_get('extent') == 'first_cmd_output_on_screen':

View File

@ -38,14 +38,8 @@ class Kitten(RemoteCommand):
return {'match': opts.match, 'args': list(args)[1:], 'kitten': args[0]} return {'match': opts.match, 'args': list(args)[1:], 'kitten': args[0]}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
windows = [window or boss.active_window]
match = payload_get('match')
if match:
windows = list(boss.match_windows(match))
if not windows:
raise MatchError(match)
retval = None retval = None
for window in windows: for window in self.windows_for_match_payload(boss, window, payload_get):
if window: if window:
retval = boss._run_kitten(payload_get('kitten'), args=tuple(payload_get('args') or ()), window=window) retval = boss._run_kitten(payload_get('kitten'), args=tuple(payload_get('args') or ()), window=window)
break break

View File

@ -81,9 +81,11 @@ instead of the active tab
if val is None: if val is None:
val = default_value val = default_value
setattr(opts, key, val) setattr(opts, key, val)
tab = self.tabs_for_match_payload(boss, window, payload_get)[0] tabs = self.tabs_for_match_payload(boss, window, payload_get)
w = do_launch(boss, opts, payload_get('args') or [], target_tab=tab) if tabs and tabs[0]:
return None if payload_get('no_response') else str(getattr(w, 'id', 0)) w = do_launch(boss, opts, payload_get('args') or [], target_tab=tabs[0])
return None if payload_get('no_response') else str(getattr(w, 'id', 0))
return None
launch = Launch() launch = Launch()

View File

@ -105,11 +105,13 @@ the id of the new window will not be printed out.
focus_os_window(os_window_id) focus_os_window(os_window_id)
return None if not aw or payload_get('no_response') else str(aw.id) return None if not aw or payload_get('no_response') else str(aw.id)
tab = self.tabs_for_match_payload(boss, window, payload_get)[0] tabs = self.tabs_for_match_payload(boss, window, payload_get)
ans = tab.new_special_window(w) if tabs and tabs[0]:
if payload_get('keep_focus') and old_window: ans = tabs[0].new_special_window(w)
boss.set_active_window(old_window) if payload_get('keep_focus') and old_window:
return None if payload_get('no_response') else str(ans.id) boss.set_active_window(old_window)
return None if payload_get('no_response') else str(ans.id)
return None
new_window = NewWindow() new_window = NewWindow()

View File

@ -33,7 +33,8 @@ Apply marker to the window this command is run in, rather than the active window
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
for window in self.windows_for_match_payload(boss, window, payload_get): for window in self.windows_for_match_payload(boss, window, payload_get):
window.remove_marker() if window:
window.remove_marker()
return None return None

View File

@ -84,7 +84,7 @@ using this option means that you will not be notified of failures.
windows = self.windows_for_match_payload(boss, window, payload_get) windows = self.windows_for_match_payload(boss, window, payload_get)
if windows: if windows:
ac = payload_get('action') ac = payload_get('action')
for os_window_id in {w.os_window_id for w in windows}: for os_window_id in {w.os_window_id for w in windows if w}:
if ac == 'resize': if ac == 'resize':
boss.resize_os_window( boss.resize_os_window(
os_window_id, width=payload_get('width'), height=payload_get('height'), os_window_id, width=payload_get('width'), height=payload_get('height'),

View File

@ -46,17 +46,12 @@ class ScrollWindow(RemoteCommand):
q = int(amt.rstrip('+-plu')) q = int(amt.rstrip('+-plu'))
amount = q * mult, 'p' if pages else ('u' if unscroll else 'l') amount = q * mult, 'p' if pages else ('u' if unscroll else 'l')
return {'match': opts.match, 'amount': amount} # defaults to scroll the window this command is run in
return {'match': opts.match, 'amount': amount, 'self': True}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
windows = [window or boss.active_window]
match = payload_get('match')
amt = payload_get('amount') amt = payload_get('amount')
if match: for window in self.windows_for_match_payload(boss, window, payload_get):
windows = list(boss.match_windows(match))
if not windows:
raise MatchError(match)
for window in windows:
if window: if window:
if amt[0] in ('start', 'end'): if amt[0] in ('start', 'end'):
getattr(window, {'start': 'scroll_home'}.get(amt[0], 'scroll_end'))() getattr(window, {'start': 'scroll_home'}.get(amt[0], 'scroll_end'))()

View File

@ -104,7 +104,7 @@ failed, the command will exit with a success code.
return AsyncResponse() return AsyncResponse()
windows = self.windows_for_payload(boss, window, payload_get) windows = self.windows_for_payload(boss, window, payload_get)
os_windows = tuple({w.os_window_id for w in windows}) os_windows = tuple({w.os_window_id for w in windows if w})
layout = payload_get('layout') layout = payload_get('layout')
if data == '-': if data == '-':
path = None path = None

View File

@ -51,7 +51,7 @@ cause background opacity to be changed in all windows.
if not get_options().dynamic_background_opacity: 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') 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) windows = self.windows_for_payload(boss, window, payload_get)
for os_window_id in {w.os_window_id for w in windows}: for os_window_id in {w.os_window_id for w in windows if w}:
boss._set_os_window_background_opacity(os_window_id, payload_get('opacity')) boss._set_os_window_background_opacity(os_window_id, payload_get('opacity'))
return None return None

View File

@ -113,14 +113,15 @@ this option, any color arguments are ignored and :option:`kitty @ set-colors --c
if payload_get('reset'): if payload_get('reset'):
colors = {k: int(v) for k, v in boss.startup_colors.items()} colors = {k: int(v) for k, v in boss.startup_colors.items()}
colors['cursor_text_color'] = None if boss.startup_cursor_text_color is None else int(boss.startup_cursor_text_color) colors['cursor_text_color'] = None if boss.startup_cursor_text_color is None else int(boss.startup_cursor_text_color)
profiles = tuple(w.screen.color_profile for w in windows) profiles = tuple(w.screen.color_profile for w in windows if w)
patch_color_profiles(colors, profiles, payload_get('configured')) patch_color_profiles(colors, profiles, payload_get('configured'))
boss.patch_colors(colors, payload_get('configured')) boss.patch_colors(colors, payload_get('configured'))
default_bg_changed = 'background' in colors default_bg_changed = 'background' in colors
for w in windows: for w in windows:
if default_bg_changed: if w:
boss.default_bg_changed_for(w.id) if default_bg_changed:
w.refresh() boss.default_bg_changed_for(w.id)
w.refresh()
return None return None

View File

@ -112,10 +112,11 @@ windows).
patch_configured_edges(get_options(), settings) patch_configured_edges(get_options(), settings)
for w in windows: for w in windows:
patch_window_edges(w, settings) if w:
tab = w.tabref() patch_window_edges(w, settings)
if tab is not None: tab = w.tabref()
dirtied_tabs[tab.id] = tab if tab is not None:
dirtied_tabs[tab.id] = tab
for tab in dirtied_tabs.values(): for tab in dirtied_tabs.values():
tab.relayout() tab.relayout()

View File

@ -113,7 +113,8 @@ failed, the command will exit with a success code.
alpha = float(payload_get('alpha', '-1')) alpha = float(payload_get('alpha', '-1'))
position = payload_get('position') or '' position = payload_get('position') or ''
for window in self.windows_for_match_payload(boss, window, payload_get): for window in self.windows_for_match_payload(boss, window, payload_get):
window.set_logo(path, position, alpha) if window:
window.set_logo(path, position, alpha)
return None return None

View File

@ -40,16 +40,12 @@ again. If you want to allow other programs to change it afterwards, use this opt
title = ' '.join(args) title = ' '.join(args)
if title: if title:
ans['title'] = title ans['title'] = title
# defaults to set the window title this command is run in
ans['self'] = True
return ans return ans
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
windows = [window or boss.active_window] for window in self.windows_for_match_payload(boss, window, payload_get):
match = payload_get('match')
if match:
windows = list(boss.match_windows(match))
if not windows:
raise MatchError(match)
for window in windows:
if window: if window:
if payload_get('temporary'): if payload_get('temporary'):
window.override_title = None window.override_title = None

View File

@ -33,18 +33,13 @@ class SignalChild(RemoteCommand):
argspec = '[SIGNAL_NAME ...]' argspec = '[SIGNAL_NAME ...]'
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:
return {'match': opts.match, 'signals': [x.upper() for x in args] or ['SIGINT']} # defaults to signal the window this command is run in
return {'match': opts.match, 'self': True, 'signals': [x.upper() for x in args] or ['SIGINT']}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
import signal import signal
windows = [window or boss.active_window]
match = payload_get('match')
if match:
windows = list(boss.match_windows(match))
if not windows:
raise MatchError(match)
signals = tuple(getattr(signal, x) for x in payload_get('signals')) signals = tuple(getattr(signal, x) for x in payload_get('signals'))
for window in windows: for window in self.windows_for_match_payload(boss, window, payload_get):
if window: if window:
window.signal_child(*signals) window.signal_child(*signals)
return None return None