haskell / haskeline

A Haskell library for line input in command-line programs.
https://hackage.haskell.org/package/haskeline
BSD 3-Clause "New" or "Revised" License
221 stars 75 forks source link

Odd behaviour with ANSI escapes in prompt #44

Closed erikd closed 8 years ago

erikd commented 8 years ago

I'm seeing this in GHCi, but I assume its haskeline problem. Please correct me if I'm wrong on that.

I've noticed this minor annoyance for a while but didn't really explore it until now. I was going to do this bug report as an interpretive dance, but i decided an animated GIF was easier.

ghci-prompt

It seems that if the prompt string has non-printable characters recalling a previous multi line expression, followed by the down arrow key leaves the prompt in a strange state. Hopefully that will be obvious from the GIF. The prompt I'm using is:

:set prompt "\ESC[1;32mλ> \ESC[m"
erikd commented 8 years ago

@judah Hoping its really obvious where this problem is. If not, I'll dive in and have a look.

judah commented 8 years ago

The feature is documented here: https://github.com/judah/haskeline/wiki/ControlSequencesInPrompt

Specifically, you need to add "\STX" to the end of each escape sequence, or else haskeline won't know the correct width of the prompt. See that page for some examples.

Let me know whether that works for you.

erikd commented 8 years ago

Close, but still not quite right. Using set prompt "\ESC[1;32mλ>\ESC[m \STX" with the example before, using up arrow to recall the previous multiline expression, followed by down arrow leaves me with no prompt at all. I tied replacing the λ with something plain ASCII but that didn't help either.

judah commented 8 years ago

You need the "\STX" before the lambda too. It should wrap the individual escape subsequences of the prompt. Something like "\ESC[1;32m\STXλ> \ESC[m\STX"

erikd commented 8 years ago

That's got it!! :100:

erikd commented 8 years ago

Wonder if it might be worth checking the prompt at startup and printing an informational message on how to improve it.