That's why I use fish. Not only does it cycle like that by default, but it autocompletes entire commands, searches for the substring in the middle of words, looks better, is faster, etc etc.
I tried oh-my-zsh for that, but it was very slow to start up. I went back to fish when I realized that I had basically set up zsh to act exactly like fish.
I've been using Fish on my Mac for a while as well as some VPS' I have. At work I just installed it on our dev server.
It has a build in git status script you can include in your prompt that's awesome. Here's my fish prompt (note __fish_git_prompt):
function fish_prompt
set last_status $status
set_color $fish_color_cwd
printf '%s' (prompt_pwd)
set_color normal
printf '%s ' (__fish_git_prompt)
set_color normal
end
It's unfortunately on the one hand too beholden to POSIX shell behavior, while still being too different from mainline Bourne derivatives. I've tried it a few times, and the cognitive load is too extreme for my 20+ yrs of POSIX brain-damage to work around.
I don't use fish for shell scripting, but I'm enjoying it as my primary environment after making these adjustments..
Status codes and argument lists:
$status # replaces $?
$argv # replaces $@
Aliases are just functions (configure your startup in
~/.config/fish/config.fish):
# alias ls="ls -lrth"
function lr; ls -lrth $argv; end
For-loops are familiar:
# for n in one two three; do echo $n; done
for n in one two three; echo $n; end
The lack of '!$' confounded my hard-wired fingers until I settled on Alt-u to avoid up-arrows (see /usr/share/fish/functions/fish_default_key_bindings.fish):
The remaining price for fish's pseudo-telepathic assistance is the occasional frustration with applications that rely on the value of a user's default shell (/etc/passwd).