22

我想用 Ruby 编写一个命令行应用程序,如果你愿意的话,也可以是一个 shell。

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

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

4

3 回答 3

32

啊,看来标准库毕竟是我的朋友。我一直在寻找的是 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

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

Readline.completer_word_break_characters = "" #Pass whole line to proc each time

(这默认设置为代表单词边界的字符列表,并且只导致最后一个单词被传递到您的 proc 中)。

于 2012-12-14T10:10:45.150 回答
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
于 2012-12-15T03:08:48.667 回答
-10

好吧,我建议你使用 Emacs 来运行你的命令行 Ruby 应用程序。在 Emacs 中,我的 SO 朋友最近帮我解决了自动完成选项卡补全问题(此处此处)。自动完成似乎是迄今为止最智能的单词完成工具。

于 2012-12-15T03:55:48.140 回答