Suggestion: Execute and select next item

Hi! First of all, atuin is awesome, thank you :smiley:

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-next which if you just have edit foo without having rebuild next, it searches for the previous edit foo (like Ctrl-R does) which has rebuild after it, and infers that you probably want rebuild again.
  • accept-and-hold, which supposing you have some 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 do some long command bar.

However, as for implementation, I’m not sure what’s best, I see two approaches, both with some downsides:

  1. Do the execute within the atuin process, makes next command easy but then atuin would have to deal with executing stuff which presumably comes with a lot of edge cases.
  2. Somehow tell the shell to reopen atuin after 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 in precmd, and open atuin.
    But this still requires some modification in atuin to 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

I use zle infer-next-history && zle up-history at the end of _atuin_search to position zle to the same history entry inside zsh’s own history when not executing the result so that ^o works. You can also run zle accept-line-and-infer-next to run the command and let zsh put you the place inside zsh’s history.

But be aware that this may conflict with some plugins and thus didn’t make it into atuin’s codebase.


atuin doesn’t have a linear history, so it would be ambiguous which command is next. Also, atuin searches the history and shows the results, not shows the history in some linear form. How would atuin show the next command?