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

Text wrap broken when using ansi_term in shell prompts #36

Open
glfmn opened this issue Feb 11, 2018 · 1 comment
Open

Text wrap broken when using ansi_term in shell prompts #36

glfmn opened this issue Feb 11, 2018 · 1 comment

Comments

@glfmn
Copy link

glfmn commented Feb 11, 2018

Background

I made a crate called glit, or Glitter which is a domain specific language for pretty printing git repository stats. The primary use-case is to embed information about git repository stats in a user's shell prompt; for example:

glit-demo

ansi_term has been super helpful in supporting ansi terminal formatting as part of the Glitter DSL, but I've unfortunately come across a strange issue:

When I have formatted text in the shell prompt, the text wrapping is broken. More specifically:

  • The terminal emulator wraps before the end of the line
  • The terminal emulator wraps onto the same line, overwriting the shell prompt

This issue is related to the way that BASH prompts expect all non-printing characters to be properly escaped so that it can properly count the length of a line.

Examples

Gnome shell
in gnome shell terminal emulator

hyper
demonstration in hyper.is terminal emulator

Expected Behaviour

The terminal again behaves as expected when I don't use any formatted text on the last line of the prompt; notice how below there is no formatting on the line which just contains $ ; that line was created by the interpreter by rendering the text \$ with Style::new(), or no formatting set.

  • The line wraps at the end of the line
  • The text does not wrap onto the same line as the shell prompt

demonstration of expected ansi_term behaviour

This has to do with lack of escapes for non-printing characters in bash prompts; from the documentation, control sequences must be escaped with:

\[

    Begin a sequence of non-printing characters. This could be used to embed a terminal control sequence into the prompt. 
\]

    End a sequence of non-printing characters. 

Replication

  • OS: Ubuntu 17.10 amd-64bit
  • uname -r: 4.13.0-32-generic
  • cargo -V: cargo 0.24.0 (45043115c 2017-12-05)
  • rustup -V: rustup 1.7.0 (813f7b7a8 2017-10-30)
  • rustc -V: rustc 1.23.0 (766bd11c8 2018-01-01)
  • ansi_term: 0.9^
  • bash --version: 4.4.12(1)-release
@joshtriplett
Copy link
Collaborator

joshtriplett commented Apr 18, 2020

Those aren't ANSI escapes, they're specific to bash's prompt. ansi_term can't emit those under normal circumstances, and I don't think it makes sense to have an option to do so that's specific to the bash prompt use case.

Ideally, bash should really be able to figure this out itself, such as by getting the current position after displaying the prompt. In the meantime, it's currently guaranteed that every sequence emitted by ansi_term will start with the byte \x1B, contain one or more characters other than m, and end with the byte m, so you could fairly easily insert the \[ and \] bash sequences with a regex or string manipulation inside your program. If you end up writing that code, you might consider providing it as a bash_prompt_ansi crate or similar.

56quarters added a commit to 56quarters/xprompt that referenced this issue Nov 8, 2020
Emit Bash escape sequences (`\[` and `\]`) around non printing
characters (colors) so that Bash knows how to correctly count the
number of characters on a line for line editing purposes.

See ogham/rust-ansi-term#36
See https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Controlling-the-Prompt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants