zsh: expand leading named directory when CDABLE_VARS is set

`z foo bar` now expands a leading zsh named directory (e.g. `~foo`)
without requiring the `~` prefix, but only when the user has opted in
via `setopt CDABLE_VARS` -- mirroring how `cd` treats its argument under
that option. A pattern guard restricts the expanded token to identifier
names so it is safe to pass through `eval`, which re-parses `~name` so
zsh performs named-directory expansion.

Closes #396.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NLxGrHd3q7cWKJkT9S3HrU
This commit is contained in:
Claude 2026-07-16 08:44:58 +00:00
parent 670bdf21b9
commit bfcb1b6b4c
No known key found for this signature in database
2 changed files with 17 additions and 0 deletions

View File

@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Zsh: when `CDABLE_VARS` is set, `z` now expands a leading named directory
without requiring the `~` prefix (e.g. `z foo bar` searches within `~foo`).
### Fixed
- Bash/Zsh: fix `z` failing on Cygwin/MSYS2 due to `cygpath` being passed a bad string.

View File

@ -97,6 +97,18 @@ function __zoxide_z() {
__zoxide_cd "$2"
else
\builtin local result
# When CDABLE_VARS is set, expand a leading named directory without its
# '~' prefix, mirroring how `cd` treats its argument, e.g. `z foo bar`
# searches within `~foo`. The pattern guard restricts `$1` to identifier
# names so that passing it to `eval` is safe; `eval` re-parses `~name`
# so that zsh performs named-directory expansion on it.
if [[ -o cdablevars ]] && [[ "$1" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then
\builtin local dir
\builtin eval "dir=~$1" 2>/dev/null
if [[ "${dir}" != "~$1" ]] && [[ -d "${dir}" ]]; then
\builtin set -- "${dir}" "${@:2}"
fi
fi
# shellcheck disable=SC2312
result="$(\command zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${result}"
fi