我想在Ruby中編寫一個命令行應用程序,一個shell,如果你願意的話。如何編寫支持製表符完成的Ruby命令行應用程序?
我希望用戶能夠在某些點按Tab鍵並提供值的完成。
我該怎麼做?我必須使用什麼圖書館?你能指點我一些代碼示例嗎?
我想在Ruby中編寫一個命令行應用程序,一個shell,如果你願意的話。如何編寫支持製表符完成的Ruby命令行應用程序?
我希望用戶能夠在某些點按Tab鍵並提供值的完成。
我該怎麼做?我必須使用什麼圖書館?你能指點我一些代碼示例嗎?
啊,看來標準圖書館畢竟是我的朋友。我在找的是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
(這是默認設置爲代表字符的列表單詞邊界並且只導致最後一個單詞被傳入你的過程)。
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
+1,謝謝,這是一個很酷的解決方案! – mydoghasworms
與其手動定義'@ completions',爲什麼不使用標準庫中的Abbrev? – iconoclast
感謝您的提示!更新了使用Abbrev庫的示例。 –
有一點需要注意的是,readline使用系統的底層readline-like庫,可能是libedit。所以,readline ruby lib的某些功能將不起作用或將導致崩潰。避免文檔所說的任何內容是可選的或可能無法使用。 – davetron5000