nushell / nushell

A new type of shell
https://www.nushell.sh/
MIT License
32.46k stars 1.68k forks source link

Sending keys on tmux does not work as expected #10379

Open marcelarie opened 1 year ago

marcelarie commented 1 year ago

Question

I have this custom bash scripts to create tmux sessions and they always work with bash or fish but not with nushell.

#!/usr/bin/env sh

SESSION_TYPE=$1

if [ -z "$SESSION_TYPE" ]; then
    echo "No session type provided"
    exit 1
fi

WORK_PATH="$HOME/clones/$SESSION_TYPE"
# Selecting a repository to work on
SELECTED_REPO=$(ls "$WORK_PATH" | fzy)
REPO=$(echo $SELECTED_REPO | sed 's/\//-/g' | sed 's/\./-dot-/g')
SESSION="$SESSION_TYPE-$REPO"
REPO_NAME="$WORK_PATH/$SELECTED_REPO/"
# Generating the session name using the repository
SHELL=nu
EDITOR=nvim
# CUSTOM_COMMAND=""

if ! tmux has-session -t "$SESSION" 2>/dev/null; then
    echo "Creating new session..."
    tmux new-session -d -s "$SESSION"
    tmux new-window -n $EDITOR
    tmux send-keys "$SHELL" C-m
    tmux send-keys "cd $REPO_NAME" C-m
    # tmux send-keys "$CUSTOM_COMMAND" C-m
    tmux send-keys "$EDITOR" C-m
    tmux send-keys C-l
    tmux split-window -v
    tmux select-pane -t 1
    tmux send-keys "$SHELL" C-m
    tmux send-keys "cd $REPO_NAME" C-m
    # tmux send-keys "$CUSTOM_COMMAND" C-m
    tmux send-keys C-l
    tmux resize-pane -D 80
else
    echo "Session already exists"
fi

tmux -2 attach-session -t "$SESSION"

The C-m key are not send and when opening the session I get the following:

Screenshot 2023-09-15 at 10 13 25

It shoul cd to the dir and open nvim, but it just gets the two lines together.

Do you know why this happens? The scripts runs inside bash so it is strange. Should I create a nushell equivalent script?

fdncred commented 1 year ago

Nushell doesn't understand bash scripts and is not POSIX compliant. I believe you'll need to write your scripts in nushell's scripting language.

marcelarie commented 1 year ago

Cool, I am trying that but the issue is the same, nu shell does not work properly with tmux send-keys.

I did a rewrite using nu but the error is still there:

#!/usr/bin/env nu

def main [$type: string] {
    let work_path = $env.HOME + '/clones/' + $type;
    let selected_repo = (^ls $work_path | fzy)
    let repo = $selected_repo | str replace '/' '-' | str replace '.' '-dot-'
    let session = $type + '-' + $repo
    let repo_name = $work_path + '/' + $selected_repo + '/'
    let shell = 'nu'
    let editor = 'nvim'
    let custom_command = 'yazi'

    let no_session = (tmux has-session -t $session) | str contains " can't find session"

    if $no_session {
        print "Creating session: " $session
        tmux new-session -d -s $session
        tmux new-window -n $editor
        tmux send-keys $shell C-m
        tmux send-keys $"cd ($repo_name)" C-m
        tmux send-keys $editor C-m
        tmux send-keys C-l
        tmux split-window -v
        tmux select-pane -t 1
        tmux send-keys $shell C-m
        tmux send-keys $"cd ($repo_name); C-m"
        tmux send-keys C-l
        tmux resize-pane -D 80

    } else {
        echo "Session already exists"
    }

    tmux -2 attach-session -t $session
}
fdncred commented 1 year ago

I guess you'll need to find someone that uses tmux for further help. You can drop by our Discord I'm sure there are a few in there.

marcelarie commented 1 year ago

Ok I will check there, thanks!

marcelarie commented 1 year ago

this is the thread: https://discord.com/channels/601130461678272522/1152220493852708866

marcelarie commented 1 year ago

Did not find any help with this, this behavior happens with all the send-keys with C-m when the command is in nushell. Anyone knows how to fix it?

fdncred commented 1 year ago

I thought @amtoine used tmux with nushell successfully. Maybe he can jump in?

marcelarie commented 1 year ago

Yes but my question is releated to how to send-keys from a nu shell script to a tmux session.

For example for this script:

#!/usr/bin/env nu

def main [$type: string] {
    let work_path = $env.HOME + '/clones/' + $type;
    let selected_repo = (^ls $work_path | fzy)
    let repo = $selected_repo | str replace '/' '-' | str replace '.' '-dot-'
    let session = $type + '-' + $repo
    let repo_name = $work_path + '/' + $selected_repo + "/"
    let shell = 'nu'
    let editor = 'nvim'
    let custom_command = 'yazi'

    let has_session = (tmux has-session -t $session) | str contains " can't find session"

    if not $has_session {
        print "Creating session: " $session
        tmux new-session -d -s $session
        tmux new-window -n $editor
        # tmux send-keys $shell C-m
        tmux send-keys $"cd ($repo_name)" C-m
        # tmux send-keys $shell C-m
        tmux send-keys $editor C-m
        tmux send-keys C-l
        tmux split-window -v
        tmux select-pane -t 1
        tmux send-keys $"cd ($repo_name)" C-m
        tmux resize-pane -D 80
        tmux send-keys $shell C-m
        tmux send-keys C-l

    } else {
        echo "Session already exists"
    }

    tmux -2 attach-session -t $session
}

if I introduce any of the lines that are commented:

        # tmux send-keys $shell C-m

The next tmux send-keys will not work correctly. But if I run the command from another nu shell, it will work.

It is really strange.

fdncred commented 1 year ago

I have no clue what tmux send-keys $shell C-m is even supposed to do. LOL. My guess is that the nushell evaluator is trying to run nushell since $shell = nu

marcelarie commented 1 year ago

tmux send-keys basically sends the characters that you add as arguments to the terminal.

In this case it will send: nu and press C-m, that will run the command. It is the equivalent to open a shell, write nu and press Enter.

My guess is that the nushell evaluator is trying to run nushell since $shell = nu

Yes that is what I thought but if I go to an already opened shell, the send-keys commands work correctly.

fdncred commented 1 year ago

I'm not sure what to tell you. This example isn't easily reproducible so it'll take someone who knows tmux and nushell to figure it out.

marcelarie commented 1 year ago

This will be the minimal example of this issue:

#!/usr/bin/env nu

def main [] {
    tmux new-session -d -s NU-TEST    # Creates the tmux session
    tmux new-window -n EDITOR         # Creates a tmux window
    tmux send-keys nu C-m             # Sends `nu` and presses C-m 
    tmux send-keys nvim C-m           # Send `nvim` and presses C-m <- THIS FAILS
    tmux attach-session -d -t NU-TEST # When we are attach to the tmux seesion we see 
                                      # that nvim is written in the shell but it is not executed
}

This only happens if we run it from a script, if we execute tmux send-keys nvim C-m manually from a shell, being bash or fish or nushell, it works.

marcelarie commented 1 year ago

Thanks @fdncred for trying to help.

amtoine commented 1 year ago

yeah i'm simply using https://github.com/amtoine/tmux-sessionizer and it works :yum:

WindSoilder commented 10 months ago

I think it's answered, so I'll close the issue for now

Feel free to re-open it if you still have questions

marcelarie commented 10 months ago

@WindSoilder tbh I think it is not resolved, the solution can be using the sessionaizer that @amtoine comments, but I want to know why if I create a tmux script some send-key commands are not sent. That is the problem.

Like I comment here: https://github.com/nushell/nushell/issues/10379#issuecomment-1792662374

saketh21v commented 4 months ago

Essentially, nushell is ignoring the "Return" key when sent from tmux if nushell isn't already open and ready to receive keycodes. I'm facing the same issue using tmuxinator.

The command shows up before the prompt is ready. And once the prompt is ready, the command is shown, but the "Enter/Return" keycode is ignored. image

marcelarie commented 4 months ago

@WindSoilder do you know anyone who might have a good understanding of why nushell could be ignoring tmux key bindings?

NotTheDr01ds commented 1 month ago

Unless I'm wrong, this can be much more minimally reproduced just by running this command from the REPL itself:

tmux send-keys "ls" C-m

As mentioned, if I supply a -t (target) pane that is different from the current pane, then it works.

I'm guessing this is a Reedline issue?