You could do something like:
up-dir() {
set -o localoptions -o pushdsilent
[[ $PWD != / ]] && pushd .. && zle reset-prompt
}
undo-up-dir() {
set -o localoptions -o pushdsilent
# pop a directory only if the current working directory matches
# the "h"ead of the top ([1]) of the directory stack:
[[ $dirstack[1]:h = $PWD ]] && popd && zle reset-prompt
}
zle -N up-dir
zle -N undo-up-dir
bindkey '^[h' up-dir
bindkey '^[b' undo-up-dir
(Alt+↑ ('^[[1;3A' with xterm) and Alt+↓ ('^[[1;3B') may be better shortcuts for that).
Note the &&s to make sure we return a non-zero exit status (which should trigger a beep or other form of failure feedback) when the directory is not changed.
You could also extend that undo-up-dir so that when it can't undo anymore, it could still look whether there's exactly one directory in the current directory and go into it:
down-dir() {
set -o localoptions -o pushdsilent
# pop a directory only if the current working directory matches
# the "h"ead of the top ([1]) of the directory stack:
if [[ $dirstack[1]:h = $PWD ]]; then
popd
else
local -a dirs
dirs=(./*(N/Y2))
(($#dirs)) || dirs=(./*(ND/Y2)) # try including hidden ones
(($#dirs)) || dirs=(./*(N-/Y2)) # try including symlinks to dirs
(($#dirs)) || dirs=(./*(DN-/Y2)) # symlinks and hidden included
(($#dirs == 1)) && cd $dirs
fi && zle reset-prompt
}
cd -? It's almost always possible (unless the directory has been deleted), and if it isn't possible it won't do anything anyway.