如何编写支持Tab键完成的Ruby命令行应用程序?

myd*_*rms 21 ruby

我想在Ruby中编写一个命令行应用程序,如果你愿意的话,写一个shell.

我希望用户能够在某些点按Tab键并提供值的完成.

我该怎么做呢?我必须使用哪个库?你能指点我一些代码示例吗?

myd*_*rms 31

啊,看来标准的图书馆毕竟是我的朋友.我在寻找的是Readline库.

这里的文档和示例:http://www.ruby-doc.org/stdlib-1.9.3/libdoc/readline/rdoc/Readline.html

特别是,这是一个很好的例子,从该页面显示完成的工作原理:

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
Run Code Online (Sandbox Code Playgroud)

注意:proc只接收输入的最后一个单词.如果您希望到目前为止输入整行(因为您希望执行特定于上下文的完成),请将以下行添加到上面的代码中:

Readline.completer_word_break_characters = "" #Pass whole line to proc each time
Run Code Online (Sandbox Code Playgroud)

(默认设置为表示单词边界的字符列表,仅导致最后一个单词传递到proc中).

  • 需要注意的一点是,readline使用系统的基础readline-like库,可能是libedit.因此,readline ruby​​ lib的某些功能将无法工作或将导致崩溃.避免文档说的任何内容是可选的或可能不起作用. (2认同)

Jos*_*gts 10

Readline库很棒,我已经多次使用它了.但是,如果你只是为了它的乐趣,你也可以自己完成.

这是一个简单的完成脚本:

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
Run Code Online (Sandbox Code Playgroud)