I want to write a command line app, a shell if you will, in Ruby.
I want the user to be able to press Tab at certain points and offer completion of values.
How do I do this? What library must I use? Can you point me to some code examples?
Command-line completion allows the user to type the first few characters of a command, program, or filename, and press a completion key (normally Tab ↹ ) to fill in the rest of the item. The user then presses Return or ↵ Enter to run the command or open the file.
Press Ctrl twice to invoke the Run Anything popup. Type the ruby script. rb command and press Enter . If necessary, you can specify the required command-line options and script arguments.
Ruby command is a free and open source programming language; it is flexible and is feature rich. As the name suggests, ruby indeed is a jewel language which comes at a very low entry cost. Its plug and play capability and also easily readable syntax makes it very user-friendly.
Ah, it seems the standard library is my friend after all. What I was looking for is the Readline library.
Doc and examples here: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/readline/rdoc/Readline.html
In particular, this is a good example from that page to show how completion works:
require 'readline' LIST = [ 'search', 'download', 'open', 'help', 'history', 'quit', 'url', 'next', 'clear', 'prev', 'past' ].sort comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) } Readline.completion_append_character = " " Readline.completion_proc = comp while line = Readline.readline('> ', true) p line end
NOTE: The proc receives only the last word entered. If you want the whole line typed so far (because you want to do context-specific completion), add the following line to the above code:
Readline.completer_word_break_characters = "" #Pass whole line to proc each time
(This is by default set to a list of characters that represent word boundaries and causes only the last word to be passed into your proc).
The Readline library is excellent, I've used it many times. But, if you're making it just for the fun of it, you can also roll your own completion.
Here's a simple completion script:
require 'io/console' # Ruby 1.9 require 'abbrev' word = "" @completions = Abbrev.abbrev([ "function", "begin" ]) while (char = $stdin.getch) != "\r" word += char word = "" if char == " " if char == "\t" if comp = @completions[word = word[0..-2]] print comp[word.length..-1] end else print char end end puts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With