Files
dotfiles/dot_config/kitty/switchtab.py
T
Prad NukalaandClaude Fable 5 3c691e8dc5 config(kitty,yazi,lazygit,lazydocker,gh): add universal tui tools from live home
kitty full config (theme symlink preserved, VictorMono NF). yazi opener
OS-branched via template (open vs xdg-open). yazi/lazygit refreshed to
live. lazydocker default empty config. gh config.yml as private_ —
hosts.yml excluded (oauth token).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 14:53:13 -04:00

104 lines
3.3 KiB
Python

from kittens.tui.handler import result_handler
from kittens.tui.handler import kitten_ui
# from kittens.tui.loop import debug
from kitty.boss import Boss
from kitty.rc.base import MatchError
from kitty.tabs import Tab, TabManager
from kitty.fast_data_types import swap_tabs
# from pprint import pprint
def get_tab_vt(tab: Tab) -> str | None:
"""Get the 'vt' user var from a tab's windows, or None if not set."""
for window in tab:
vt = window.user_vars.get("vt")
if vt is not None:
return vt
return None
def reorder_tabs_by_vt(tm: TabManager) -> None:
"""Reorder tabs so those without 'vt' come first, then those with 'vt' sorted by value."""
tabs = tm.tabs
if len(tabs) <= 1:
return
# Build list of (tab, vt_value) tuples
tab_vt_pairs: list[tuple[Tab, str | None]] = [
(tab, get_tab_vt(tab)) for tab in tabs
]
# Sort: tabs without vt first (None sorts before strings with key trick),
# then tabs with vt sorted by vt value
def sort_key(pair: tuple[Tab, str | None]) -> tuple[int, int, str]:
tab, vt = pair
if vt is None:
return (0, 0, "") # No vt: sort first
# Try numeric sort first, fall back to string sort
try:
return (1, int(vt), "") # Numeric vt
except ValueError:
return (2, 0, vt) # Non-numeric vt: sort after numeric, by string
sorted_pairs = sorted(tab_vt_pairs, key=sort_key)
sorted_tabs = [pair[0] for pair in sorted_pairs]
# Check if already in correct order
if sorted_tabs == tabs:
return
# Reorder by swapping to target positions
# We'll do a simple bubble-sort style swap to get tabs in place
for target_idx, target_tab in enumerate(sorted_tabs):
current_idx = tabs.index(target_tab)
while current_idx > target_idx:
# Swap with previous position
tabs[current_idx], tabs[current_idx - 1] = (
tabs[current_idx - 1],
tabs[current_idx],
)
swap_tabs(tm.os_window_id, current_idx, current_idx - 1)
current_idx -= 1
tm.mark_tab_bar_dirty()
# @kitten_ui(allow_remote_control=True)
def main(args: list[str]) -> None:
pass
@result_handler(no_ui=True)
def handle_result(
args: list[str], answer: str, target_window_id: int, boss: Boss
) -> None:
target_id = args[1]
# pprint(("target_id: ", target_id))
# pprint(("args: ", args))
w = boss.window_id_map.get(target_window_id)
tm = boss.active_tab_manager_with_dispatch
if tm is None:
raise RuntimeError("No tab manager?")
tabs = list(boss.match_tabs(f"var:vt=^{target_id}$"))
if len(tabs) > 0:
tm.set_active_tab(tabs[0])
return
# pprint(("tm", tm, "tabs", list(tabs)))
if w is not None:
try:
boss.call_remote_control(
w, ("focus-tab", "--match", f"var:vt=^{target_id}$")
)
except MatchError:
# pprint("No match, need to create tab")
boss.call_remote_control(
w, ("launch", "--type", "tab", "--var", f"vt={target_id}", *args[2:])
)
reorder_tabs_by_vt(tm)
tabs = list(boss.match_tabs(f"var:vt=^{target_id}$"))
if len(tabs) > 0:
tm.set_active_tab(tabs[0])
return