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

Wrapped escape sequence breaks bash prompt #1684

Closed
Joshuao95 opened this issue Apr 23, 2019 · 17 comments
Closed

Wrapped escape sequence breaks bash prompt #1684

Joshuao95 opened this issue Apr 23, 2019 · 17 comments

Comments

@Joshuao95
Copy link

Joshuao95 commented Apr 23, 2019

I'm attempting to distinguish between insert and normal mode in Readline applications (like Bash), typically this is done by using this escape sequence in .inputrc:

set vi-cmd-mode-string "\1\e[2 q\2"
set vi-ins-mode-string "\1\e[6 q\2"

This works fine outside of tmux, however it simply doesn't work once inside tmux.
From some searching around I found this notion that escape sequences need to be wrapped in a special wrapper, and then tmux will pass it through
\ePtmux;\e ........ \e\\

I couldn't find any documentation about it, other than random forum posts, however it does indeed work, correctly changing the cursor in the respective modes.

However it "breaks" the prompt when scrolling up in the Bash history, retaining some text from previous commands, obscuring the one that is currently typed in, whenever this "wrapper" is used.

My question is: Is there a solution to this? If this is some undocumented and possibly not rigorous way to pass through these sequences, is there a better way, or is something else going on?

@nicm
Copy link
Member

nicm commented Apr 23, 2019

No idea, your best bet would be to ask the Bash developers. Don't you need \[ and \] or something?

@Joshuao95
Copy link
Author

I believe you need those escaped brackets to signal you're using a 0-width "character" like a colour escape sequence in the prompt, and you're right, failing to do that in the actual PS1 prompt does indeed display similar behaviour.

I'm actually setting this inside readlines configs, so maybe they're not bringing in this "addition" to the prompt nicely.
I think you're right it's a question for them, I do wonder why it appears to work fine without this tmux-y escape sequence though, is there anywhere I can find/read more on that? It might provide some clues.

@nicm
Copy link
Member

nicm commented Apr 23, 2019

Maybe it understands how to filter out standard escape sequences already without you telling it to.

@nicm nicm closed this as completed Apr 24, 2019
@Joshuao95
Copy link
Author

Hi, sorry for the late response, I was waiting for some information from the Bash maintainers before replying.

If the DCS terminated by the ST really is supposed to transparently pass though escape sequences, and the escape sequences without the "wrapper" is working outside of tmux, then I think it has to be tmux doesn't it? If the wrapper thing was working as expected, Readline shouldn't get anything different than without using the DCS/ST wrapper.

Here's that conversation with Chet if it helps:

Are these characters at the end of the displayed line (or beyond the end of
the line?) If so, I suspect that there's a problem with the clear-to-end-
of-line that readline is using. I don't use tmux, though, so I've never
seen it in that context.

I did some more testing, to be more clear now:
When scrolling back up in the command history, some commands will "stick"
to the prompt, and look in essence as though they've been added to the
prompt, that is to say, further commands or letters typed in appear after
the "stuck text.
For example, if I've executed the commands:
cd, ls, dd, man, reallylongcommand
after pressing up twice, the prompt will show:
$reallylongman
However upon pressing enter it's obvious that only "man" was really there,
so it's just a display issue.

Like I said, I'm not a tmux user, but if the issue only comes up while
running under tmux, it's hard to call it a problem with bash/readline.
I suspect tmux is losing some of the escape sequences readline's redisplay
uses to move around the line (that would explain the display issue above),
but all I have is a suspicion.

Chet

@nicm
Copy link
Member

nicm commented Apr 30, 2019

It could be tmux but it doesn't have to be. The application sending the escape sequence may also need to understand it (for example if it needs to calculate the width). The wrapper is removed by tmux AFTER readline sends it. If you include some logs I can take a look and see what it is sending though.

But if you just want to change the cursor, why don't you configure tmux to do it? You probably just need to put Ms in terminal-overrides.

@Joshuao95
Copy link
Author

I want to change the cursor depending on the "mode" that bash is in when it's using Readline's vi mode, maybe there's a way to script that with tmux, but it would be nice if it simply used readline's config file alone.

I don't know which of these 3 log files is helpful, so I'll just include them all.
If it helps, the key sequence I pressed was: aiaxy

tmux-client: https://pastebin.com/w2Gg22mR
tmux-server: https://pastebin.com/3MWe0kzz
tmux-out: https://pastebin.com/2zPe7rC8

@nicm
Copy link
Member

nicm commented Apr 30, 2019 via email

@nicm
Copy link
Member

nicm commented Apr 30, 2019 via email

@nicm
Copy link
Member

nicm commented Apr 30, 2019

Are you sure these logs show the problem? I can only see the prompt printed once, what key do you use to scroll through the history?

@nicm nicm reopened this Apr 30, 2019
@Joshuao95
Copy link
Author

Hi nicm,

Sorry, I thought it would be sufficient to simply enter insert/command mode, as that is where the escape sequence passes through.
Here's the logs for reproducing the issue during scrolling (I'm just using Up to scroll up in the commands).

https://gist.github.com/Joshuao95/81179e4815fde634493f38a63be5c033

@nicm
Copy link
Member

nicm commented Apr 30, 2019

The problem is that readline is sending this (I have trimmed out some irrelevent bits):

tmuxlogs $ reallylongcommandthatwillbreak\r\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[Ccommand6\033[K

So what it is is doing is moving the cursor to the start of line (\r) then sending a long series of CUF (\033[C) to move it to the right where it expects the command should be printed.

It is sending 21 cursor right sequences so the cursor ends up in column 21.

Your prompt, however is "tmuxlogs $ " which is only 11 columns.

It looks like bash or readline is miscalculating the length of the prompt.

I could very well be wrong but my guess is that readline has some code to filter out escape sequences that follow the standard CSI form (such as \033[...a), but it doesn't understand DCS so it doesn't properly account for it when it is calculating the length of the prompt. If you take the full prompt it sends and remove all CSI sequences, you get 21:

>>> print len("tmuxlogs $ ")
11
>>> print len("\033Ptmux;\033\033[6 q\033\\tmuxlogs $ ")
26
>>> print len("\033Ptmux;\033\033\\tmuxlogs $ ")
21
>>>

@nicm
Copy link
Member

nicm commented Apr 30, 2019

You can report this to them but the best and easiest thing for you to do if you want this to work would be to add this to .tmux.conf and restart tmux (you can adjust the 2 in \E[2 q if you want a different default cursor):

set -as terminal-overrides ",*st-*:Ss=\\E[%p1%d q:Se=\\E[2 q"

@nicm
Copy link
Member

nicm commented Apr 30, 2019

Put that in .tmux.conf and then DON'T use the DCS bypass sequence.

@nicm
Copy link
Member

nicm commented Apr 30, 2019

If you want to report it to the bash developers, here is exactly what it is sending:

\033Ptmux;\033\033[6 q\033\\\033[93mtmuxlogs $ \033[m\017command3\b\b\b\b\b\b\b\b\033[4Pexit\b\b\b\breallylongcommandthatwillbreak\r\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[C\033[Ccommand6\033[K

You can see this by putting the above in a file and then doing:

$ printf "$(cat testfile)\n"
tmuxlogs $ reallylongcommand6
$

I also suspect you will be able to reproduce this outside tmux if you configure your prompt in the same way (so it contains the DCS Ptmux wrapper).

@nicm
Copy link
Member

nicm commented Apr 30, 2019

I'm going to close this again because it is not a tmux issue.

@nicm nicm closed this as completed Apr 30, 2019
@Joshuao95
Copy link
Author

I'm going to close this again because it is not a tmux issue.

Thank you for all the help and patience Nicholas, and for your contributions to tmux, it's an excellent program.

@lock
Copy link

lock bot commented Feb 14, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked and limited conversation to collaborators Feb 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

2 participants