How to write a Ruby command line app that supports tab completion?

后端 未结 3 1106
野趣味
野趣味 2020-12-23 10:25

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.

H

相关标签:
3条回答
  • 2020-12-23 11:13

    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
    
    0 讨论(0)
  • 2020-12-23 11:20

    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).

    0 讨论(0)
  • 2020-12-23 11:20

    Well, I suggest that you use Emacs to run your command line Ruby app. In Emacs, my SO friends just recently helped me to solve the Autocomplete tab completion (here and here). Autocomplete seems to be the most intelligent word completion tool to date.

    0 讨论(0)
提交回复
热议问题