Is it possible to print something without overwriting the already written but not sent input?
This is the client side for a socket and I'm wanting to print messages from the server without overwriting/appending the currently written input.
def listen():
while True:
data = s.recv(1024)
print(data.decode('utf-8'))
def write():
while True:
text = input("Text > ")
s.sendall(bytes(text, 'utf-8'))
listener = threading.Thread(target=listen)
listener.start()
writer = threading.Thread(target=write)
writer.start()
I'd want to print the received data above or below the current input line, but right now it just writes it on the input line.
Interactive terminal input is complex and is usually handled with libraries, it's hard to handle it directly. For line input, readline and its alternatives such as libedit are popular. Most shells and REPLs use such libraries.
Python's standard library has readline module, which is interface to readline or libedit. Importing it makes input use realine/libedit, so it obtains cursor navigation and even auto-completion and history capabilities. And it allows to redraw input line after you draw something in terminal.
To print in previous line, you can use ANSI escape codes.
import threading
import sys
from time import sleep
import readline # importing readline makes input() use it
def listen():
i = 0
while True:
i += 1
sleep(1)
# <esc>[s - save cursor position
# <esc>[1A - move cursor up
# \r - carriage return
# print message
# <esc>[u - restore cursor position
sys.stdout.write("\x1b[s\x1b[1A\rOutput: "+str(i)+"\x1b[u")
readline.redisplay()
def write():
while True:
print "" # make space for printing messages
text = input("Text > ")
listener = threading.Thread(target=listen)
listener.daemon = True
listener.start()
write()
readline library also has rl_message and other useful capabilities, but its' not exported by python's readline module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With