atuin
atuin copied to clipboard
Key binding to run the command immediately
It'd be nice if there were a key binding that somehow ran the selected command immediately instead of simply placing it on the command line. Having to hit enter twice to run a command I don't want to modify is a tad annoying.
Shift+Enter maybe?
looks like Termion might not support multiple modifiers (like Shift+Enter) yet https://github.com/redox-os/termion/blob/dce5e7500fd709987f9bf8f3911e4daa61d0ad14/src/event.rs#L288
Also not sure how to actually execute the command - apending '\n' or '\u{15}' doesn't seem to help
@elle any idea how we might tell the shell to 'don't just echo this, but execute this!'? Adding \n
or similar to the output doesn't seem to do much. Only other option i can think of is to exec
after echoing the command, but we'll have to most likely start a shell to process the commandline and that gets messy...
haha my name has an i
in it too :)
So the only solution I could think of is really gross. We could return the command with a prefix that could never be in a normal shell command (maybe a space/special comment) and then ZSH could check for this. If it exists, ZSH can then execute the command
It'll have to be done this way as the subprocess won't be able to access the parent context. Plus, anything returned from Atuin is just inserted into the ZLE buffer, regardless of what it is (even newlines).
FYI, mcfly
does this by writing something like this:
mode run
commandline /usr/bin/command args
into a temporary file, parses it in zsh, then use zle accept-line
if mode
is run
(mode
can also be display
, which just inserts the command).
ohhh that's awesome, thanks @yshui!
Was searching for this issue :)
Would be great to have the key combo for this configurable. I would tend to use Ctrl+Enter
instead of the already mentioned Shift+Enter
.
Edit: Just found where to start, maybe I'll implement it in the coming weeks. I also just noticed for me some other Keybindings like Ctrl+Left/Right
to jump words or Pos1
and End
are not working, maybe I can debug this also.
:smiley: This was one of the first things I tried to do in interactive mode.
My keybind preference would be TAB
to return-query
, ESC
to return-original
and ENTER
to return-execute
, where the latter is a new ExitMode
. I just briefly looked at the code and this would be my first idea to approach this, sorry, if I missed something that would make this more complicated.
I might be interested in implementing this.
I've started experimenting with this a bit by using eval
in bash. The only problem is that we'd need to indicate how atuin exited, either with return-execute
or something else. An easy way (at least on the bash side) would be exit codes. Then we could do something like this
stty_orig=$(stty -g)
__atuin_myhistory() {
tput rmkx
# shellcheck disable=SC2048,SC2086
HISTORY="$(RUST_LOG=error atuin search $* -i -- "${READLINE_LINE}" 3>&1 1>&2 2>&3)"
exitcode=$?
tput smkx
if [[ "$exitcode" == "0" ]]; then
echo -e "${PS1@P}${HISTORY}"
_atuin_preexec "${HISTORY}"
local stty_bkup=$(stty -g)
stty "$stty_orig"
eval "${HISTORY}"
_atuin_precmd
stty "$stty_bkup"
else
READLINE_LINE=${HISTORY}
READLINE_POINT=${#READLINE_LINE}
fi
}
The echo -e "${PS1@P}${HISTORY}"
emulates what the line would've looked like normally by printing the prompt. ${PS1@P}
is available since bash 4.4. I then call _atuin_preexec
to record the execution to the database, use eval
, and finish the execution with _atuin_precmd
.
It's not super mature yet but it does fix the issue of the new command being a child of atuin. What do people here think about this approach, especially the exit code stuff?
Edit: fixed tty configuration during eval (otherwise interactive programs don't work)
I've played some more with this and now think that the mcfly
way is probably the way to go, at least for zsh
_atuin_search() {
...
exitcode=$?
if [[ -n $output ]]; then
RBUFFER=""
LBUFFER=$output
fi
if [[ "$exitcode" == "0" ]]; then
if [[ -n $output ]]; then
zle accept-line
fi
zle redisplay
else
zle reset-prompt
fi
}
The next question is how to best communicate from atuin to the shell. My local version is using exit codes and mcfly
is using a temporary file. The former is easier and the latter more flexible. We could in the future for example split LBUFFER
and RBUFFER
if the search mode is prefix
Any chance of this change ever happening?
Any chance of this change ever happening?
Yes
FWIW https://github.com/dvorka/hstr supports this across multiple shells so there might be something to learn from there also.
Apparently referencing issues from discussions doesn't link back, but @davidhewitt has a patch that would be an excellent starting place.
This has been an open issue for a long while, and a few people have started PRs to get it in. I'm going to open a PR with David's commit as the starting place tonight/tomorrow, unless anybody else really fancies getting it in 😊
https://github.com/atuinsh/atuin/discussions/817#discussioncomment-7323475
TLDR of #817:
Tab: Select and edit (Current behavior of Enter) Enter: Run immediately
I really like that approach of @davidhewitt! Should really feel natural. I also like that this is aimed to be the default for new users, but keeping current behavior for existing users. But definitely I will switch as soon as it's available. I'm looking forward for a version featuring this!
This will be merged for zsh
with #1311, I'll follow up with others (unless anyone else fancies it?)
@yannickulrich, do you remember any specific issues you ran into with the bash example you laid out in https://github.com/atuinsh/atuin/issues/78#issuecomment-1555949322a?
We had to disable this feature for bash because we weren't able to make interactive input work, however your stty solutions do seem to fix that problem, but I haven't tested extensively.
Released in v17 :) (for all shells other than nushell)
I think we can close this