Search code examples
rubystdintty

How to allow users to edit given string via $stdin in ruby


I'm searching to allows users to edit an existing string.

Edit the following string: Edit me
# After user delete and add characters
Edit the following string: Edit you

I thought to prepend some data to the $stdin but seems like it's not possible and anyway IMHO it's a too radical solution.

Someone told me to use GNU Readline's Ruby wrapper so I've taken a quick look and I found Readline#pre_input_hook which acts before Readline start taking the input.

I tried:

require 'readline'
Readline.pre_input_hook = -> { "Edit me" }
result = Readline.readline("Edit the following string: ")
puts result

But seems not work.


Solution

  • begin
      system("stty raw -echo")
      print (acc = "Edit me: ")
      loop.each_with_object(acc) do |_,acc|
        sym = $stdin.getc
        case sym.ord
        when 13    # carriage return
          break acc
        when 127   # backspace
          print "\e[1D \e[1D"
          acc.slice!(acc.length - 1) if acc.length > 0
        else       # regular symbol
          print sym
          acc << sym
        end
      end
    ensure
      system("stty -raw echo")
      puts
      puts "\e[0mEntered: |#{acc}|"
    end
    

    Here you go. More info on terminal control sequences. Also, ANSI terminal codes.