Hi! First of all, atuin is awesome, thank you ![]()
My suggestion is based on something I use in zsh frequently: accept-line-and-down-history (mapped to ctrl-o by default, which is how I discovered the inspector – already found that useful to see how long the system update took).
The way it works is very simple, execute the current line (like enter), but then re-open the search again. E.g. if you have a history of
1 # some older stuff
> edit foo
rebuild
and do accept-line-and-down-history then it opens the editor, then when you close it, it has rebuild automatically selected.
It has relatives:
accept-line-and-infer-nextwhich if you just haveedit foowithout havingrebuildnext, it searches for the previousedit foo(like Ctrl-R does) which hasrebuildafter it, and infers that you probably wantrebuildagain.accept-and-hold, which supposing you havesome long command foo, you execute that, it does the long command on foo, and puts you into editing the line again so you can easily dosome long command bar.
However, as for implementation, I’m not sure what’s best, I see two approaches, both with some downsides:
- Do the execute within the
atuinprocess, makes next command easy but thenatuinwould have to deal with executing stuff which presumably comes with a lot of edge cases. - Somehow tell the shell to reopen
atuinafter search. I think this is the better way, but then it might depend on behaviours of different shells… I’m new to shell tweaking so I don’t know if we can just store a variable and read that inprecmd, and openatuin.
But this still requires some modification inatuinto bind this into the search mode.
Having a look at atuin init zsh seems like option 2 is halfway there anyway, given output= in zsh and __atuin_output= in bash. However not sure about the rest so I thought I’d just reach out. I thought something like atuin search -i –-offset=10 etc but the offset doesn’t seem to do what I think it does.
What I started playing around with is
--- atuin-init.zsh 2026-01-03 16:52:15.415411151 +0000
+++ atuin-execute-and-down-history.zsh 2026-01-03 16:50:50.891191275 +0000
@@ -47,6 +47,11 @@ _atuin_precmd() {
(ATUIN_LOG=error atuin history end --exit $EXIT ${duration:+--duration=$duration} -- $ATUIN_HISTORY_ID &) >/dev/null 2>&1
export ATUIN_HISTORY_ID=""
+
+ if [[ "${__atuin_next__%:*}" == offset ]]; then
+ _atuin_search
+ fi
}
_atuin_search() {
@@ -72,6 +77,7 @@ _atuin_search() {
then
LBUFFER=${LBUFFER#__atuin_accept__:}
zle accept-line
+ __atuin_next__=offset:10
fi
fi
}
@@ -121,3 +127,4 @@ bindkey -M emacs '^[OA' atuin-up-search
bindkey -M vicmd '^[OA' atuin-up-search-vicmd
bindkey -M viins '^[OA' atuin-up-search-viins
bindkey -M vicmd 'k' atuin-up-search-vicmd
+bindkey -M emacs '^o' atuin-accept-and-down-history
but this doesn’t work because ZSH doesn’t like being called in precmd (widgets can only be called when ZLE is active). And might have issues with recursion. I tried echoing ^R (raw control R entered via ^V^R) into /dev/tty or /dev/stdin but it doesn’t re-execute search