prompt-toolkit / python-prompt-toolkit

Library for building powerful interactive command line applications in Python
https://python-prompt-toolkit.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
9.11k stars 718 forks source link

Add a "plain" output mode that does not use any ANSI codes #509

Open infinity0 opened 7 years ago

infinity0 commented 7 years ago

Applications using prompt-toolkit find it harder to interface with other applications because of the presence of ANSI codes. For example, Cantor wants to use Sage as a backend, and recently this has been broken because Sage uses IPython which uses prompt-toolkit, and Cantor cannot deal with the presence of extra ANSI codes.

IPython, as a hack, has added a --simple-prompt option that avoids prompt-toolkit and uses raw_input instead, but this does not support multiline input. Besides, this is a dirty work-around for prompt-toolkit's lack of support for a "plain" IO mode. It would be cleaner if prompt-toolkit supplied such a functionality itself.

infinity0 commented 7 years ago

As a hack, I tried adding if data[0] == '\x1b': return to Vt100_Output.write_raw to filter away escape codes, but this interferes with "next line" output and I get something like this:

$ SAGE_BANNER=no sage
sage: 1sage: 1
1
sage: 2sage: 2
2
sage: 3sage: 3
3
sage: sage:                                                                                                                                                                                                                                                    
Exiting Sage (CPU time 0m0.10s, Wall time 0m5.96s).

Note the repetition of the input prompt (including what the user typed as input) after I hit "enter".

jonathanslenders commented 7 years ago

Hi @infinity0, I understand the problem, but as far as I know, this is something that won't/can't be fixed.

prompt_toolkit provides a human interface, not a machine interface. It assumes that stdin and stdout are attached to a TTY for human interaction. If you want to do inter process communication, then you have to use a different library.

Applications that want to support piping input to stdin should detect whether the input is a pipe, and if so, they should not use prompt_toolkit, but instead simply read stdin.

infinity0 commented 7 years ago

OK, thanks for the explanation. I was a bit confused at first, I thought prompt-toolkit was a bit more invasive than simply doing terminal-based I/O because it has an Application class and an event loop, but I think I might have fixed this directly in IPython with https://github.com/ipython/ipython/pull/10606.