fix(pty): always set TERM/COLORTERM for spawned shells
A GUI/launchd-spawned daemon has no TERM in its environment, so child shells
inherited none and tput/zsh/ncurses failed ('tput: No value for $TERM').
The PTY now defaults TERM=xterm-256color and COLORTERM=truecolor (matching
xterm.js) unless the caller already provides them. Adds a regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,16 @@ impl PtyHandle {
|
||||
cmd.arg(a);
|
||||
}
|
||||
cmd.cwd(&spec.cwd);
|
||||
// Guarantee a terminal environment even when the daemon was launched
|
||||
// without one (GUI/launchd have no TERM, which breaks tput/zsh/ncurses).
|
||||
// xterm.js renders an xterm-256color/truecolor terminal. Caller-provided
|
||||
// values in spec.env win.
|
||||
if !spec.env.iter().any(|(k, _)| k == "TERM") {
|
||||
cmd.env("TERM", "xterm-256color");
|
||||
}
|
||||
if !spec.env.iter().any(|(k, _)| k == "COLORTERM") {
|
||||
cmd.env("COLORTERM", "truecolor");
|
||||
}
|
||||
for (k, v) in &spec.env {
|
||||
cmd.env(k, v);
|
||||
}
|
||||
@@ -125,6 +135,19 @@ mod tests {
|
||||
assert!(text.contains("SPACESH_OK"), "got: {text:?}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn term_is_set_even_without_inherited_env() {
|
||||
// Clear TERM in the parent to emulate a GUI/launchd-spawned daemon.
|
||||
std::env::remove_var("TERM");
|
||||
let mut handle = PtyHandle::spawn(shell_spec("printf %s \"$TERM\"")).unwrap();
|
||||
let mut collected = Vec::new();
|
||||
while let Some(chunk) = handle.output.recv().await {
|
||||
collected.extend_from_slice(&chunk);
|
||||
}
|
||||
let text = String::from_utf8_lossy(&collected);
|
||||
assert!(text.contains("xterm-256color"), "got: {text:?}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn resize_does_not_error() {
|
||||
let handle = PtyHandle::spawn(shell_spec("sleep 0.2")).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user