Search code examples
rubycommand-prompt

Pre-Filled Prompt in Ruby


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?


Solution

  • 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}"