warpdotdev / Warp

Warp is a modern, Rust-based terminal with AI built in so you and your team can build great software, faster.
https://warp.dev
Other
21.47k stars 376 forks source link

In Bash, PROMPT_COMMAND array causes a syntax error when an element ends with `;`, `&`, etc. #5219

Open akinomyoga opened 3 months ago

akinomyoga commented 3 months ago

Dupe Check

Describe the bug

The bug happens in Bash. Bash 5.1 started to support the array version of PROMPT_COMMAND, where each element would be executed before showing a prompt. When an element of the array PROMPT_COMMAND (that is not the last element in the array) ends with ; or & after the initialization in ~/.bashrc, a syntax error arises.

This is caused by the following part of Warp's shell integration:

    # If the user's rc files turned PROMPT_COMMAND into an array, we must undo that.
    # Since Bash 5.1, the PROMPT_COMMAND variable can be an array, see:
    #   https://tiswww.case.edu/php/chet/bash/NEWS
    # Unfortunately, doing so will break Warp because of the way it interacts with bash-preexec.
    # When PROMPT_COMMAND is an array, the DEBUG signal fires for each array element, and since
    # bash-preexec uses a DEBUG trap to trigger the preexec functions, it will run our preexec
    # functions before the command at PROMPT_COMMAND[1], PROMPT_COMMAND[2], etc. This means our
    # Preexec hook gets called without the user submitting a command, putting the input block into
    # a broken state, e.g. see https://github.com/warpdotdev/Warp/issues/2636
    # If they end up fixing this, we may be able to remove this at some point, check this:
    #   https://github.com/rcaloras/bash-preexec/issues/130
    #
    # If PROMPT_COMMAND is set and it's an array, "join" the array into a semicolon-delimited string,
    # then overwrite PROMPT_COMMAND
    if [[ -n $PROMPT_COMMAND && "$(declare -p PROMPT_COMMAND)" =~ "declare -a" ]]; then
        PROMPT_COMMAND_FLATTENED=$(IFS="; "; echo "${PROMPT_COMMAND[*]}")
        unset PROMPT_COMMAND
        PROMPT_COMMAND=$PROMPT_COMMAND_FLATTENED
    fi

The problem lies in the line calculating PROMPT_COMMAND_FLATTENED. In shell language, commands cannot be always joined by ;. For example cmd1 & and cmd2 (which are both valid commands) cannot be combined to be cmd1 & ; cmd2. cmd1 & ; cmd2 is a syntax error. Similarly, cmd1 ; and cmd2 cannot be combined to be cmd1 ;; cmd2 nor cmd1 ; ; cmd2. To join valid commands, a newline character should be used. Here, I suggest the following change:

     if [[ -n $PROMPT_COMMAND && "$(declare -p PROMPT_COMMAND)" =~ "declare -a" ]]; then
-        PROMPT_COMMAND_FLATTENED=$(IFS="; "; echo "${PROMPT_COMMAND[*]}")
+        PROMPT_COMMAND_FLATTENED=$(IFS=$'\n'; echo "${PROMPT_COMMAND[*]}")
         unset PROMPT_COMMAND
         PROMPT_COMMAND=$PROMPT_COMMAND_FLATTENED
     fi

To reproduce

With the following single-line ~/.bashrc, start Warp Terminal with Bash.

# bashrc
PROMPT_COMMAND=('echo foo;' 'echo bar')

Then, the following error message appears:

bash: PROMPT_COMMAND: line 706: syntax error near unexpected token `;;'
bash: PROMPT_COMMAND: line 706: `echo foo;;echo bar'

Expected behavior

The messages foo and bar are printed before every new prompt.

Screenshots

No response

Operating system

Linux

Operating system and version

KDE neon 6.0 x86_64

Shell Version

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

Current Warp version

warp-terminal-v0.2024.08.06.08.01.stable_00-1-x86_64

Regression

No, this bug or issue has existed throughout my experience using Warp

Recent working Warp date

No response

Additional context

No response

Does this block you from using Warp daily?

No

Is this an issue only in Warp?

Yes, I confirmed that this only happens in Warp, not other terminals.

Warp Internal (ignore): linear-label:b9d78064-c89e-4973-b153-5178a31ee54e

None

aminya commented 3 months ago

I can confirm that the issue exists. See https://github.com/cantino/mcfly/issues/435 for more information.

The issue is crucial because I have to use Mcfly instead of Warp's built-in command search due to #4964.

dannyneira commented 3 months ago

Hi folks, unfortunately, Warp doesn't fully support PROMPT_COMMAND in bash right now, to set a custom prompt use PS1. That being said, Ive been able to reproduce this issue and will let the team know. We'll post updates on this thread.

akinomyoga commented 2 months ago

What is the current status of this problem? As included in the initial report, this problem should be fixed by the following one line change in the code fetched to Bash:

     if [[ -n $PROMPT_COMMAND && "$(declare -p PROMPT_COMMAND)" =~ "declare -a" ]]; then
-        PROMPT_COMMAND_FLATTENED=$(IFS="; "; echo "${PROMPT_COMMAND[*]}")
+        PROMPT_COMMAND_FLATTENED=$(IFS=$'\n'; echo "${PROMPT_COMMAND[*]}")
         unset PROMPT_COMMAND
         PROMPT_COMMAND=$PROMPT_COMMAND_FLATTENED
     fi

Ive been able to reproduce this issue and will let the team know.

Have you already let the team know? Does the team have access to GitHub? If not, could you let them know about the above suggested patch?