Search code examples
pythonstringvariablesuser-input

How do I take a user input that ends when the user presses Tab in Python?


I've been trying to find a way to take a user input that ends in the user pressing Tab. What I want to happen is for the user to type notes and it doesn't finish the input until they press Tab.

I was trying to use this method but not sure what to do.

text = input()

I want the user to type notes and be able to go to a new line by pressing Enter without finishing the input. Only if the user presses Tab will the input finish and the text get stored into the variable.


Solution

  • What you're asking for sounds straightforward, but unfortunately isn't very easy to do. The problem is that input from the command line to your program is line-buffered. That is, it only gets sent to the program one line at a time. There are some difficult ways to get around this, but they generally don't work very well.

    If you clarify your question with what you are trying accomplish one level above this, people might be able to offer an even better solution. In the meantime, here's a simple version that ends the input if the user presses tab then enter:

    def get_input_ending_with_tab():
        inp = input() + "\n"
        while not inp.endswith("\t\n"):
            inp += input() + "\n"
        return inp
    

    And here's a more complicated version that does what you want, but will not work on Windows. This will also only work in an interactive execution of your program (when it's attached to a TTY).

    import sys
    import tty
    import termios
    def get_input_ending_with_tab_2():
        buf = ""
        stdin = sys.stdin.fileno()
        tattr = termios.tcgetattr(stdin)
        try:
            tty.setcbreak(stdin, termios.TCSANOW)
            while True:
                buf += sys.stdin.read(1)
                print(buf[-1], end="")
                sys.stdout.flush()
                if buf[-1] == "\t":
                    break
        finally:
            termios.tcsetattr(stdin, termios.TCSANOW, tattr)
            print()
        return buf