Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pre-Filled Prompt in Ruby [duplicate]

I am using to Ruby to write a small command line utility to search Pubmed. Right now, I prompt the user for a query and display the results, and the user has the option of appending to the query or entering an entirely new query. I would like to add the ability to edit the current query; i.e. the prompt should come pre-filled with an editable version of the previous query, like so:

Enter query: <PREVIOUS QUERY HERE>

It's easy enough to print out the previous query next to the prompt, but how do I make this output editable, as if the user had typed it herself?

@casper: Thank you for the response Casper. I tried the code that you supplied below, and it does indeed work on its own. Strangely enough, it doesn't seem to work when I try to use it in a gem. My gem is called db_hippo. I added rb-readline as a dependency in my gemspec, and I put the extension to RbReadline in lib/db_hippo/rb-readline.rb

module DbHippo
  module RbReadline
    <CASPER'S EXTENSION HERE>
  end
end

I wish to use the functionality in another submodule of DbHippo, DbHippo::Source. In DbHippo::Source I added at the top:

require 'rb-readline'
require 'db_hippo/rb-readline'

Then in one of the methods of DbHippo::Source, I have:

RbReadline.prefill_prompt(query)
query = Readline.readline("Query: ", true)

The query variable is definitely not empty, but for some reason in this context the prompt doesn't get prefilled. I also notice that if I put the extension in the same file (lib/db_hippo/rb-readline) without making it a submodule of DbHippo, I get the error: uninitialized constant DbHippo::Source::Readline (NameError) on the line:

query = Readline.readline("Query: ", true)

This all seems to have something to do with proper naming of modules, require statements, and gems. This is the first gem I've tried to build. Any idea what's going wrong here?

like image 519
Sean Mackesey Avatar asked Jun 13 '12 21:06

Sean Mackesey


2 Answers

Maybe googlers will find this useful.

With plain Readline on Ruby 2.1 you could use:

def ask(prompt, default=nil)

  if default
    Readline.pre_input_hook = -> {
      Readline.insert_text(default)
      Readline.redisplay
      # prevent re-trigger on every `readline`
      Readline.pre_input_hook = nil
    }
  end
  data = Readline.readline("#{prompt}: ")
  return data.chomp
end

ask("MOAR...?", "COMPUTARS!") # displays: MOAR...? COMPUTARS!

At the prompt the text COMPUTARS! will be editable

like image 176
Roberto Avatar answered Sep 28 '22 07:09

Roberto


You can do it with RbReadline:

require 'rubygems'
require 'rb-readline'

module RbReadline
  def self.prefill_prompt(str)
    @rl_prefill = str
    @rl_startup_hook = :rl_prefill_hook
  end

  def self.rl_prefill_hook
    rl_insert_text @rl_prefill if @rl_prefill
    @rl_startup_hook = nil
  end
end

RbReadline.prefill_prompt("Previous query")
str = Readline.readline("Enter query: ", true)

puts "You entered: #{str}"
like image 35
Casper Avatar answered Sep 28 '22 07:09

Casper