Last active
September 4, 2025 12:53
-
-
Save jahands/f08844ca1a310b88881b62c8d117a016 to your computer and use it in GitHub Desktop.
zoxide wrapper to prevent leaving current repo (add to .zshrc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# alias to jump to repo root | |
alias zz='cd $(git rev-parse --show-toplevel)' | |
# global cache for repo root | |
typeset -A _ZO_REPO_CACHE | |
# custom zoxide wrapper to prevent leaving the repo | |
function z() { | |
# special cases: use regular zoxide behavior | |
# "-" = jump to previous dir, $HOME = unlikely to be a git repo | |
if [[ "$1" == "-" || "$PWD" == "$HOME" ]]; then | |
__zoxide_z "$@" | |
return | |
fi | |
local root | |
# check if we have a cached root and if we're still in it | |
if [[ -n "$_ZO_REPO_CACHE[root]" ]] && [[ "$PWD/" == "$_ZO_REPO_CACHE[root]"/* || "$PWD" == "$_ZO_REPO_CACHE[root]" ]]; then | |
root="$_ZO_REPO_CACHE[root]" | |
else | |
# not in cached repo or no cache, get new root | |
root="$(git rev-parse --show-toplevel 2>/dev/null)" || { | |
# clear cache if we're not in a repo | |
unset '_ZO_REPO_CACHE[root]' | |
__zoxide_z "$@"; return | |
} | |
# cache the new root | |
_ZO_REPO_CACHE[root]="$root" | |
fi | |
# ask zoxide for candidates (scored), filter to paths under the repo root, then | |
# select the next candidate after $PWD (wraps to the first if at the end). | |
# This preserves zoxide's repeated-call cycling behavior within the repo. | |
local target | |
target="$( | |
zoxide query -ls -- "$@" | awk -v r="$root" -v c="$PWD" ' | |
BEGIN { first=""; seen=0; printed=0 } | |
{ | |
p = $0 | |
# Strip leading score and whitespace, if present | |
sub(/^[[:space:]]*[0-9.]+[[:space:]]+/, "", p) | |
# Consider only paths under the repo root | |
if (index(p, r"/") == 1 || p == r) { | |
# Remember the first candidate (highest score under root) | |
if (first == "") first = p | |
# If we already saw current dir, the next candidate is our target | |
if (seen == 1) { | |
print p | |
printed = 1 | |
exit | |
} | |
# Mark when we reach the current directory in the list | |
if (p == c) seen = 1 | |
} | |
} | |
END { | |
# If nothing printed (current not found or was last), wrap to first | |
if (!printed && first != "") print first | |
} | |
' | |
)" || return 1 | |
[[ -n "$target" ]] && cd "$target" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment