From faca67e0af60abccf234165e65acbd479acaa831 Mon Sep 17 00:00:00 2001 From: Ukang'a Dickson Date: Tue, 21 Apr 2026 16:28:07 +0300 Subject: [PATCH] fix(shell): restore ZDOTDIR and source full zsh startup chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The zsh wrapper pointed ZDOTDIR at a temp directory containing only a synthetic .zshrc. This caused two correctness problems for any zsh setup that depends on ZDOTDIR or .zshenv: - `.zshenv` was silently skipped, because zsh reads it from the overridden temp ZDOTDIR before our wrapper runs. PATH additions, env vars, and bootstraps (nvm, pyenv, etc.) placed there were lost inside wt shells. - Frameworks that locate files via `${ZDOTDIR:-$HOME}/...` — e.g. prezto's `${ZDOTDIR:-$HOME}/.zprezto/init.zsh` — looked in the temp dir and failed to load. Without the framework, `compinit` never ran, so completion loads such as `kops completion zsh` emitted `compdef: command not found`. The wrapper now restores ZDOTDIR to _WT_ORIG_ZDOTDIR first, re-sources .zshenv / .zprofile (for login shells) / .zshrc in the normal order from the real ZDOTDIR/HOME, and defines a no-op compdef stub as a safety net for any framework (oh-my-zsh, prezto, zim, custom dotfiles) that calls compdef before compinit runs. --- src/shell.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/shell.rs b/src/shell.rs index 3479514..f2dc2fd 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -83,12 +83,28 @@ fn create_zsh_wrapper() -> Result { let temp_dir = std::env::temp_dir().join(format!("wt-zsh-{}", std::process::id())); std::fs::create_dir_all(&temp_dir)?; - let zshrc_content = r#"# Source user's zshrc -if [[ -n "$_WT_ORIG_ZDOTDIR" ]] && [[ -f "$_WT_ORIG_ZDOTDIR/.zshrc" ]]; then - source "$_WT_ORIG_ZDOTDIR/.zshrc" -elif [[ -f "$HOME/.zshrc" ]]; then - source "$HOME/.zshrc" + let zshrc_content = r#"# Restore ZDOTDIR so frameworks like prezto can locate their files. +if [[ -n "$_WT_ORIG_ZDOTDIR" ]]; then + ZDOTDIR="$_WT_ORIG_ZDOTDIR" +else + unset ZDOTDIR fi +export ZDOTDIR + +# Safety stub: prevents `compdef: command not found` when a startup file calls +# compdef before compinit runs. Real compdef overrides this once compinit loads. +(( $+functions[compdef] )) || compdef() { :; } + +# Re-source startup files in normal order from the real ZDOTDIR/HOME, since +# zsh's own startup sourced them from the overridden temp ZDOTDIR (empty). +_wt_zdot="${ZDOTDIR:-$HOME}" +[[ -f "$_wt_zdot/.zshenv" ]] && source "$_wt_zdot/.zshenv" +if [[ -o login ]]; then + [[ -f "$_wt_zdot/.zprofile" ]] && source "$_wt_zdot/.zprofile" +fi +[[ -f "$_wt_zdot/.zshrc" ]] && source "$_wt_zdot/.zshrc" +unset _wt_zdot + # Add wt indicator to prompt PROMPT="(wt) $PROMPT" "#;