Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key binding to run the command immediately #78

Closed
ElvishJerricco opened this issue May 8, 2021 · 19 comments
Closed

Key binding to run the command immediately #78

ElvishJerricco opened this issue May 8, 2021 · 19 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@ElvishJerricco
Copy link
Contributor

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.

@yuvipanda
Copy link
Contributor

Shift+Enter maybe?

@yuvipanda
Copy link
Contributor

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
Copy link
Contributor

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

@yuvipanda
Copy link
Contributor

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

@ellie
Copy link
Member

ellie commented May 12, 2021

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

@yshui
Copy link

yshui commented Sep 8, 2022

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

@ellie
Copy link
Member

ellie commented Oct 8, 2022

ohhh that's awesome, thanks @yshui!

@ellie ellie added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels Oct 8, 2022
@RafaelKr
Copy link

RafaelKr commented Mar 22, 2023

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.

@VuiMuich
Copy link
Contributor

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

@yannickulrich
Copy link
Contributor

yannickulrich commented May 20, 2023

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
Copy link
Contributor

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

@romanr
Copy link

romanr commented Aug 3, 2023

Any chance of this change ever happening?

@ellie
Copy link
Member

ellie commented Aug 3, 2023

Any chance of this change ever happening?

Yes

@mattklein123
Copy link

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

@ellie
Copy link
Member

ellie commented Oct 19, 2023

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 😊

#817 (comment)

@RafaelKr
Copy link

RafaelKr commented Oct 19, 2023

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!

@ellie
Copy link
Member

ellie commented Oct 19, 2023

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

@arcuru
Copy link
Sponsor Contributor

arcuru commented Nov 19, 2023

@yannickulrich, do you remember any specific issues you ran into with the bash example you laid out in #78 (comment)?

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.

@ellie
Copy link
Member

ellie commented Jan 12, 2024

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

I think we can close this

@ellie ellie closed this as completed Jan 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants