ssh kitten: Allow changing terminal colors when connecting

This commit is contained in:
Kovid Goyal 2022-04-08 12:10:59 +05:30
parent c3b23679f3
commit dd331ca12e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 50 additions and 1 deletions

View File

@ -9,6 +9,8 @@ Truly convenient SSH
* Make kitty itself available in the remote host :opt:`on demand <kitten-ssh.remote_kitty>` * Make kitty itself available in the remote host :opt:`on demand <kitten-ssh.remote_kitty>`
* Easily :opt:`change terminal colors <kitten-ssh.color_scheme>` when connecting to remote hosts
.. versionadded:: 0.25.0 .. versionadded:: 0.25.0
Automatic shell integration, file transfer and reuse of connections Automatic shell integration, file transfer and reuse of connections

View File

@ -28,6 +28,7 @@ from typing import (
Union Union
) )
from kittens.tui.operations import restore_colors, save_colors
from kitty.constants import ( from kitty.constants import (
cache_dir, runtime_dir, shell_integration_dir, ssh_control_master_template, cache_dir, runtime_dir, shell_integration_dir, ssh_control_master_template,
str_version, terminfo_dir str_version, terminfo_dir
@ -35,7 +36,7 @@ from kitty.constants import (
from kitty.options.types import Options from kitty.options.types import Options
from kitty.shm import SharedMemory from kitty.shm import SharedMemory
from kitty.types import run_once from kitty.types import run_once
from kitty.utils import SSHConnectionData, set_echo as turn_off_echo from kitty.utils import SSHConnectionData, set_echo as turn_off_echo, expandvars, resolve_abs_or_config_path
from .completion import complete, ssh_options from .completion import complete, ssh_options
from .config import init_config from .config import init_config
@ -598,6 +599,34 @@ def drain_potential_tty_garbage(p: 'subprocess.Popen[bytes]', data_request: str)
data += q data += q
def change_colors(color_scheme: str) -> bool:
if not color_scheme:
return False
from kittens.themes.collection import load_themes, NoCacheFound, text_as_opts
from kittens.themes.main import colors_as_escape_codes
if color_scheme.endswith('.conf'):
conf_file = resolve_abs_or_config_path(color_scheme)
try:
with open(conf_file) as f:
opts = text_as_opts(f.read())
except FileNotFoundError:
raise SystemExit(f'Failed to find the color conf file: {expandvars(conf_file)}')
else:
try:
themes = load_themes(-1)
except NoCacheFound:
themes = load_themes()
cs = expandvars(color_scheme)
try:
theme = themes[cs]
except KeyError:
raise SystemExit(f'Failed to find the color theme: {cs}')
opts = theme.kitty_opts
raw = colors_as_escape_codes(opts)
print(save_colors(), sep='', end=raw, flush=True)
return True
def run_ssh(ssh_args: List[str], server_args: List[str], found_extra_args: Tuple[str, ...]) -> NoReturn: def run_ssh(ssh_args: List[str], server_args: List[str], found_extra_args: Tuple[str, ...]) -> NoReturn:
cmd = [ssh_exe()] + ssh_args cmd = [ssh_exe()] + ssh_args
hostname, remote_args = server_args[0], server_args[1:] hostname, remote_args = server_args[0], server_args[1:]
@ -650,6 +679,7 @@ def run_ssh(ssh_args: List[str], server_args: List[str], found_extra_args: Tuple
rcmd, replacements, shm_name = get_remote_command( rcmd, replacements, shm_name = get_remote_command(
remote_args, host_opts, hostname_for_match, uname, echo_on, request_data=need_to_request_data) remote_args, host_opts, hostname_for_match, uname, echo_on, request_data=need_to_request_data)
cmd += rcmd cmd += rcmd
colors_changed = change_colors(host_opts.color_scheme)
try: try:
p = subprocess.Popen(cmd) p = subprocess.Popen(cmd)
except FileNotFoundError: except FileNotFoundError:
@ -661,6 +691,9 @@ def run_ssh(ssh_args: List[str], server_args: List[str], found_extra_args: Tuple
raise SystemExit(p.wait()) raise SystemExit(p.wait())
except KeyboardInterrupt: except KeyboardInterrupt:
raise SystemExit(1) raise SystemExit(1)
finally:
if colors_changed:
print(end=restore_colors(), flush=True)
def main(args: List[str]) -> NoReturn: def main(args: List[str]) -> NoReturn:

View File

@ -103,6 +103,15 @@ value are expanded. The default is empty so no changing is done, which
usually means the home directory is used. usually means the home directory is used.
''') ''')
opt('color_scheme', '', long_text='''
Specify a color scheme to use when connecting to the remote host. If the
color_scheme ends with :code:`.conf` it is assumed to be the name of a config
file to load from the kitty config directory, otherwise it is assumed to be the
name of a color theme to load via the themes kitten. Note that only colors
applying to the text/background are changed, other config settings in the .conf
files/themes are ignored.
''')
opt('remote_kitty', 'if-needed', choices=('if-needed', 'no', 'yes'), long_text=''' opt('remote_kitty', 'if-needed', choices=('if-needed', 'no', 'yes'), long_text='''
Make kitty available on the remote server. Useful to run kittens such as the Make kitty available on the remote server. Useful to run kittens such as the
icat kitten to display images or the transfer file kitten to transfer files. icat kitten to display images or the transfer file kitten to transfer files.

View File

@ -15,6 +15,9 @@ class Parser:
choices_for_askpass = frozenset(('unless-set', 'ssh', 'native')) choices_for_askpass = frozenset(('unless-set', 'ssh', 'native'))
def color_scheme(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['color_scheme'] = str(val)
def copy(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: def copy(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
for k, v in copy(val, ans["copy"]): for k, v in copy(val, ans["copy"]):
ans["copy"][k] = v ans["copy"][k] = v

View File

@ -12,6 +12,7 @@ else:
option_names = ( # {{{ option_names = ( # {{{
'askpass', 'askpass',
'color_scheme',
'copy', 'copy',
'cwd', 'cwd',
'env', 'env',
@ -26,6 +27,7 @@ option_names = ( # {{{
class Options: class Options:
askpass: choices_for_askpass = 'unless-set' askpass: choices_for_askpass = 'unless-set'
color_scheme: str = ''
cwd: str = '' cwd: str = ''
hostname: str = '*' hostname: str = '*'
interpreter: str = 'sh' interpreter: str = 'sh'