diff --git a/src/shell.rs b/src/shell.rs index 1a3d4c1..d6a7199 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -122,6 +122,7 @@ function _cj_builtin_cd() {{ \builtin unalias cd 2>/dev/null || : function cd() {{ + typeset -f _cj_record_move >/dev/null || {{ \{builtin} cd "$@"; return; }} local target _cj_status _cj_before _cj_after _cj_nav_arg _cj_nav_mode local _cj_count _cj_remaining _cj_index _cj_up_count _cj_parent local -a _cj_args diff --git a/tests/shell_generation.rs b/tests/shell_generation.rs index 6c756e7..997faf1 100644 --- a/tests/shell_generation.rs +++ b/tests/shell_generation.rs @@ -710,3 +710,56 @@ fn toml_string(path: &Path) -> String { .replace('\\', "\\\\") .replace('"', "\\\"") } + +#[cfg(unix)] +#[test] +fn posix_cd_falls_back_to_builtin_when_helpers_are_missing() { + let temp = TempDir::new("cd-missing-helpers"); + let config = temp.path().join("config.toml"); + fs::write(&config, "").expect("write config"); + let target = temp.path().join("target dir"); + fs::create_dir(&target).expect("create target"); + let expected = fs::canonicalize(&target).expect("canonical target"); + + for (shell, args, strip) in [ + ( + "bash", + ["--noprofile", "--norc", "-c"], + "for f in $(compgen -A function _cj_); do unset -f \"$f\"; done", + ), + ( + "zsh", + ["-f", "-c", "--"], + "unfunction ${(k)functions[(I)_cj_*]}", + ), + ] { + if !available(shell) { + eprintln!("skipping {shell} missing-helper test: interpreter is unavailable"); + continue; + } + let source = generate_with_args( + temp.path(), + &config, + ["init", shell, "--no-setup-key-binding"], + ); + let output = Command::new(shell) + .args(args) + .arg(format!( + "eval \"$1\"; {strip}; cd \"$2\" && pwd -P; cd \"$2/missing\" 2>/dev/null; echo \"status=$?\"" + )) + .args(["_", &source, target.to_str().unwrap()]) + .output() + .expect("run shell"); + assert_success(&output); + assert!( + output.stderr.is_empty(), + "{shell}: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert_eq!( + String::from_utf8(output.stdout).unwrap(), + format!("{}\nstatus=1\n", expected.display()), + "{shell}" + ); + } +}