mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 02:02:14 +02:00
Dont rely on env -0 for bash either
This commit is contained in:
@@ -497,6 +497,51 @@ def parse_opts_for_clone(args: List[str]) -> LaunchCLIOptions:
|
|||||||
return default_opts
|
return default_opts
|
||||||
|
|
||||||
|
|
||||||
|
def parse_bash_env(text: str) -> Dict[str, str]:
|
||||||
|
# See https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
|
||||||
|
ans = {}
|
||||||
|
pos = 0
|
||||||
|
escapes = r'"\$`'
|
||||||
|
while pos < len(text):
|
||||||
|
idx = text.find('="', pos)
|
||||||
|
if idx < 0:
|
||||||
|
break
|
||||||
|
i = text.rfind(' ', 0, idx)
|
||||||
|
if i < 0:
|
||||||
|
break
|
||||||
|
key = text[i+1:idx]
|
||||||
|
pos = idx + 2
|
||||||
|
buf: List[str] = []
|
||||||
|
a = buf.append
|
||||||
|
while pos < len(text):
|
||||||
|
ch = text[pos]
|
||||||
|
pos += 1
|
||||||
|
if ch == '\\':
|
||||||
|
if text[pos] in escapes:
|
||||||
|
a(text[pos])
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
a(ch)
|
||||||
|
elif ch == '"':
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
a(ch)
|
||||||
|
ans[key] = ''.join(buf)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def parse_null_env(text: str) -> Dict[str, str]:
|
||||||
|
ans = {}
|
||||||
|
for line in text.split('\0'):
|
||||||
|
if line:
|
||||||
|
try:
|
||||||
|
k, v = line.split('=', 1)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
ans[k] = v
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class CloneCmd:
|
class CloneCmd:
|
||||||
|
|
||||||
def __init__(self, msg: str) -> None:
|
def __init__(self, msg: str) -> None:
|
||||||
@@ -504,6 +549,7 @@ class CloneCmd:
|
|||||||
self.args: List[str] = []
|
self.args: List[str] = []
|
||||||
self.env: Optional[Dict[str, str]] = None
|
self.env: Optional[Dict[str, str]] = None
|
||||||
self.cwd = ''
|
self.cwd = ''
|
||||||
|
self.envfmt = 'default'
|
||||||
self.pid = -1
|
self.pid = -1
|
||||||
self.parse_message(msg)
|
self.parse_message(msg)
|
||||||
self.opts = parse_opts_for_clone(self.args)
|
self.opts = parse_opts_for_clone(self.args)
|
||||||
@@ -520,14 +566,7 @@ class CloneCmd:
|
|||||||
if k == 'a':
|
if k == 'a':
|
||||||
self.args.append(v)
|
self.args.append(v)
|
||||||
elif k == 'env':
|
elif k == 'env':
|
||||||
self.env = {}
|
self.env = parse_bash_env(v) if self.envfmt == 'bash' else parse_null_env(v)
|
||||||
for line in v.split('\0'):
|
|
||||||
if line:
|
|
||||||
try:
|
|
||||||
k, v = line.split('=', 1)
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
self.env[k] = v
|
|
||||||
elif k == 'cwd':
|
elif k == 'cwd':
|
||||||
self.cwd = v
|
self.cwd = v
|
||||||
elif k == 'argv':
|
elif k == 'argv':
|
||||||
|
|||||||
@@ -357,3 +357,10 @@ PS1="{ps1}"
|
|||||||
run_test('bash +O login_shell -ic "echo ok;read"', 'bash.bashrc', excluded=('.bash_profile'), wait_string='ok', assert_not_in=True)
|
run_test('bash +O login_shell -ic "echo ok;read"', 'bash.bashrc', excluded=('.bash_profile'), wait_string='ok', assert_not_in=True)
|
||||||
run_test('bash -l .bashrc', 'profile', rc='echo ok;read', wait_string='ok', assert_not_in=True)
|
run_test('bash -l .bashrc', 'profile', rc='echo ok;read', wait_string='ok', assert_not_in=True)
|
||||||
run_test('bash -il -- .bashrc', 'profile', rc='echo ok;read', wait_string='ok')
|
run_test('bash -il -- .bashrc', 'profile', rc='echo ok;read', wait_string='ok')
|
||||||
|
|
||||||
|
with self.run_shell(rc=f'''PS1="{ps1}"\nexport ES=$'a\n `b` c\n$d' ''') as pty:
|
||||||
|
pty.callbacks.clear()
|
||||||
|
pty.send_cmd_to_child('clone-in-kitty')
|
||||||
|
pty.wait_till(lambda: len(pty.callbacks.clone_cmds) == 1)
|
||||||
|
env = pty.callbacks.clone_cmds[0].env
|
||||||
|
self.ae(env.get('ES'), 'a\n `b` c\n$d')
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ case :$SHELLOPTS: in
|
|||||||
*:posix:*) ;;
|
*:posix:*) ;;
|
||||||
*)
|
*)
|
||||||
clone-in-kitty() {
|
clone-in-kitty() {
|
||||||
builtin local data="argv=${_ksi_prompt[argv]},cwd=$(builtin printf "%s" "$PWD" | builtin command base64),env=$(builtin command env -0 | builtin command base64)"
|
builtin local data="argv=${_ksi_prompt[argv]},cwd=$(builtin printf "%s" "$PWD" | builtin command base64),envfmt=bash,env=$(builtin export | builtin command base64)"
|
||||||
while :; do
|
while :; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"") break;;
|
"") break;;
|
||||||
|
|||||||
Reference in New Issue
Block a user