Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to print without overwriting current typed input?

Tags:

python

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.

like image 859
Access Avatar asked Dec 02 '25 13:12

Access


1 Answers

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.

like image 141
kolen Avatar answered Dec 04 '25 03:12

kolen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!