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

156 views Asked by At

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.

2

There are 2 answers

0
Aleksei Matiushkin On BEST ANSWER
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.

0
Mike Slinn On

I found prompt.ask from tty-prompt fulfilled my need:

$ gem install tty-prompt

$ irb
irb(main):001:0> require "tty-prompt"
=> true

irb(main):002:0> prompt = TTY::Prompt.new
=> #<TTY::Prompt prefix="" quiet=false enabled_color=nil active_color=:green 
error_color=:red help_color=:bright_black input=#<IO:<ST...

irb(main):003:0> prompt.ask("What is your name?", default: ENV["USER"])
What is your name? xxx
=> "xxx"

irb(main):004:0> prompt.ask("What is your name?", value: "Mike")
What is your name? Michael
=> "Michael"