atuin icon indicating copy to clipboard operation
atuin copied to clipboard

Key binding to run the command immediately

Open ElvishJerricco opened this issue 3 years ago • 18 comments

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.

ElvishJerricco avatar May 08 '21 22:05 ElvishJerricco

Shift+Enter maybe?

yuvipanda avatar May 09 '21 06:05 yuvipanda

looks like Termion might not support multiple modifiers (like Shift+Enter) yet https://github.com/redox-os/termion/blob/dce5e7500fd709987f9bf8f3911e4daa61d0ad14/src/event.rs#L288

yuvipanda avatar May 09 '21 06:05 yuvipanda

Also not sure how to actually execute the command - apending '\n' or '\u{15}' doesn't seem to help

yuvipanda avatar May 09 '21 08:05 yuvipanda

@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...

yuvipanda avatar May 12 '21 00:05 yuvipanda

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).

ellie avatar May 12 '21 20:05 ellie

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).

yshui avatar Sep 08 '22 22:09 yshui

ohhh that's awesome, thanks @yshui!

ellie avatar Oct 08 '22 04:10 ellie

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.

RafaelKr avatar Mar 22 '23 10:03 RafaelKr

: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.

VuiMuich avatar Apr 15 '23 12:04 VuiMuich

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)

yannickulrich avatar May 20 '23 16:05 yannickulrich

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

yannickulrich avatar Jun 20 '23 15:06 yannickulrich

Any chance of this change ever happening?

romanr avatar Aug 03 '23 12:08 romanr

Any chance of this change ever happening?

Yes

ellie avatar Aug 03 '23 12:08 ellie

FWIW https://github.com/dvorka/hstr supports this across multiple shells so there might be something to learn from there also.

mattklein123 avatar Sep 25 '23 00:09 mattklein123

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

ellie avatar Oct 19 '23 08:10 ellie

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!

RafaelKr avatar Oct 19 '23 09:10 RafaelKr

This will be merged for zsh with #1311, I'll follow up with others (unless anyone else fancies it?)

ellie avatar Oct 19 '23 21:10 ellie

@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.

arcuru avatar Nov 19 '23 14:11 arcuru

Released in v17 :) (for all shells other than nushell)

I think we can close this

ellie avatar Jan 12 '24 16:01 ellie