Weird issue with console typing effect + input

Question:
I’m trying to make a typing effect in the terminal paired with an input(). I found some code online (snippet below) and tried it. It worked, it had the typing effect and the input worked. Kind of. If I typed a little into the input, and then held backspace, it would delete the text from the typing effect!
image
image
image

Repl link:
https://replit.com/@TinyMooshmallow/imbadatpython

Typing effect code?

import sys
import time

def tinput(text):
  for character in text:
      sys.stdout.write(character)
      sys.stdout.flush()
      time.sleep(0.05)
  value = input("")
  return value
2 Likes

Hey @TinyMooshmallow!

I believe when you use sys it counts as normal user inputted text, therefore you can delete it, whereas if it’s text from the program (like normal inputs) it’s text can’t be deleted. (I might be totally wrong, if so point it out)

2 Likes

It’s because you are using sys.stdout.write() and input() .

When you call input() , the terminal cursor goes back to the line where the output from sys.stdout.write() is… If you use backspace, it will erase the characters on this line.

You can fix this by printing a newline character, like this:

import sys
import time

def tinput(text):
  for character in text:
      sys.stdout.write(character)
      sys.stdout.flush()
      time.sleep(0.05)
  sys.stdout.write('\n')  # Print a newline character
  value = input()
  return value

4 Likes

Yeah but I don’t want to make another line. I want it to be like a normal input, just with the typing effect. Is that possible?

1 Like

Hmmm
It’s possible but without the sys.stdout. You can use the print() function with the end parameter set to an empty string ('' ).

Kinda like this:

import time

def tinput(text):
  for character in text:
      print(character, end='', flush=True)
      time.sleep(0.05)
  value = input()
  return value

(flush=true and stdout.flush is kinda like the same)

1 Like

Even with print(), I’m still getting the same problem?

1 Like

Strange…

Try using ANSI.
I found this googling:

Adapting to your code will be something like this:

import sys
import time
from colorama import Fore, Style

def tinput(text):
  for character in text:
      sys.stdout.write(character)
      sys.stdout.flush()
      time.sleep(0.05)
  sys.stdout.write('\n')  
  value = input()
  sys.stdout.write('\x1b[1A')  
  return value

tinput(Fore.CYAN + "Username: " + Style.RESET_ALL)
2 Likes

The code causes really weird behavior. When I press enter on the input, some of the text becomes “ghost text” that you can’t delete and when you type over them and backspace they disappear?

I created a new project and tried some things…
I found out about readline so I think this will work in your case.

import time
from colorama import Fore, Style
import readline

def tinput(text):
    for character in text:
        print(character, end='', flush=True)
        time.sleep(0.05)
    readline.set_startup_hook(lambda: readline.insert_text(''))
    value = input()
    readline.set_startup_hook() 
    return value

tinput(Fore.CYAN + "Username: " + Style.RESET_ALL)
1 Like

It still didn’t work? When deleting the last character in the input, it simply removes all of the text earlier.

UPDATE: I figured out that when putting ANY string containing something in the input, it works? I’m not sure why though. Also I tried using the zero-width non-joiner in the string to cheat it but that didn’t work.

this function might help you

from os import system
from time import sleep
def type_text(text):
  for i in range(len(text)):
    print(text[0:i+1])
    sleep(0.5)
    system("clear")

…no, it doesn’t. look at the other comments please