Remote control launch: Fix the --copy-env option not copying current environment variables
Fixes #6724
This commit is contained in:
parent
d2026574b8
commit
ddb121b418
5 changed files with 63 additions and 11 deletions
|
|
@ -62,6 +62,8 @@ Detailed list of changes
|
|||
|
||||
- Fix trailing bracket not ignored when detecting a multi-line URL with the trailing bracket as the first character on the last line (:iss:`6710`)
|
||||
|
||||
- Remote control launch: Fix the ``--copy-env`` option not copying current environment variables (:iss:`6724`)
|
||||
|
||||
|
||||
0.30.1 [2023-10-05]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ def generate_completions_for_kitty() -> None:
|
|||
|
||||
|
||||
def go_field_type(json_field_type: str) -> str:
|
||||
json_field_type = json_field_type.partition('=')[0]
|
||||
q = json_field_types.get(json_field_type)
|
||||
if q:
|
||||
return q
|
||||
|
|
@ -324,6 +325,7 @@ def __init__(self, line: str) -> None:
|
|||
field_def = line.split(':', 1)[0]
|
||||
self.required = False
|
||||
self.field, self.field_type = field_def.split('/', 1)
|
||||
self.field_type, self.special_parser = self.field_type.partition('=')[::2]
|
||||
if self.field.endswith('+'):
|
||||
self.required = True
|
||||
self.field = self.field[:-1]
|
||||
|
|
@ -370,14 +372,17 @@ def go_code_for_remote_command(name: str, cmd: RemoteCommand, template: str) ->
|
|||
if oq in option_map:
|
||||
o = option_map[oq]
|
||||
used_options.add(oq)
|
||||
optstring = f'options_{name}.{o.go_var_name}'
|
||||
if field.special_parser:
|
||||
optstring = f'{field.special_parser}({optstring})'
|
||||
if field.field_type == 'str':
|
||||
jc.append(f'payload.{field.struct_field_name} = escaped_string(options_{name}.{o.go_var_name})')
|
||||
jc.append(f'payload.{field.struct_field_name} = escaped_string({optstring})')
|
||||
elif field.field_type == 'list.str':
|
||||
jc.append(f'payload.{field.struct_field_name} = escape_list_of_strings(options_{name}.{o.go_var_name})')
|
||||
jc.append(f'payload.{field.struct_field_name} = escape_list_of_strings({optstring})')
|
||||
elif field.field_type == 'dict.str':
|
||||
jc.append(f'payload.{field.struct_field_name} = escape_dict_of_strings(options_{name}.{o.go_var_name})')
|
||||
jc.append(f'payload.{field.struct_field_name} = escape_dict_of_strings({optstring})')
|
||||
else:
|
||||
jc.append(f'payload.{field.struct_field_name} = options_{name}.{o.go_var_name}')
|
||||
jc.append(f'payload.{field.struct_field_name} = {optstring}')
|
||||
elif field.field in handled_fields:
|
||||
pass
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ def options_spec() -> str:
|
|||
oldest foreground process associated with the currently active window rather
|
||||
than the newest foreground process. Finally, the special value :code:`root`
|
||||
refers to the process that was originally started when the window was created.
|
||||
When running via remote control a value of current uses the working directory
|
||||
for the remote control invocation.
|
||||
|
||||
|
||||
--env
|
||||
|
|
@ -322,10 +324,12 @@ def parse_launch_args(args: Optional[Sequence[str]] = None) -> LaunchSpec:
|
|||
return LaunchSpec(opts, args)
|
||||
|
||||
|
||||
def get_env(opts: LaunchCLIOptions, active_child: Optional[Child] = None) -> Dict[str, str]:
|
||||
def get_env(opts: LaunchCLIOptions, active_child: Optional[Child] = None, base_env: Optional[Dict[str,str]] = None) -> Dict[str, str]:
|
||||
env: Dict[str, str] = {}
|
||||
if opts.copy_env and active_child:
|
||||
env.update(active_child.foreground_environ)
|
||||
if base_env is not None:
|
||||
env.update(base_env)
|
||||
for x in opts.env:
|
||||
for k, v in parse_env(x, env):
|
||||
env[k] = v
|
||||
|
|
@ -456,6 +460,7 @@ def _launch(
|
|||
active: Optional[Window] = None,
|
||||
is_clone_launch: str = '',
|
||||
rc_from_window: Optional[Window] = None,
|
||||
base_env: Optional[Dict[str, str]] = None,
|
||||
) -> Optional[Window]:
|
||||
active = active or boss.active_window_for_cwd
|
||||
if active:
|
||||
|
|
@ -470,7 +475,7 @@ def _launch(
|
|||
if opts.os_window_title == 'current':
|
||||
tm = boss.active_tab_manager
|
||||
opts.os_window_title = get_os_window_title(tm.os_window_id) if tm else None
|
||||
env = get_env(opts, active_child)
|
||||
env = get_env(opts, active_child, base_env)
|
||||
remote_control_restrictions: Optional[Dict[str, Sequence[str]]] = None
|
||||
if opts.allow_remote_control and opts.remote_control_password:
|
||||
from kitty.options.utils import remote_control_password
|
||||
|
|
@ -633,12 +638,13 @@ def launch(
|
|||
active: Optional[Window] = None,
|
||||
is_clone_launch: str = '',
|
||||
rc_from_window: Optional[Window] = None,
|
||||
base_env: Optional[Dict[str, str]] = None,
|
||||
) -> Optional[Window]:
|
||||
active = active or boss.active_window_for_cwd
|
||||
if opts.keep_focus and active:
|
||||
orig, active.ignore_focus_changes = active.ignore_focus_changes, True
|
||||
try:
|
||||
return _launch(boss, opts, args, target_tab, force_target_tab, active, is_clone_launch, rc_from_window)
|
||||
return _launch(boss, opts, args, target_tab, force_target_tab, active, is_clone_launch, rc_from_window, base_env)
|
||||
finally:
|
||||
if opts.keep_focus and active:
|
||||
active.ignore_focus_changes = orig
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING, Dict, Optional
|
||||
|
||||
from kitty.cli_stub import LaunchCLIOptions
|
||||
from kitty.launch import launch as do_launch
|
||||
|
|
@ -21,7 +21,7 @@ class Launch(RemoteCommand):
|
|||
args+/list.str: The command line to run in the new window, as a list, use an empty list to run the default shell
|
||||
match/str: The tab to open the new window in
|
||||
window_title/str: Title for the new window
|
||||
cwd/str: Working directory for the new window
|
||||
cwd/str=copy_local_cwd: Working directory for the new window
|
||||
env/list.str: List of environment variables of the form NAME=VALUE
|
||||
var/list.str: List of user variables of the form NAME=VALUE
|
||||
tab_title/str: Title for the new tab
|
||||
|
|
@ -29,7 +29,7 @@ class Launch(RemoteCommand):
|
|||
keep_focus/bool: Boolean indicating whether the current window should retain focus or not
|
||||
copy_colors/bool: Boolean indicating whether to copy the colors from the current window
|
||||
copy_cmdline/bool: Boolean indicating whether to copy the cmdline from the current window
|
||||
copy_env/bool: Boolean indicating whether to copy the environ from the current window
|
||||
copy_env/list.str=copy_local_env: List of strings representing the local env vars
|
||||
hold/bool: Boolean indicating whether to keep window open after cmd exits
|
||||
location/choices.first.after.before.neighbor.last.vsplit.hsplit.split.default: Where in the tab to open the new window
|
||||
allow_remote_control/bool: Boolean indicating whether to allow remote control from the new window
|
||||
|
|
@ -83,17 +83,30 @@ def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get:
|
|||
default_opts = parse_launch_args()[0]
|
||||
opts = LaunchCLIOptions()
|
||||
for key, default_value in default_opts.__dict__.items():
|
||||
if key == 'copy_env':
|
||||
continue
|
||||
val = payload_get(key)
|
||||
if val is None:
|
||||
val = default_value
|
||||
setattr(opts, key, val)
|
||||
ceval = payload_get('copy_env')
|
||||
opts.copy_env = False
|
||||
base_env: Optional[Dict[str, str]] = None
|
||||
if ceval:
|
||||
if isinstance(ceval, list):
|
||||
base_env = {}
|
||||
for x in ceval:
|
||||
k, v = x.partition('=')[::2]
|
||||
base_env[k] = v
|
||||
elif isinstance(ceval, bool):
|
||||
opts.copy_env = ceval
|
||||
target_tab = None
|
||||
tabs = self.tabs_for_match_payload(boss, window, payload_get)
|
||||
if tabs and tabs[0]:
|
||||
target_tab = tabs[0]
|
||||
elif payload_get('type') not in ('background', 'os-window', 'tab', 'window'):
|
||||
return None
|
||||
w = do_launch(boss, opts, payload_get('args') or [], target_tab=target_tab, rc_from_window=window)
|
||||
w = do_launch(boss, opts, payload_get('args') or [], target_tab=target_tab, rc_from_window=window, base_env=base_env)
|
||||
return None if payload_get('no_response') else str(getattr(w, 'id', 0))
|
||||
|
||||
|
||||
|
|
|
|||
26
tools/cmd/at/launch.go
Normal file
26
tools/cmd/at/launch.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||
|
||||
package at
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
func copy_local_env(copy_env bool) []string {
|
||||
if copy_env {
|
||||
return os.Environ()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func copy_local_cwd(copy_cwd string) string {
|
||||
if copy_cwd == "current" {
|
||||
if c, e := os.Getwd(); e == nil {
|
||||
copy_cwd = c
|
||||
}
|
||||
}
|
||||
return copy_cwd
|
||||
}
|
||||
Loading…
Reference in a new issue