kitty: color terminal tabs by ssh/mosh host

Tint the kitty tab background by target host so local vs remote (and
which remote) is visible at a glance.

- __kitty_host_color: explicit color table for known hosts (routers,
  resolvers, ryzen/mini, personal cloud, geo VPS) + stable hashed
  palette fallback; auto-picks readable fg by luminance
- __kitty_ssh_host: parse target host from ssh/mosh-style argv
- __kitty_tab_set/__kitty_tab_reset: active tab = full host-color bg,
  inactive tab = dark theme bg with host-color text; revert on exit
- ssh wrapper + s (kitten ssh) and m (mosh) wired to tint/reset

Also includes unrelated pending dotfile changes (GH MCP PAT from
keychain in fish/zsh, kitty/wezterm font_size 15->14, kitty
colorspace displayp3) committed together at user request.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Anton Volnuhin 2026-05-19 23:08:32 +03:00
parent fe835de7f1
commit 1590a272aa
9 changed files with 143 additions and 6 deletions

View File

@ -33,3 +33,5 @@ command -v atuin >/dev/null 2>&1 && eval "$(atuin init zsh --disable-up-arrow)"
# Added by LM Studio CLI (lms) # Added by LM Studio CLI (lms)
export PATH="$PATH:$HOME/.cache/lm-studio/bin" export PATH="$PATH:$HOME/.cache/lm-studio/bin"
[[ -r "$HOME/.codex/github-mcp-env.zsh" ]] && source "$HOME/.codex/github-mcp-env.zsh"

View File

@ -13,6 +13,7 @@ map cmd+7 goto_tab 7
map cmd+8 goto_tab 8 map cmd+8 goto_tab 8
map cmd+9 goto_tab 9 map cmd+9 goto_tab 9
map shift+enter send_text all \x1b[13;2u map shift+enter send_text all \x1b[13;2u
cursor_trail 0 cursor_trail 0
shell_integration no-cursor shell_integration no-cursor
cursor_shape beam cursor_shape beam
@ -84,7 +85,7 @@ font_features Menligaturized-Regular -liga
#font_family MesloLGS NF #font_family MesloLGS NF
shell . shell .
allow_remote_control yes allow_remote_control yes
font_size 15 font_size 14
#macos_thicken_font 1 #macos_thicken_font 1
text_composition_strategy 1.7 50 text_composition_strategy 1.7 50
@ -1603,8 +1604,8 @@ macos_menubar_title_max_length 0
#: mouse cursor invisible on dual GPU machines. Changing this option #: mouse cursor invisible on dual GPU machines. Changing this option
#: by reloading the config is not supported. #: by reloading the config is not supported.
#macos_colorspace displayp3 macos_colorspace displayp3
macos_colorspace srgb #macos_colorspace srgb
#: The colorspace in which to interpret terminal colors. The default #: The colorspace in which to interpret terminal colors. The default
#: of srgb will cause colors to match those seen in web browsers. The #: of srgb will cause colors to match those seen in web browsers. The

View File

@ -62,6 +62,7 @@ if type -q ip
end end
function s function s
__kitty_tab_set (__kitty_ssh_host $argv)
# auto-tmux when called as: s <host> <session> # auto-tmux when called as: s <host> <session>
if test (count $argv) -eq 2; and not string match -q -- '-*' $argv[1]; and not string match -q -- '-*' $argv[2] if test (count $argv) -eq 2; and not string match -q -- '-*' $argv[1]; and not string match -q -- '-*' $argv[2]
set -l host $argv[1] set -l host $argv[1]
@ -69,24 +70,28 @@ function s
if test "$TERM" = xterm-kitty if test "$TERM" = xterm-kitty
kitten ssh $host -t "tmux new-session -A -s $session" kitten ssh $host -t "tmux new-session -A -s $session"
else else
ssh $host -t "tmux new-session -A -s $session" command ssh $host -t "tmux new-session -A -s $session"
end end
__kitty_tab_reset
return return
end end
if test "$TERM" = xterm-kitty if test "$TERM" = xterm-kitty
kitten ssh $argv kitten ssh $argv
else else
ssh $argv command ssh $argv
end end
__kitty_tab_reset
end end
function m function m
__kitty_tab_set (__kitty_ssh_host $argv)
# auto-tmux when called as: m <host> <session> # auto-tmux when called as: m <host> <session>
if test (count $argv) -eq 2; and not string match -q -- '-*' $argv[1]; and not string match -q -- '-*' $argv[2] if test (count $argv) -eq 2; and not string match -q -- '-*' $argv[1]; and not string match -q -- '-*' $argv[2]
set -l host $argv[1] set -l host $argv[1]
set -l session $argv[2] set -l session $argv[2]
command mosh -A $host -- env KITTY_MOSH=1 tmux new-session -A -s $session command mosh -A $host -- env KITTY_MOSH=1 tmux new-session -A -s $session
__kitty_tab_reset
return return
end end
@ -95,6 +100,7 @@ function m
else else
command mosh -A $argv -- env KITTY_MOSH=1 sh -lc 'exec "${SHELL:?}" -l' command mosh -A $argv -- env KITTY_MOSH=1 sh -lc 'exec "${SHELL:?}" -l'
end end
__kitty_tab_reset
end end
@ -181,3 +187,6 @@ fish_add_path $HOME/.antigravity/antigravity/bin
# Added by OrbStack: command-line tools and integration # Added by OrbStack: command-line tools and integration
# This won't be added again if you remove it. # This won't be added again if you remove it.
source ~/.orbstack/shell/init2.fish 2>/dev/null || : source ~/.orbstack/shell/init2.fish 2>/dev/null || :
# GitHub MCP plugin auth — pull PAT from keychain (avoids plaintext in config files)
set -gx GITHUB_PERSONAL_ACCESS_TOKEN (security find-generic-password -s codex-github-mcp-pat -w 2>/dev/null)

View File

@ -0,0 +1,58 @@
function __kitty_host_color -d "Map an ssh host/alias to a stable 'bg fg' hex pair for the kitty tab"
set -l host $argv[1]
# ---- Explicit table for known hosts (alias OR resolved hostname) ----
# Keep colors meaningful: infra/routers = warm/danger, personal cloud = blue,
# local heavy box = green, geo VPS = a varied but recognizable palette.
set -l bg
switch $host
# Routers / network gear — orange = "you are touching the plumbing"
case '192.168.1.1' '192.168.15.1' 'proxmox'
set bg ff8c00
# Home Unbound resolvers (see reset-zone) — amber, sibling of routers
case '192.168.88.88' '192.168.11.11'
set bg d79921
# ryzen / mini — local powerhouse boxes — green
case ryzen mini 'mini.*' 'mini-*'
set bg 689d6a
# Personal cloud (beslan / setia / zephyr.setia.cloud) — blue
case 'beslan*' setia 'setia*' 'zephyr*' '*.setia.cloud'
set bg 2e84e6
# Riga boxes — teal
case 'riga*'
set bg 1abc9c
# Finland / Helsinki — purple
case fi 'fi-*' hel hel2
set bg 9b59b6
# US (NJ / NY) — red-ish, "far away prod"
case nj 'nj-*' ny 'ny-*'
set bg e74c3c
# Stockholm / Tallinn / Vilnius / Krasnodar / Voronezh — slate blue
case sth tln vln krd vrn kz blr highland riga am
set bg 5b7bb4
case '*'
set bg ''
end
# ---- Hash fallback: stable, curated palette so every host is distinct ----
set -l kind explicit
if test -z "$bg"
set kind hash
set -l palette 458588 b16286 d65d0e 689d6a d79921 8f3f71 \
076678 af3a03 427b58 9d0006 b57614 8ec07c \
cc241d 98971a d5c4a1 fb4934
set -l n (printf '%s' "$host" | cksum | string split ' ')[1]
set -l idx (math "$n % "(count $palette)" + 1")
set bg $palette[$idx]
end
# ---- Pick readable fg (black/white) from bg luminance ----
set -l r (math "0x"(string sub -s 1 -l 2 $bg))
set -l g (math "0x"(string sub -s 3 -l 2 $bg))
set -l b (math "0x"(string sub -s 5 -l 2 $bg))
set -l lum (math -s0 "0.299 * $r + 0.587 * $g + 0.114 * $b")
set -l fg ffffff
test $lum -gt 150; and set fg 000000
echo "#$bg #$fg $kind"
end

View File

@ -0,0 +1,24 @@
function __kitty_ssh_host -d "Extract the target host token from ssh/mosh-style argv"
# Skip short options that consume a following argument (ssh + mosh-ish).
set -l argtaking b c D E e F I i J L l m O o p Q R S W w P
set -l host ''
set -l skip 0
for tok in $argv
if test $skip -eq 1
set skip 0
continue
end
if string match -q -- '-*' $tok
set -l opt (string sub -s 2 -l 1 -- $tok)
if test (string length -- $tok) -eq 2; and contains -- $opt $argtaking
set skip 1
end
continue
end
set host $tok
break
end
set host (string replace -r '.*@' '' -- $host) # strip user@
set host (string replace -r ':.*' '' -- $host) # strip :port (scp-style)
echo $host
end

View File

@ -0,0 +1,7 @@
function __kitty_tab_reset -d "Revert kitty tab color/title to theme defaults"
set -q KITTY_WINDOW_ID; and type -q kitten
or return 0
kitten @ set-tab-color active_bg=NONE active_fg=NONE \
inactive_bg=NONE inactive_fg=NONE 2>/dev/null
kitten @ set-tab-title "" 2>/dev/null
end

View File

@ -0,0 +1,25 @@
function __kitty_tab_set -d "Tint the current kitty tab for the given ssh/mosh host"
set -l host $argv[1]
set -q KITTY_WINDOW_ID; and type -q kitten; and test -n "$host"
or return 0
set -l colors (__kitty_host_color $host)
# If the typed name only got a hash color, retry with the
# ssh_config-resolved hostname (it may be in the explicit table).
if test (string split ' ' $colors)[3] = hash
set -l resolved (command ssh -G $host 2>/dev/null \
| string match -r '^hostname .*' | string split ' ')[2]
if test -n "$resolved"; and test "$resolved" != "$host"
set -l rcolors (__kitty_host_color $resolved)
test (string split ' ' $rcolors)[3] = explicit; and set colors $rcolors
end
end
set -l bg (string split ' ' $colors)[1]
set -l fg (string split ' ' $colors)[2]
# Active tab: full host-color background, readable fg.
# Inactive tab: keep theme's dark background (NONE), host color as text only.
kitten @ set-tab-color "active_bg=$bg" "active_fg=$fg" \
"inactive_bg=NONE" "inactive_fg=$bg" 2>/dev/null
kitten @ set-tab-title "$host" 2>/dev/null
end

View File

@ -0,0 +1,11 @@
function ssh -d "ssh wrapper: tint the kitty tab by target host, reset on exit"
if not set -q KITTY_WINDOW_ID; or not type -q kitten
command ssh $argv
return $status
end
__kitty_tab_set (__kitty_ssh_host $argv)
command ssh $argv
set -l rc $status
__kitty_tab_reset
return $rc
end

View File

@ -91,7 +91,7 @@ config.quit_when_all_windows_are_closed = false
config.color_scheme = 'Galaxy' config.color_scheme = 'Galaxy'
config.font = wezterm.font('Jetbrains Mono', { weight = 600 }) config.font = wezterm.font('Jetbrains Mono', { weight = 600 })
config.freetype_load_target = 'Light' config.freetype_load_target = 'Light'
config.font_size = 15 config.font_size = 14
config.line_height = 1.05 config.line_height = 1.05
config.harfbuzz_features = { 'calt=1', 'clig=0', 'liga=0' } config.harfbuzz_features = { 'calt=1', 'clig=0', 'liga=0' }