4

To simplify, let's say I'm trying to write a command line two-way chat in Python. I would like the user to input his message with input() at the command prompt, but a listening thread could print a message at any moment. By default, this would "break" the user's input. Visually something like this:

userB>Stop interuserA wrote:Hey check this out!
rupting me!

The closest I was able to find was this answer here which is almost, but not exactly, what I'm looking for, but it did point me towards the blessings package which seems to be what I need (although I'm happy with an answer for any package, or even pure ANSII).

What I'm trying to achieve is to print incoming output from a Thread above the user's input, so that his text doesn't break. Let's say the user is typing:

userB>Stop inter

Suddenly a message comes in from the thread, but our user's input doesn't brake:

userA says: Ok I won't interrupt you
userB>Stop inter

What should my threads theoretical print_incoming_message() method look like to achieve this?

NB: I'm using Linux and am not interested in cross-platform compatibility.

Community
  • 1
  • 1
Juicy
  • 11,840
  • 35
  • 123
  • 212

1 Answers1

3

There are two ways of doing this.

One is to use ncurses. There are python bindings for this. With ncurses, the terminal screen is under your complete control, and you can print characters at any point.

Without ncurses, you can't write above the current line. What you can do, however, is print a \r character and go back to the beginning of the line.

If you save the user's input (say he wrote foo), and you want to print the line bar above that, you can output:

\rbar\nfoo

This will overwrite the current line, and introduce a newline, moving the user's input down. The effect is similar, but it won't be as tamper-proof as ncurses.

salezica
  • 74,081
  • 25
  • 105
  • 166
  • Thanks. Do I have to keep track of the user input myself or is there a way to say "save current input" before overwriting? ie: is there a way to get input that hasn't been flushed yet? – Juicy Sep 26 '16 at 22:45
  • You should track input yourself, from the last newline entered – salezica Sep 26 '16 at 22:59
  • 5
    Discovered the `readline` module that has a `get_line_buffer()` method. It's working pretty good so far! Thanks for pointing me in the right direction. https://docs.python.org/3/library/readline.html#module-readline – Juicy Sep 26 '16 at 23:25