Respect shell-integration=none in zsh wrapper (#816)
This commit is contained in:
parent
bdfcc74df3
commit
34c6250a37
2 changed files with 138 additions and 2 deletions
|
|
@ -13,7 +13,9 @@
|
|||
# - CMUX_ZSH_ZDOTDIR (set by cmux when it overwrote a user-provided ZDOTDIR)
|
||||
# - unset (zsh treats unset ZDOTDIR as $HOME)
|
||||
|
||||
builtin typeset _cmux_had_ghostty_zdotdir=0
|
||||
if [[ -n "${GHOSTTY_ZSH_ZDOTDIR+X}" ]]; then
|
||||
_cmux_had_ghostty_zdotdir=1
|
||||
builtin export ZDOTDIR="$GHOSTTY_ZSH_ZDOTDIR"
|
||||
builtin unset GHOSTTY_ZSH_ZDOTDIR
|
||||
elif [[ -n "${CMUX_ZSH_ZDOTDIR+X}" ]]; then
|
||||
|
|
@ -31,7 +33,9 @@ fi
|
|||
if [[ -o interactive ]]; then
|
||||
# We overwrote GhosttyKit's injected ZDOTDIR, so manually load Ghostty's
|
||||
# zsh integration if available.
|
||||
if [[ -n "${GHOSTTY_RESOURCES_DIR:-}" ]]; then
|
||||
# Guard on GHOSTTY_ZSH_ZDOTDIR being set by Ghostty. When users configure
|
||||
# shell-integration=none, Ghostty does not set this and we must skip.
|
||||
if [[ "$_cmux_had_ghostty_zdotdir" == "1" && -n "${GHOSTTY_RESOURCES_DIR:-}" ]]; then
|
||||
builtin typeset _cmux_ghostty="$GHOSTTY_RESOURCES_DIR/shell-integration/zsh/ghostty-integration"
|
||||
[[ -r "$_cmux_ghostty" ]] && builtin source -- "$_cmux_ghostty"
|
||||
fi
|
||||
|
|
@ -43,5 +47,5 @@ fi
|
|||
fi
|
||||
fi
|
||||
|
||||
builtin unset _cmux_file _cmux_ghostty _cmux_integ
|
||||
builtin unset _cmux_file _cmux_ghostty _cmux_integ _cmux_had_ghostty_zdotdir
|
||||
}
|
||||
|
|
|
|||
132
tests/test_issue_734_shell_integration_none_respected.py
Normal file
132
tests/test_issue_734_shell_integration_none_respected.py
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Regression for issue #734:
|
||||
cmux wrapper .zshenv should only source Ghostty zsh integration when Ghostty
|
||||
actually enabled shell integration (signaled by GHOSTTY_ZSH_ZDOTDIR being set).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _run_case(
|
||||
*,
|
||||
wrapper_dir: Path,
|
||||
home: Path,
|
||||
orig_zdotdir: Path,
|
||||
ghostty_resources: Path,
|
||||
out_path: Path,
|
||||
ghostty_enabled: bool,
|
||||
) -> tuple[int, str]:
|
||||
env = dict(os.environ)
|
||||
env["HOME"] = str(home)
|
||||
env["ZDOTDIR"] = str(wrapper_dir)
|
||||
env["GHOSTTY_RESOURCES_DIR"] = str(ghostty_resources)
|
||||
env["CMUX_SHELL_INTEGRATION"] = "0"
|
||||
env["CMUX_TEST_OUT"] = str(out_path)
|
||||
|
||||
# Keep input deterministic and local to this test.
|
||||
for key in (
|
||||
"GHOSTTY_ZSH_ZDOTDIR",
|
||||
"CMUX_ZSH_ZDOTDIR",
|
||||
"CMUX_ORIGINAL_ZDOTDIR",
|
||||
"GHOSTTY_SHELL_FEATURES",
|
||||
"GHOSTTY_BIN_DIR",
|
||||
):
|
||||
env.pop(key, None)
|
||||
|
||||
if ghostty_enabled:
|
||||
env["GHOSTTY_ZSH_ZDOTDIR"] = str(orig_zdotdir)
|
||||
else:
|
||||
env["CMUX_ZSH_ZDOTDIR"] = str(orig_zdotdir)
|
||||
|
||||
result = subprocess.run(
|
||||
["zsh", "-d", "-i", "-c", "true"],
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=8,
|
||||
)
|
||||
return (result.returncode, (result.stdout or "") + (result.stderr or ""))
|
||||
|
||||
|
||||
def main() -> int:
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
wrapper_dir = root / "Resources" / "shell-integration"
|
||||
if not (wrapper_dir / ".zshenv").exists():
|
||||
print(f"SKIP: missing wrapper .zshenv at {wrapper_dir}")
|
||||
return 0
|
||||
|
||||
base = Path("/tmp") / f"cmux_issue_734_{os.getpid()}"
|
||||
try:
|
||||
shutil.rmtree(base, ignore_errors=True)
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
home = base / "home"
|
||||
orig = base / "orig-zdotdir"
|
||||
resources = base / "ghostty-resources"
|
||||
home.mkdir(parents=True, exist_ok=True)
|
||||
orig.mkdir(parents=True, exist_ok=True)
|
||||
(resources / "shell-integration" / "zsh").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Keep user startup files inert and local.
|
||||
for filename in (".zshenv", ".zprofile", ".zshrc"):
|
||||
(orig / filename).write_text("", encoding="utf-8")
|
||||
|
||||
marker = base / "ghostty-sourced.txt"
|
||||
(resources / "shell-integration" / "zsh" / "ghostty-integration").write_text(
|
||||
'echo "sourced" >> "$CMUX_TEST_OUT"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
rc, out = _run_case(
|
||||
wrapper_dir=wrapper_dir,
|
||||
home=home,
|
||||
orig_zdotdir=orig,
|
||||
ghostty_resources=resources,
|
||||
out_path=marker,
|
||||
ghostty_enabled=False,
|
||||
)
|
||||
if rc != 0:
|
||||
print(f"FAIL: zsh exited non-zero when ghostty_enabled=False rc={rc}")
|
||||
if out.strip():
|
||||
print(out.strip())
|
||||
return 1
|
||||
if marker.exists():
|
||||
print("FAIL: ghostty integration sourced when Ghostty shell integration was disabled")
|
||||
return 1
|
||||
|
||||
rc, out = _run_case(
|
||||
wrapper_dir=wrapper_dir,
|
||||
home=home,
|
||||
orig_zdotdir=orig,
|
||||
ghostty_resources=resources,
|
||||
out_path=marker,
|
||||
ghostty_enabled=True,
|
||||
)
|
||||
if rc != 0:
|
||||
print(f"FAIL: zsh exited non-zero when ghostty_enabled=True rc={rc}")
|
||||
if out.strip():
|
||||
print(out.strip())
|
||||
return 1
|
||||
if not marker.exists():
|
||||
print("FAIL: ghostty integration not sourced when Ghostty shell integration was enabled")
|
||||
return 1
|
||||
|
||||
contents = marker.read_text(encoding="utf-8")
|
||||
if "sourced" not in contents:
|
||||
print("FAIL: expected marker output missing after enabled run")
|
||||
return 1
|
||||
|
||||
print("PASS: wrapper respects Ghostty shell-integration=none via GHOSTTY_ZSH_ZDOTDIR gate")
|
||||
return 0
|
||||
finally:
|
||||
shutil.rmtree(base, ignore_errors=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue