Search code examples
crystal-lang

Why does the backspace key print ^? when calling gets() in crystal?


When I try to correct input for my crystal program (in a zsh terminal on my Mac), a ^? character is printed to the screen for each press of backspace. It's disorienting and does not delete any characters from the screen, but it technically functions just fine as I discovered playing around with this little testing snippet.

a = gets.as(String).chomp
puts a
a = gets   # alright then^?^?^?^?^?
puts a     # alright

What is going on here? How can I make my input behave as a user would expect, is there something special I can do with STDIN?


Solution

  • I think, it will depend on the terminal that you are using and it is largely independent of the programming language (e.g. it has been reported in Python).

    Some terminals send ^H or ^? when you type a backslash. I can also reproduce it in xterm (on Linux) when calling cat, which is roughly similar to getting a line and printing it (in a loop):

    $ echo $TERM
    xterm
    
    $ cat
    abc^H^H^Hdef
    def
    

    ... while it works with other terminals (same test: typing abc, deleting three characters, then typing def):

    $ echo $TERM
    xterm-256color
    
    $ cat
    def
    def
    

    You can use libraries like readline to workaround around it. I have not tried it myself, but this library implements bindings for Crystal: crystal-readline