Start work on a command to clone the current working env into a new kitty window
This commit is contained in:
parent
7788f48dd5
commit
c19e69855a
@ -10,7 +10,7 @@ from .cli import parse_args
|
|||||||
from .cli_stub import LaunchCLIOptions
|
from .cli_stub import LaunchCLIOptions
|
||||||
from .constants import kitty_exe, shell_path
|
from .constants import kitty_exe, shell_path
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
get_os_window_title, patch_color_profiles, set_clipboard_string
|
get_boss, get_os_window_title, patch_color_profiles, set_clipboard_string
|
||||||
)
|
)
|
||||||
from .options.utils import env as parse_env
|
from .options.utils import env as parse_env
|
||||||
from .tabs import Tab, TabManager
|
from .tabs import Tab, TabManager
|
||||||
@ -224,7 +224,7 @@ def parse_launch_args(args: Optional[Sequence[str]] = None) -> LaunchSpec:
|
|||||||
return LaunchSpec(opts, args)
|
return LaunchSpec(opts, args)
|
||||||
|
|
||||||
|
|
||||||
def get_env(opts: LaunchCLIOptions, active_child: Optional[Child]) -> Dict[str, str]:
|
def get_env(opts: LaunchCLIOptions, active_child: Optional[Child] = None) -> Dict[str, str]:
|
||||||
env: Dict[str, str] = {}
|
env: Dict[str, str] = {}
|
||||||
if opts.copy_env and active_child:
|
if opts.copy_env and active_child:
|
||||||
env.update(active_child.foreground_environ)
|
env.update(active_child.foreground_environ)
|
||||||
@ -342,7 +342,8 @@ def launch(
|
|||||||
opts: LaunchCLIOptions,
|
opts: LaunchCLIOptions,
|
||||||
args: List[str],
|
args: List[str],
|
||||||
target_tab: Optional[Tab] = None,
|
target_tab: Optional[Tab] = None,
|
||||||
force_target_tab: bool = False
|
force_target_tab: bool = False,
|
||||||
|
base_env: Optional[Dict[str, str]] = None
|
||||||
) -> Optional[Window]:
|
) -> Optional[Window]:
|
||||||
active = boss.active_window_for_cwd
|
active = boss.active_window_for_cwd
|
||||||
if active:
|
if active:
|
||||||
@ -357,6 +358,10 @@ def launch(
|
|||||||
if opts.os_window_title == 'current':
|
if opts.os_window_title == 'current':
|
||||||
tm = boss.active_tab_manager
|
tm = boss.active_tab_manager
|
||||||
opts.os_window_title = get_os_window_title(tm.os_window_id) if tm else None
|
opts.os_window_title = get_os_window_title(tm.os_window_id) if tm else None
|
||||||
|
if base_env:
|
||||||
|
env = base_env.copy()
|
||||||
|
env.update(get_env(opts))
|
||||||
|
else:
|
||||||
env = get_env(opts, active_child)
|
env = get_env(opts, active_child)
|
||||||
kw: LaunchKwds = {
|
kw: LaunchKwds = {
|
||||||
'allow_remote_control': opts.allow_remote_control,
|
'allow_remote_control': opts.allow_remote_control,
|
||||||
@ -470,3 +475,55 @@ def launch(
|
|||||||
new_window.set_logo(opts.logo, opts.logo_position or '', opts.logo_alpha)
|
new_window.set_logo(opts.logo, opts.logo_position or '', opts.logo_alpha)
|
||||||
return new_window
|
return new_window
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_opts_for_clone(args: List[str]) -> LaunchCLIOptions:
|
||||||
|
unsafe, unsafe_args = parse_launch_args(args)
|
||||||
|
default_opts, default_args = parse_launch_args()
|
||||||
|
for x in (
|
||||||
|
'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'env', 'hold',
|
||||||
|
'location', 'os_window_class', 'os_window_name', 'os_window_title',
|
||||||
|
'logo', 'logo_position', 'logo_alpha', 'color'
|
||||||
|
):
|
||||||
|
setattr(default_opts, x, getattr(unsafe, x))
|
||||||
|
return default_opts
|
||||||
|
|
||||||
|
|
||||||
|
def clone_and_launch(msg: str, window: Window) -> None:
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from .child import cmdline_of_process
|
||||||
|
args = []
|
||||||
|
env: Dict[str, str] = {}
|
||||||
|
cwd = ''
|
||||||
|
pid = -1
|
||||||
|
|
||||||
|
for x in msg.split(','):
|
||||||
|
k, v = x.split('=', 1)
|
||||||
|
if k == 'pid':
|
||||||
|
pid = int(v)
|
||||||
|
continue
|
||||||
|
v = base64.standard_b64decode(v).decode('utf-8', 'replace')
|
||||||
|
if k == 'a':
|
||||||
|
args.append(v)
|
||||||
|
elif k == 'env':
|
||||||
|
for line in v.split('\0'):
|
||||||
|
if line:
|
||||||
|
try:
|
||||||
|
k, v = line.split('=', 1)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
env[k] = v
|
||||||
|
elif k == 'cwd':
|
||||||
|
cwd = v.rstrip()
|
||||||
|
opts = parse_opts_for_clone(args)
|
||||||
|
if cwd:
|
||||||
|
opts.cwd = cwd
|
||||||
|
opts.copy_colors = True
|
||||||
|
try:
|
||||||
|
cmdline = cmdline_of_process(pid)
|
||||||
|
except Exception:
|
||||||
|
cmdline = []
|
||||||
|
if not cmdline:
|
||||||
|
cmdline = list(window.child.argv)
|
||||||
|
launch(get_boss(), opts, cmdline, base_env=env)
|
||||||
|
|||||||
@ -1086,6 +1086,7 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
|||||||
} else IF_SIMPLE_PREFIX("echo|", handle_remote_echo)
|
} else IF_SIMPLE_PREFIX("echo|", handle_remote_echo)
|
||||||
} else IF_SIMPLE_PREFIX("ssh|", handle_remote_ssh)
|
} else IF_SIMPLE_PREFIX("ssh|", handle_remote_ssh)
|
||||||
} else IF_SIMPLE_PREFIX("ask|", handle_remote_askpass)
|
} else IF_SIMPLE_PREFIX("ask|", handle_remote_askpass)
|
||||||
|
} else IF_SIMPLE_PREFIX("clone|", handle_remote_clone)
|
||||||
#undef IF_SIMPLE_PREFIX
|
#undef IF_SIMPLE_PREFIX
|
||||||
} else {
|
} else {
|
||||||
REPORT_ERROR("Unrecognized DCS @ code: 0x%x", screen->parser_buf[1]);
|
REPORT_ERROR("Unrecognized DCS @ code: 0x%x", screen->parser_buf[1]);
|
||||||
|
|||||||
@ -473,6 +473,7 @@ class Window:
|
|||||||
self.watchers = global_watchers().copy()
|
self.watchers = global_watchers().copy()
|
||||||
self.last_focused_at = 0.
|
self.last_focused_at = 0.
|
||||||
self.started_at = monotonic()
|
self.started_at = monotonic()
|
||||||
|
self.current_clone_data = ''
|
||||||
self.current_mouse_event_button = 0
|
self.current_mouse_event_button = 0
|
||||||
self.current_clipboard_read_ask: Optional[bool] = None
|
self.current_clipboard_read_ask: Optional[bool] = None
|
||||||
self.prev_osc99_cmd = NotificationCommand()
|
self.prev_osc99_cmd = NotificationCommand()
|
||||||
@ -1009,6 +1010,19 @@ class Window:
|
|||||||
if tab is not None:
|
if tab is not None:
|
||||||
tab.move_window_to_top_of_group(self)
|
tab.move_window_to_top_of_group(self)
|
||||||
|
|
||||||
|
def handle_remote_clone(self, msg: str) -> None:
|
||||||
|
if not msg:
|
||||||
|
if self.current_clone_data:
|
||||||
|
cdata, self.current_clone_data = self.current_clone_data, ''
|
||||||
|
from .launch import clone_and_launch
|
||||||
|
clone_and_launch(cdata, self)
|
||||||
|
self.current_clone_data = ''
|
||||||
|
return
|
||||||
|
num, rest = msg.split(':', 1)
|
||||||
|
if num == '0' or len(self.current_clone_data) > 1024 * 1024:
|
||||||
|
self.current_clone_data = ''
|
||||||
|
self.current_clone_data += msg
|
||||||
|
|
||||||
def handle_remote_askpass(self, msg: str) -> None:
|
def handle_remote_askpass(self, msg: str) -> None:
|
||||||
from .shm import SharedMemory
|
from .shm import SharedMemory
|
||||||
with SharedMemory(name=msg, readonly=True) as shm:
|
with SharedMemory(name=msg, readonly=True) as shm:
|
||||||
|
|||||||
@ -354,3 +354,24 @@ _ksi_deferred_init() {
|
|||||||
# to unfunction themselves when invoked. Unfunctioning is done by calling code.
|
# to unfunction themselves when invoked. Unfunctioning is done by calling code.
|
||||||
builtin unfunction _ksi_deferred_init
|
builtin unfunction _ksi_deferred_init
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone-in-kitty() {
|
||||||
|
builtin local data="pid=$$,cwd=$(builtin pwd -P | builtin command base64),env=$(builtin command env -0 | builtin command base64)"
|
||||||
|
while :; do
|
||||||
|
case "$1" in
|
||||||
|
"") break;;
|
||||||
|
*) data="$data,a=$(builtin printf "%s" "$1" | builtin command base64)";;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
data="${data//[[:space:]]}"
|
||||||
|
builtin local pos=0
|
||||||
|
builtin local chunk_num=0
|
||||||
|
while [ $pos -lt ${#data} ]; do
|
||||||
|
builtin local chunk="${data:$pos:2048}"
|
||||||
|
pos=$(($pos+2048))
|
||||||
|
builtin print -nu "$_ksi_fd" '\eP@kitty-clone|'"${chunk}:"'\e\\'
|
||||||
|
chunk_num=$(($chunk_num+1))
|
||||||
|
done
|
||||||
|
builtin print -nu "$_ksi_fd" '\eP@kitty-clone|\e\\'
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user